Skip to content

Commit

Permalink
Ensure isSelected works if item value is false or 0 (#4005)
Browse files Browse the repository at this point in the history
  • Loading branch information
gdebrauwer committed Jan 29, 2024
1 parent 77b1736 commit 5693447
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/ui/src/combobox.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ function handleRoot(el, Alpine) {
let item = this.__context.getItemByEl(el)

if (! item) return false
if (! item.value) return false
if (item.value === null || item.value === undefined) return false

return this.__hasSelected(item.value)
},
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/listbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ function handleRoot(el, Alpine) {
let item = this.__context.getItemByEl(el)

if (! item) return false
if (! item.value) return false
if (item.value === null || item.value === undefined) return false

return this.__hasSelected(item.value)
},
Expand Down
141 changes: 141 additions & 0 deletions tests/cypress/integration/plugins/ui/combobox.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1666,3 +1666,144 @@ test('works with morph',
get('button').should(haveText('Select Framework (updated)'))
},
)

test('boolean option values',
[html`
<div x-data="{ value: null }">
<div x-combobox x-model="value">
<input x-combobox:input />
<button x-combobox:button>Select boolean</button>
<ul x-combobox:options>
<li
option="boolean-true"
x-combobox:option
:value="true"
:class="{
'selected': $comboboxOption.isSelected,
'active': $comboboxOption.isActive,
}">
<span>Yes</span>
</li>
<li
option="boolean-false"
x-combobox:option
:value="false"
:class="{
'selected': $comboboxOption.isSelected,
'active': $comboboxOption.isActive,
}">
<span>No</span>
</li>
</ul>
</div>
Selected: <p x-text="value?.toString()"></p>
</div>
`],
({ get }) => {
get('ul').should(notBeVisible())
get('p').should(haveText(''))
get('button')
.should(haveText('Select boolean'))
.click()
get('ul').should(beVisible())
get('[option="boolean-true"]').should(notHaveClasses(['selected']))
get('[option="boolean-false"]').should(notHaveClasses(['selected']))
get('[option="boolean-true"]').click()
get('ul').should(notBeVisible())
get('p').should(haveText('true'))
get('button').click()
get('ul').should(beVisible())
get('[option="boolean-true"]').should(haveClasses(['selected']))
get('[option="boolean-false"]').should(notHaveClasses(['selected']))
get('[option="boolean-false"]').click()
get('ul').should(notBeVisible())
get('p').should(haveText('false'))
get('button').click()
get('ul').should(beVisible())
get('[option="boolean-true"]').should(notHaveClasses(['selected']))
get('[option="boolean-false"]').should(haveClasses(['selected']))
},
)

test('integer option values',
[html`
<div x-data="{ value: null }">
<div x-combobox x-model="value">
<input x-combobox:input />
<button x-combobox:button>Select number</button>
<ul x-combobox:options>
<li
option="0"
x-combobox:option
:value="0"
:class="{
'selected': $comboboxOption.isSelected,
'active': $comboboxOption.isActive,
}">
<span>0</span>
</li>
<li
option="1"
x-combobox:option
:value="1"
:class="{
'selected': $comboboxOption.isSelected,
'active': $comboboxOption.isActive,
}">
<span>1</span>
</li>
<li
option="2"
x-combobox:option
:value="2"
:class="{
'selected': $comboboxOption.isSelected,
'active': $comboboxOption.isActive,
}">
<span>2</span>
</li>
</ul>
</div>
Selected: <p x-text="value?.toString()"></p>
</div>
`],
({ get }) => {
get('ul').should(notBeVisible())
get('p').should(haveText(''))
get('button')
.should(haveText('Select number'))
.click()
get('ul').should(beVisible())
get('[option="0"]').should(notHaveClasses(['selected']))
get('[option="1"]').should(notHaveClasses(['selected']))
get('[option="2"]').should(notHaveClasses(['selected']))
get('[option="1"]').click()
get('ul').should(notBeVisible())
get('p').should(haveText('1'))
get('button').click()
get('ul').should(beVisible())
get('[option="0"]').should(notHaveClasses(['selected']))
get('[option="1"]').should(haveClasses(['selected']))
get('[option="2"]').should(notHaveClasses(['selected']))
get('[option="0"]').click()
get('ul').should(notBeVisible())
get('p').should(haveText('0'))
get('button').click()
get('ul').should(beVisible())
get('[option="0"]').should(haveClasses(['selected']))
get('[option="1"]').should(notHaveClasses(['selected']))
get('[option="2"]').should(notHaveClasses(['selected']))
get('[option="2"]').click()
get('ul').should(notBeVisible())
get('p').should(haveText('2'))
get('button').click()
get('ul').should(beVisible())
get('[option="0"]').should(notHaveClasses(['selected']))
get('[option="1"]').should(notHaveClasses(['selected']))
get('[option="2"]').should(haveClasses(['selected']))
},
)
134 changes: 134 additions & 0 deletions tests/cypress/integration/plugins/ui/listbox.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -957,4 +957,138 @@ test('works with morph',
},
)


test('boolean option values',
[html`
<div x-data="{ value: null }" x-listbox x-model="value">
<label x-listbox:label>Value</label>
<button x-listbox:button x-text="value !== null ? value.toString() : 'Select boolean'"></button>
<ul x-listbox:options options>
<li
option="boolean-true"
x-listbox:option
:value="true"
:class="{
'selected': $listboxOption.isSelected,
'active': $listboxOption.isActive,
}">
<span>Yes</span>
</li>
<li
option="boolean-false"
x-listbox:option
:value="false"
:class="{
'selected': $listboxOption.isSelected,
'active': $listboxOption.isActive,
}">
<span>No</span>
</li>
</ul>
</div>
`],
({ get }) => {
get('ul').should(notBeVisible())
get('button')
.should(haveText('Select boolean'))
.click()
get('ul').should(beVisible())
get('[option="boolean-true"]').should(notHaveClasses(['selected']))
get('[option="boolean-false"]').should(notHaveClasses(['selected']))
get('[option="boolean-true"]').click()
get('ul').should(notBeVisible())
get('button').should(haveText('true'))
get('button').click()
get('ul').should(beVisible())
get('[option="boolean-true"]').should(haveClasses(['selected']))
get('[option="boolean-false"]').should(notHaveClasses(['selected']))
get('[option="boolean-false"]').click()
get('ul').should(notBeVisible())
get('button').should(haveText('false'))
get('button').click()
get('ul').should(beVisible())
get('[option="boolean-true"]').should(notHaveClasses(['selected']))
get('[option="boolean-false"]').should(haveClasses(['selected']))
},
)

test('integer option values',
[html`
<div x-data="{ value: null }" x-listbox x-model="value">
<label x-listbox:label>Value</label>
<button x-listbox:button x-text="value !== null ? value.toString() : 'Select number'"></button>
<ul x-listbox:options options>
<li
option="0"
x-listbox:option
:value="0"
:class="{
'selected': $listboxOption.isSelected,
'active': $listboxOption.isActive,
}">
<span>0</span>
</li>
<li
option="1"
x-listbox:option
:value="1"
:class="{
'selected': $listboxOption.isSelected,
'active': $listboxOption.isActive,
}">
<span>1</span>
</li>
<li
option="2"
x-listbox:option
:value="2"
:class="{
'selected': $listboxOption.isSelected,
'active': $listboxOption.isActive,
}">
<span>2</span>
</li>
</ul>
</div>
`],
({ get }) => {
get('ul').should(notBeVisible())
get('button')
.should(haveText('Select number'))
.click()
get('ul').should(beVisible())
get('[option="0"]').should(notHaveClasses(['selected']))
get('[option="1"]').should(notHaveClasses(['selected']))
get('[option="2"]').should(notHaveClasses(['selected']))
get('[option="1"]').click()
get('ul').should(notBeVisible())
get('button').should(haveText('1'))
get('button').click()
get('ul').should(beVisible())
get('[option="0"]').should(notHaveClasses(['selected']))
get('[option="1"]').should(haveClasses(['selected']))
get('[option="2"]').should(notHaveClasses(['selected']))
get('[option="0"]').click()
get('ul').should(notBeVisible())
get('button').should(haveText('0'))
get('button').click()
get('ul').should(beVisible())
get('[option="0"]').should(haveClasses(['selected']))
get('[option="1"]').should(notHaveClasses(['selected']))
get('[option="2"]').should(notHaveClasses(['selected']))
get('[option="2"]').click()
get('ul').should(notBeVisible())
get('button').should(haveText('2'))
get('button').click()
get('ul').should(beVisible())
get('[option="0"]').should(notHaveClasses(['selected']))
get('[option="1"]').should(notHaveClasses(['selected']))
get('[option="2"]').should(haveClasses(['selected']))
},
)

// test "by" attribute

0 comments on commit 5693447

Please sign in to comment.