Skip to content

Commit

Permalink
fix(range): defaultValue & min max change
Browse files Browse the repository at this point in the history
  • Loading branch information
aesteves60 authored and dpellier committed Jul 29, 2024
1 parent 8a5b1d6 commit 4f4d62d
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
:host {
display: flex;
position: relative;
height: 32px;
width: inherit;
height: range.$ods-range-height;
}

:host(.ods-range-dual) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getRandomHTMLId } from '../../../../../utils/dom';
import { ODS_INPUT_TYPE } from '../../../../input/src';
import { ODS_TEXT_PRESET } from '../../../../text/src';
import { type OdsTooltip } from '../../../../tooltip/src';
import { isDualRange, setFormValue, toPercentage } from '../../controller/ods-range';
import { getDefaultValue, isDualRange, setFormValue, toPercentage } from '../../controller/ods-range';
import { type OdsRangeValueChangeEventDetail } from '../../interfaces/event';

@Component({
Expand Down Expand Up @@ -64,6 +64,41 @@ export class OdsRange {
this.odsReset.emit();
}

@Watch('min')
@Watch('max')
onMinOrMaxChange(): void {
if (!this.value) {
return;
}

if (!isDualRange(this.value)) {
if (this.min > this.value) {
this.value = this.min;
}

if (this.value > this.max) {
this.value = this.max;
}
} else {
const [valueMin, valueMax] = this.value;
if (valueMax > this.max) {
this.value = [this.value[0], this.max];
}

if (valueMin > this.max) {
this.value = [this.max, this.value[1]];
}

if (this.min > valueMax) {
this.value = [this.value[0], this.min];
}

if (this.min > valueMin) {
this.value = [this.min, this.value[1]];
}
}
}

@Watch('value')
private onValueChange(): void {
this.isDualRange = isDualRange(this.value);
Expand All @@ -74,8 +109,8 @@ export class OdsRange {
componentWillLoad(): void {
this.hostId = this.el.id || getRandomHTMLId();

if (!this.value && this.defaultValue) {
this.value = this.defaultValue;
if (!this.value) {
this.value = getDefaultValue(this.min, this.max, this.defaultValue);
}
setFormValue(this.internals, this.value);
this.onValueChange();
Expand Down Expand Up @@ -203,6 +238,7 @@ export class OdsRange {
min={ this.min }
ref={ (el?: HTMLInputElement) => this.inputElDual = el }
type={ ODS_INPUT_TYPE.range }
step={ this.step }
value={ this.dualValue?.toString() }
/>
{
Expand Down
8 changes: 8 additions & 0 deletions packages/ods/src/components/range/src/controller/ods-range.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
function getDefaultValue(min: number, max: number, defaultValue?: number | [number, number]): number | [number, number] {
if (defaultValue) {
return defaultValue;
}
return max < min ? min : min + (max - min) / 2;
}

function isDualRange(value: number | [number, number] | null): value is [number, number] {
return Array.isArray(value) && value.length === 2 && value.every((v) => typeof v === 'number');
}
Expand All @@ -11,6 +18,7 @@ function toPercentage(max: number, min: number, value?: number): number {
}

export {
getDefaultValue,
isDualRange,
toPercentage,
setFormValue,
Expand Down
72 changes: 68 additions & 4 deletions packages/ods/src/components/range/tests/behavior/ods-range.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ describe('ods-range behavior', () => {
let el: E2EElement;
let page: E2EPage;

async function setup(content: string): Promise<void> {
async function setup(content: string, additionalProperties?: Record<string, unknown>): Promise<void> {
page = await newE2EPage();

await page.setContent(content);
await page.evaluate(() => document.body.style.setProperty('margin', '0px'));

el = await page.find('ods-range');

additionalProperties && Object.entries(additionalProperties).forEach(([key, value]) => {
el.setProperty(key, value);
});
await page.waitForChanges();
}

Expand Down Expand Up @@ -47,12 +51,12 @@ describe('ods-range behavior', () => {
await page.keyboard.press('ArrowUp');
await page.waitForChanges();

expect(await el.getProperty('value')).toBe(1);
expect(await el.getProperty('value')).toBe(51);
expect(odsChangeSpy).toHaveReceivedEventTimes(1);
expect(odsChangeSpy).toHaveReceivedEventDetail({
name: 'name',
validity: {},
value: 1,
value: 51,
});
});

Expand All @@ -64,11 +68,71 @@ describe('ods-range behavior', () => {
await page.keyboard.press('ArrowUp');
await page.waitForChanges();

expect(await el.getProperty('value')).toBe(0);
expect(await el.getProperty('value')).toBe(50);
expect(odsChangeSpy).not.toHaveReceivedEvent();
});
});

describe('change:min&max', () => {
it('should change value with max inf value', async() => {
await setup('<ods-range min="0" max="100" value="50"></ods-range>');
const newMax = 40;
await el.setProperty('max', newMax);
await page.waitForChanges();

expect(await el.getProperty('value')).toBe(newMax);
});

it('should change value with min if min > value', async() => {
await setup('<ods-range min="0" max="100" value="50"></ods-range>');
const newMin = 60;
await el.setProperty('min', newMin);
await page.waitForChanges();

expect(await el.getProperty('value')).toBe(newMin);
});

it('should change value dual with max if max < one value', async() => {
await setup('<ods-range min="0" max="100"></ods-range>', { value: [30, 70] });
const newMax = 60;
await el.setProperty('max', newMax);
await page.waitForChanges();

expect((await el.getProperty('value'))?.[0]).toBe(30);
expect((await el.getProperty('value'))?.[1]).toBe(newMax);
});

it('should change value dual with min if min > one value', async() => {
await setup('<ods-range min="0" max="100"></ods-range>', { value: [30, 70] });
const newMin = 60;
await el.setProperty('min', newMin);
await page.waitForChanges();

expect((await el.getProperty('value'))?.[0]).toBe(newMin);
expect((await el.getProperty('value'))?.[1]).toBe(70);
});

it('should change value dual with max if max > both value', async() => {
await setup('<ods-range min="0" max="100"></ods-range>', { value: [30, 70] });
const newMax = 20;
await el.setProperty('max', newMax);
await page.waitForChanges();

expect((await el.getProperty('value'))?.[0]).toBe(newMax);
expect((await el.getProperty('value'))?.[1]).toBe(newMax);
});

it('should change value dual with min if min > both value', async() => {
await setup('<ods-range min="0" max="100"></ods-range>', { value: [30, 50] });
const newMin = 60;
await el.setProperty('min', newMin);
await page.waitForChanges();

expect((await el.getProperty('value'))?.[0]).toBe(newMin);
expect((await el.getProperty('value'))?.[1]).toBe(newMin);
});
});

describe('Form', () => {
it('should get form data with button type submit', async() => {
await setup(`<form method="get">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
import { isDualRange, toPercentage } from '../../src/controller/ods-range';
import { getDefaultValue, isDualRange, toPercentage } from '../../src/controller/ods-range';

describe('ods-range controller', () => {
describe('isDualRange function', () => {

describe('getDefaultValue', () => {
it('returns the provided defaultValue if specified', () => {
expect(getDefaultValue(0, 10, 5)).toBe(5);
expect(getDefaultValue(0, 10, [3, 7])).toEqual([3, 7]);
});

it('calculates the midpoint if no defaultValue is provided', () => {
expect(getDefaultValue(0, 10)).toBe(5);
expect(getDefaultValue(0, 0)).toBe(0);
});

it('handles cases where max < min by returning min', () => {
expect(getDefaultValue(10, 5)).toBe(10);
expect(getDefaultValue(-5, -10)).toBe(-5);
});
});

describe('isDualRange', () => {
it('should return true for valid dual range', () => {
expect(isDualRange([1, 2])).toBe(true);
});
Expand Down Expand Up @@ -35,7 +53,7 @@ describe('ods-range controller', () => {
});
});

describe('toPercentage function', () => {
describe('toPercentage', () => {
it('should return correct percentage for valid numbers', () => {
expect(toPercentage(100, 0, 50)).toBe(50);
});
Expand Down
15 changes: 15 additions & 0 deletions packages/ods/src/components/range/tests/rendering/ods-range.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,19 @@ describe('ods-range rendering', () => {

expect(el.shadowRoot).not.toBeNull();
});

describe('defaultValue', () => {
it('get defaultValue with props', async() => {
const defaultValue = 40;
await setup(`<ods-range default-value="${defaultValue}"></ods-range>`);

expect(await el.getProperty('value')).toBe(defaultValue);
});

it('get defaultValue with midpoint max and min', async() => {
await setup('<ods-range min="0" max="50"></ods-range>');

expect(await el.getProperty('value')).toBe(25);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ describe('ods-range rendering', () => {
expect(root?.getAttribute('value')).toBe(value.toString());
});

it('should be set by default', async() => {
it('should not be set by default', async() => {
await setup('<ods-range></ods-range>');

expect(root?.getAttribute('value')).toBe('0');
expect(root?.getAttribute('value')).toBeNull();
});
});
});
16 changes: 8 additions & 8 deletions packages/ods/src/style/_range.scss
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
@use './focus';

$ods-range-height: 8px;
$ods-range-size-thumb: 16px;
$ods-range-height: 32px;
$ods-input-range-height: 8px;
$ods-input-range-size-thumb: 16px;
$range-background-color-active: var(--ods-color-primary-500);
$range-background-color: var(--ods-color-neutral-300);

@mixin ods-range() {
$range: &;

appearance: none;
position: absolute;
outline: none;
border-radius: var(--ods-border-radius-sm);
cursor: pointer;
width: 100%;
height: $ods-range-height;
height: $ods-input-range-height;

&::-webkit-slider-thumb {
@include thumb();
Expand Down Expand Up @@ -105,8 +104,8 @@ $range-background-color: var(--ods-color-neutral-300);
box-shadow: none;
background-color: var(--ods-color-neutral-000);
cursor: pointer;
width: $ods-range-size-thumb;
height: $ods-range-size-thumb;
width: $ods-input-range-size-thumb;
height: $ods-input-range-size-thumb;
}

@mixin thumb-hover-active() {
Expand Down Expand Up @@ -145,8 +144,9 @@ $range-background-color: var(--ods-color-neutral-300);
}

.ods-range__range {
position: absolute;
z-index: 2;
margin-top: 6px;
margin-top: $ods-input-range-height;
height: 0;
}
}
Expand Down

0 comments on commit 4f4d62d

Please sign in to comment.