From d0c06708a905410e35d9285af6ead3f8ac384b3f Mon Sep 17 00:00:00 2001 From: Honore Hounwanou Date: Tue, 19 Aug 2025 20:38:33 -0400 Subject: [PATCH] [LiveComponent] Return empty string for `data-value=""` instead of falling back to null --- .../assets/dist/live_controller.js | 2 +- src/LiveComponent/assets/src/dom_utils.ts | 2 +- .../assets/test/unit/dom_utils.test.ts | 34 +++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/LiveComponent/assets/dist/live_controller.js b/src/LiveComponent/assets/dist/live_controller.js index b1f8049a6f4..ddb40ed667d 100644 --- a/src/LiveComponent/assets/dist/live_controller.js +++ b/src/LiveComponent/assets/dist/live_controller.js @@ -377,7 +377,7 @@ function getValueFromElement(element, valueStore) { } return element.value; } - if (element.dataset.value) { + if (element.hasAttribute("data-value")) { return element.dataset.value; } if ("value" in element) { diff --git a/src/LiveComponent/assets/src/dom_utils.ts b/src/LiveComponent/assets/src/dom_utils.ts index 0a8afe29b74..c99275ee587 100644 --- a/src/LiveComponent/assets/src/dom_utils.ts +++ b/src/LiveComponent/assets/src/dom_utils.ts @@ -51,7 +51,7 @@ export function getValueFromElement(element: HTMLElement, valueStore: ValueStore } // element is some other element - if (element.dataset.value) { + if (element.hasAttribute('data-value')) { return element.dataset.value; } diff --git a/src/LiveComponent/assets/test/unit/dom_utils.test.ts b/src/LiveComponent/assets/test/unit/dom_utils.test.ts index e5c9613555e..7ce80e52c26 100644 --- a/src/LiveComponent/assets/test/unit/dom_utils.test.ts +++ b/src/LiveComponent/assets/test/unit/dom_utils.test.ts @@ -110,6 +110,40 @@ describe('getValueFromElement', () => { expect(getValueFromElement(div, createStore())).toEqual('the_value_from_attribute'); }); + + it('Returns empty string for data-value=""', () => { + const btn = document.createElement('button'); + // simulate the attribute explicitly present but empty + btn.dataset.value = ''; + // also set a value on the button to ensure data-value takes precedence + btn.value = 'should_not_be_used'; + expect(getValueFromElement(btn, createStore())).toBe(''); + }); + + it('Returns "0" for data-value="0" (falsy but valid)', () => { + const el = document.createElement('div'); + el.dataset.value = '0'; + expect(getValueFromElement(el, createStore())).toBe('0'); + }); + + it('Prefers data-value over value attribute when both are present', () => { + const el = document.createElement('div'); + el.dataset.value = 'from_data_value'; + el.setAttribute('value', 'from_value_attribute'); + expect(getValueFromElement(el, createStore())).toBe('from_data_value'); + }); + + it('Falls back to value attribute when data-value is absent', () => { + const el = document.createElement('div'); + el.setAttribute('value', ''); + // No data-value set + expect(getValueFromElement(el, createStore())).toBe(''); + }); + + it('Returns null when neither data-value nor value attribute nor value property is present', () => { + const el = document.createElement('div'); + expect(getValueFromElement(el, createStore())).toBe(null); + }); }); describe('setValueOnElement', () => {