diff --git a/BREAKING.md b/BREAKING.md index 7f16d41108..c95ba87190 100644 --- a/BREAKING.md +++ b/BREAKING.md @@ -192,6 +192,8 @@ Ionic now listens on the `keydown` event instead of the `keyup` event when deter - Range no longer clamps assigned values within bounds. Developers will need to validate the value they are assigning to `ion-range` is within the `min` and `max` bounds when programmatically assigning a value. +- The `name` property defaults to `ion-r-${rangeIds++}` where `rangeIds` is a number that is incremented for every instance of `ion-range`. + - `ionChange` is no longer emitted when the `value` of `ion-searchbar` is modified externally. `ionChange` is only emitted from user committed changes, such as typing in the searchbar and the searchbar losing focus. diff --git a/core/api.txt b/core/api.txt index 6f43a9fc1f..caeb8d2d93 100644 --- a/core/api.txt +++ b/core/api.txt @@ -1034,7 +1034,7 @@ ion-range,prop,legacy,boolean | undefined,undefined,false,false ion-range,prop,max,number,100,false,false ion-range,prop,min,number,0,false,false ion-range,prop,mode,"ios" | "md",undefined,false,false -ion-range,prop,name,string,'',false,false +ion-range,prop,name,string,this.rangeId,false,false ion-range,prop,pin,boolean,false,false,false ion-range,prop,pinFormatter,(value: number) => string | number,(value: number): number => Math.round(value),false,false ion-range,prop,snaps,boolean,false,false,false diff --git a/core/src/components/range/range.tsx b/core/src/components/range/range.tsx index c57982114e..1e24a85c6b 100644 --- a/core/src/components/range/range.tsx +++ b/core/src/components/range/range.tsx @@ -46,7 +46,7 @@ import type { shadow: true, }) export class Range implements ComponentInterface { - private rangeId?: string; + private rangeId = `ion-r-${rangeIds++}`; private didLoad = false; private noUpdate = false; private rect!: ClientRect; @@ -91,12 +91,10 @@ export class Range implements ComponentInterface { this.ionInput = debounce === undefined ? originalIonInput ?? ionInput : debounceEvent(ionInput, debounce); } - // TODO: In Ionic Framework v6 this should initialize to this.rangeId like the other form components do. - /** * The name of the control, which is submitted with the form data. */ - @Prop() name = ''; + @Prop() name = this.rangeId; /** * Show two knobs. @@ -302,7 +300,9 @@ export class Range implements ComponentInterface { * If user has custom ID set then we should * not assign the default incrementing ID. */ - this.rangeId = this.el.hasAttribute('id') ? this.el.getAttribute('id')! : `ion-r-${rangeIds++}`; + if (this.el.hasAttribute('id')) { + this.rangeId = this.el.getAttribute('id')!; + } this.inheritedAttributes = inheritAriaAttributes(this.el); } @@ -553,9 +553,9 @@ export class Range implements ComponentInterface { private renderLegacyRange() { if (!this.hasLoggedDeprecationWarning) { printIonWarning( - `Using ion-range with an ion-label has been deprecated. To migrate, remove the ion-label and pass your label directly into ion-toggle instead. + `Using ion-range with an ion-label has been deprecated. To migrate, remove the ion-label and pass your label directly into ion-range instead. -Example: Volume: +Example:
Volume:
For ranges that do not have a visible label, developers should use "aria-label" so screen readers can announce the purpose of the range. diff --git a/core/src/components/range/test/range.spec.ts b/core/src/components/range/test/range.spec.ts index 4707cf5212..2898675c89 100644 --- a/core/src/components/range/test/range.spec.ts +++ b/core/src/components/range/test/range.spec.ts @@ -1,3 +1,4 @@ +import { newSpecPage } from '@stencil/core/testing'; import { Range } from '../range'; let sharedRange; @@ -61,3 +62,17 @@ describe('Range', () => { }); }); }); + +describe('range id', () => { + it('should render custom id if passed', async () => { + const page = await newSpecPage({ + components: [Range], + html: ` +
Range
+
`, + }); + + const range = page.body.querySelector('ion-range'); + expect(range.getAttribute('id')).toBe('my-custom-range'); + }); +});