Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e563341
refactor: two-way binding using proxy to improve input synchronization
mohamedhyouns Dec 12, 2024
f16a7c1
chore: generate the new assets
mohamedhyouns Dec 12, 2024
7c4183f
refactor: add 'name' attributes for proxy-based synchronization
mohamedhyouns Dec 12, 2024
6616d75
fix: unit tests
mohamedhyouns Dec 12, 2024
6417327
chore: deprecate multi-stage event test
mohamedhyouns Dec 12, 2024
73174a8
test: add new test coverage
mohamedhyouns Dec 12, 2024
c38fb11
style: reformating the file
mohamedhyouns Dec 12, 2024
71f288d
fix: replace `name` with `data-dxb-proxy-key`
mohamedhyouns Dec 17, 2024
8ecc562
fix: set slider in the middle if the input field is cleared
mohamedhyouns Dec 19, 2024
402568a
fix: set slider in the middle in both inputs when input number is empty
mohamedhyouns Dec 22, 2024
91878c7
Merge branch '2.x' into mohamedhany/2.x/#32-refactor-two-way-binding
jjroelofs Jan 7, 2025
fd63495
fix: prevent input value from exceeding maximum value
mohamedhyouns Jan 21, 2025
fcc97f4
fix: support new slider `investment`
mohamedhyouns Jan 21, 2025
5aa8e33
fix: deprecate `data-dxb-proxy-key` data attribute
mohamedhyouns Jan 21, 2025
68ee689
fix: `MutationObserver` infinite loop
mohamedhyouns Jan 22, 2025
a4496c0
fix: move reset max logic to proxy
mohamedhyouns Jan 22, 2025
a4a1d4c
chore: decouple input listeners
mohamedhyouns Jan 22, 2025
c2927bf
chore: update dist file
mohamedhyouns Jan 22, 2025
7a41514
feat: improve input validation and handling in `dxb-slider.js`
mohamedhyouns Feb 2, 2025
631254b
chore: update tests
mohamedhyouns Feb 3, 2025
4e88e93
fix: allow empty/clear input
mohamedhyouns Feb 3, 2025
f789629
chore: update dist file
mohamedhyouns Feb 3, 2025
bba3606
chore: remove `getDefaultValue`
mohamedhyouns Feb 3, 2025
09d663a
fix: allow emptiness when clearing in case of min isn't Zero
mohamedhyouns Feb 3, 2025
1354a0c
refactor: improve value handling and precision in `updateFieldValue`
mohamedhyouns Feb 6, 2025
901089a
Merge branch '2.x' into mohamedhany/2.x/#32-refactor-two-way-binding
mohamedhyouns Jun 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 177 additions & 9 deletions __tests__/dxb-slider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,17 @@ describe('DXB Slider Core Tests', () => {
expect(numberInput.value).toBe('75');
});

it('should synchronize range and number input values (0 based)', () => {
slider.value = 0;
slider.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe('0');
});

it('should initialize dynamically added sliders', async () => {
const newSlider = document.createElement('input');
newSlider.type = 'range';
newSlider.setAttribute('data-dxb-slider', '');
newSlider.id = "myNewSlider";

// Append the new slider to the DOM
document.body.appendChild(newSlider);
Expand All @@ -63,21 +70,34 @@ describe('DXB Slider Core Tests', () => {
expect(newSlider.hasAttribute('data-dxb-initialized')).toBe(true);
});

it('should dispatch change event on number input change', () => {
const changeHandler = vi.fn();

slider.addEventListener('change', changeHandler);
it('should synchronize values on number input change', () => {
numberInput.value = 80;
numberInput.dispatchEvent(new window.Event('change'));
numberInput.dispatchEvent(new window.Event('input'));

expect(changeHandler).toHaveBeenCalled();
expect(slider.value).toBe('80');
});

it('should synchronize values on number input change', () => {
numberInput.value = 80;
it('should clamp value to max when number input exceeds max limit', () => {
numberInput.max = 100;
numberInput.value = 1000;
numberInput.dispatchEvent(new window.Event('input'));

expect(slider.value).toBe('80');
expect(numberInput.value).toBe('100');
});


it('should synchronize values on number input change (0 based)', () => {
numberInput.value = "";
numberInput.dispatchEvent(new window.Event('input'));

expect(slider.value).toBe('0');
});

it('should synchronize values on number input change (empty)', () => {
numberInput.value = "";
numberInput.dispatchEvent(new window.Event('input'));

expect(numberInput.value).toBe('');
});

it('should set initial ARIA attributes', () => {
Expand All @@ -93,6 +113,154 @@ describe('DXB Slider Core Tests', () => {
});
});

describe('DXB Slider Negative Value Tests', () => {
let document;
let window;
let slider;
let numberInput;

beforeEach(() => {
const scriptContent = fs.readFileSync(path.resolve(__dirname, '../dxb-slider.js'), 'utf8');

const dom = new JSDOM(`
<html>
<body>
<label for="negativeSlider">Negative Slider</label>
<input type="range" id="negativeSlider" class="dxb-slider"
min="-50" max="50" value="-25" step="5"
data-dxb-slider>
<script>${scriptContent}</script>
</body>
</html>
`, { runScripts: "dangerously", resources: "usable" });

document = dom.window.document;
window = dom.window;
global.document = document;
global.window = window;

slider = document.querySelector('#negativeSlider');
numberInput = document.querySelector('.dxb-slider-value');
});

it('should initialize the slider with negative min value', () => {
expect(slider.min).toBe('-50');
expect(slider.max).toBe('50');
expect(slider.value).toBe('-25');
});

it('should synchronize values between slider and number input (negative values)', () => {
slider.value = -40;
slider.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe('-40');
});

it('should synchronize values when number input is updated with a negative value', () => {
numberInput.value = -10;
numberInput.dispatchEvent(new window.Event('input'));
expect(slider.value).toBe('-10');
});

it('should clamp values to min when below min limit', () => {
numberInput.value = -100;
numberInput.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe('-50');
expect(slider.value).toBe('-50');
});

it('should allow entering "-" without immediately parsing', () => {

// Since JSDOM does not allow incomplete number input states (like "-"), we have to mock it manually
Object.defineProperty(numberInput, "value", {
get: () => "-",
set: () => { }, // Prevents JSDOM from resetting it
configurable: true
});

numberInput.dispatchEvent(new window.InputEvent("input", { data: "-" }));

expect(numberInput.value).toBe("-");
});

});

describe('DXB Slider Floating Point Tests', () => {
let document;
let window;
let slider;
let numberInput;

beforeEach(() => {
const scriptContent = fs.readFileSync(path.resolve(__dirname, '../dxb-slider.js'), 'utf8');

const dom = new JSDOM(`
<html>
<body>
<label for="mySlider">Slider Label</label>
<input type="range" id="mySlider" class="dxb-slider"
min="0.1" max="10.5" value="5.5" step="0.1"
data-dxb-slider>
<script>${scriptContent}</script>
</body>
</html>
`, { runScripts: "dangerously", resources: "usable" });

document = dom.window.document;
window = dom.window;
global.document = document;
global.window = window;

slider = document.querySelector('#mySlider');
numberInput = document.querySelector('.dxb-slider-value');
});

it('should allow entering "." without immediate parsing', () => {
// Prevent JSDOM from resetting an incomplete decimal state
Object.defineProperty(numberInput, "value", {
get: () => "5.",
set: () => { },
configurable: true
});

numberInput.dispatchEvent(new window.InputEvent("input", { data: "." }));

expect(numberInput.value).toBe("5."); // Allow incomplete decimal state
});

it('should synchronize range and number input values with floating points', () => {
slider.value = "7.3";
slider.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe("7.3");
});

it('should clamp values to max boundary for floating points', () => {
numberInput.value = "20.3"; // Exceeding max
numberInput.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe("10.5"); // Clamped to max
});

it('should clamp values to min boundary for floating points', () => {
numberInput.value = "-5.0"; // Below min
numberInput.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe("0.1"); // Clamped to min
});

it('should retain correct floating point precision when stepping up', () => {
numberInput.value = "2.2";
numberInput.stepUp();
numberInput.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe("2.3"); // Step increment of 0.1
});

it('should retain correct floating point precision when stepping down', () => {
numberInput.value = "3.5";
numberInput.stepDown();
numberInput.dispatchEvent(new window.Event('input'));
expect(numberInput.value).toBe("3.4"); // Step decrement of 0.1
});
});


describe('DXB Slider Step Tests', () => {
let document;
let window;
Expand Down
Loading