mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
feat(range): add classes to the range when the value is at the min or max (#30932)
## What is the current behavior? Range adds classes to the knobs at `min` and `max`, but the host element doesn't reflect those states. ## What is the new behavior? - Adds `range-value-min` and `range-value-max` when the value is at the `min` or `max`, respectively. - Adds a spec test verifying the classes are applied properly. --------- Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com>
This commit is contained in:
@@ -883,7 +883,7 @@ export class Range implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { disabled, el, hasLabel, rangeId, pin, pressedKnob, labelPlacement, label } = this;
|
||||
const { disabled, el, hasLabel, rangeId, pin, pressedKnob, labelPlacement, label, dualKnobs, min, max } = this;
|
||||
|
||||
const inItem = hostContext('ion-item', el);
|
||||
|
||||
@@ -906,6 +906,13 @@ export class Range implements ComponentInterface {
|
||||
|
||||
const mode = getIonMode(this);
|
||||
|
||||
/**
|
||||
* Determine if any knob is at the min or max value to
|
||||
* apply Host classes for styling.
|
||||
*/
|
||||
const valueAtMin = dualKnobs ? this.valA === min || this.valB === min : this.valA === min;
|
||||
const valueAtMax = dualKnobs ? this.valA === max || this.valB === max : this.valA === max;
|
||||
|
||||
renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
|
||||
|
||||
return (
|
||||
@@ -922,6 +929,8 @@ export class Range implements ComponentInterface {
|
||||
[`range-label-placement-${labelPlacement}`]: true,
|
||||
'range-item-start-adjustment': needsStartAdjustment,
|
||||
'range-item-end-adjustment': needsEndAdjustment,
|
||||
'range-value-min': valueAtMin,
|
||||
'range-value-max': valueAtMax,
|
||||
})}
|
||||
>
|
||||
<label class="range-wrapper" id="range-label">
|
||||
|
||||
@@ -253,3 +253,101 @@ describe('range: item adjustments', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('range: value state classes', () => {
|
||||
it('should apply range-value-min class when value is at min', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Range],
|
||||
html: `<ion-range min="0" max="100" value="0"></ion-range>`,
|
||||
});
|
||||
|
||||
const range = page.body.querySelector('ion-range')!;
|
||||
|
||||
expect(range.classList.contains('range-value-min')).toBe(true);
|
||||
expect(range.classList.contains('range-value-max')).toBe(false);
|
||||
});
|
||||
|
||||
it('should apply range-value-max class when value is at max', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Range],
|
||||
html: `<ion-range min="0" max="100" value="100"></ion-range>`,
|
||||
});
|
||||
|
||||
const range = page.body.querySelector('ion-range')!;
|
||||
|
||||
expect(range.classList.contains('range-value-max')).toBe(true);
|
||||
expect(range.classList.contains('range-value-min')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not apply range-value-min or range-value-max classes when value is in the middle', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Range],
|
||||
html: `<ion-range min="0" max="100" value="50"></ion-range>`,
|
||||
});
|
||||
|
||||
const range = page.body.querySelector('ion-range')!;
|
||||
|
||||
expect(range.classList.contains('range-value-min')).toBe(false);
|
||||
expect(range.classList.contains('range-value-max')).toBe(false);
|
||||
});
|
||||
|
||||
it('should apply range-value-min class when lower knob is at min in dual knobs', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Range],
|
||||
html: `<ion-range dual-knobs="true" min="0" max="100"></ion-range>`,
|
||||
});
|
||||
|
||||
const range = page.body.querySelector('ion-range')!;
|
||||
range.value = { lower: 0, upper: 50 };
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(range.classList.contains('range-value-min')).toBe(true);
|
||||
expect(range.classList.contains('range-value-max')).toBe(false);
|
||||
});
|
||||
|
||||
it('should apply range-value-max class when upper knob is at max in dual knobs', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Range],
|
||||
html: `<ion-range dual-knobs="true" min="0" max="100"></ion-range>`,
|
||||
});
|
||||
|
||||
const range = page.body.querySelector('ion-range')!;
|
||||
range.value = { lower: 50, upper: 100 };
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(range.classList.contains('range-value-max')).toBe(true);
|
||||
expect(range.classList.contains('range-value-min')).toBe(false);
|
||||
});
|
||||
|
||||
it('should apply range-value-min and range-value-max classes for dual knobs when both are at boundaries', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Range],
|
||||
html: `<ion-range dual-knobs="true" min="0" max="100"></ion-range>`,
|
||||
});
|
||||
|
||||
const range = page.body.querySelector('ion-range')!;
|
||||
range.value = { lower: 0, upper: 100 };
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(range.classList.contains('range-value-min')).toBe(true);
|
||||
expect(range.classList.contains('range-value-max')).toBe(true);
|
||||
});
|
||||
|
||||
it('should not apply range-value-min or range-value-max classes for dual knobs when neither is at boundaries', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Range],
|
||||
html: `<ion-range dual-knobs="true" min="0" max="100"></ion-range>`,
|
||||
});
|
||||
|
||||
const range = page.body.querySelector('ion-range')!;
|
||||
range.value = { lower: 25, upper: 75 };
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(range.classList.contains('range-value-min')).toBe(false);
|
||||
expect(range.classList.contains('range-value-max')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user