Fix strength meter binding the field after it instead of before it (#3192)

Co-authored-by: codecalm <codecalm@gmail.com>
This commit is contained in:
Bartosz-Doandcodecalm authored and GitHub committed 2026-09-25 12:13:40 +02:00
1 parent 77480290dc
commit f7c3956667
3 files changed
+50 -3

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
---
"@tabler/core": patch
---
Fixed the strength meter rating a confirm-password field after it instead of the password field before it.
+6 -3
View File
@@ -170,11 +170,14 @@ class Strength extends BaseComponent {
return SelectorEngine.findOne(input) as HTMLInputElement | null
}
// Without an explicit selector only the meter's own parent is searched, so
// a form with several password fields cannot bind the wrong one.
// Without an explicit selector only the meter's own parent is searched.
// The nearest field before the meter wins, so a confirm-password field
// placed after it is never mistaken for the one being rated; a meter
// placed above its field falls back to the first field after it.
const parent = this._element.parentElement
const fields = parent ? (SelectorEngine.find(SELECTOR_PASSWORD, parent) as HTMLInputElement[]) : []
return fields[fields.length - 1] ?? null
const precedingFields = fields.filter((field) => Boolean(field.compareDocumentPosition(this._element) & Node.DOCUMENT_POSITION_FOLLOWING))
return precedingFields[precedingFields.length - 1] ?? fields[0] ?? null
}
_getText(): HTMLElement | null {
+39
View File
@@ -69,6 +69,45 @@ describe('Strength', () => {
expect(instance._input).toBe(fixtureEl.querySelector('#remote'))
})
it('should bind the password field before it, not a confirm field after it', () => {
fixtureEl.innerHTML = `
<div>
<input type="password" id="pw">
<div class="strength" data-bs-strength><span class="strength-segment"></span></div>
<input type="password" id="pw2">
</div>`
const instance = new Strength(meter())
expect(instance._input).toBe(fixtureEl.querySelector('#pw'))
})
it('should bind the last of several preceding fields, ignoring one after it', () => {
fixtureEl.innerHTML = `
<div>
<input type="password" id="old">
<input type="password" id="new">
<div class="strength" data-bs-strength><span class="strength-segment"></span></div>
<input type="password" id="confirm">
</div>`
const instance = new Strength(meter())
expect(instance._input).toBe(fixtureEl.querySelector('#new'))
})
it('should bind the field after it when none precedes it', () => {
fixtureEl.innerHTML = `
<div>
<div class="strength" data-bs-strength><span class="strength-segment"></span></div>
<input type="password" id="confirm">
</div>`
const instance = new Strength(meter())
expect(instance._input).toBe(fixtureEl.querySelector('#confirm'))
})
})
describe('levels', () => {