Skip to content

Commit

Permalink
fix(ld-radio): change selection with arrow buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
borisdiakur authored Oct 28, 2021
1 parent 71024c7 commit a071221
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 13 deletions.
17 changes: 13 additions & 4 deletions src/liquid/components/ld-radio/ld-radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ export class LdRadio implements InnerFocusable {
case 'ArrowUp':
case 'ArrowLeft': {
ev.preventDefault()
this.focusRadio('prev')
this.focusAndSelect('prev')
return
}
case 'ArrowDown':
case 'ArrowRight': {
ev.preventDefault()
this.focusRadio('next')
this.focusAndSelect('next')
return
}
}
Expand Down Expand Up @@ -123,13 +123,17 @@ export class LdRadio implements InnerFocusable {
this.el.dispatchEvent(new Event('input', { bubbles: true, composed: true }))
}

private focusRadio(dir: 'next' | 'prev') {
private focusAndSelect(dir: 'next' | 'prev') {
const ldRadios = Array.from(document.querySelectorAll('ld-radio')).filter(
(ldRadio) => ldRadio.getAttribute('name') === this.name
)
ldRadios.forEach((ldRadio, index) => {
if (ldRadio === ((this.el as unknown) as HTMLLdRadioElement)) {
ldRadios[index + (dir === 'next' ? 1 : -1)]?.focusInner()
const targetLdRadio = ldRadios[index + (dir === 'next' ? 1 : -1)]
if (targetLdRadio) {
targetLdRadio.focusInner()
targetLdRadio.click()
}
}
})
}
Expand Down Expand Up @@ -174,6 +178,11 @@ export class LdRadio implements InnerFocusable {
{...cloneAttributes(this.el)}
disabled={this.disabled}
checked={this.checked}
tabIndex={
this.checked
? parseInt(this.el.getAttribute('tabindex')) || undefined
: -1
}
/>
<div part="dot" class="ld-radio__dot"></div>
<div class="ld-radio__box" part="box"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`ld-radio creates hidden input field, if inside a form 1`] = `
<ld-radio class="ld-radio" part="root">
<mock:shadow-root>
<input part="input focusable" type="radio">
<input part="input focusable" tabindex="-1" type="radio">
<div class="ld-radio__dot" part="dot"></div>
<div class="ld-radio__box" part="box"></div>
</mock:shadow-root>
Expand All @@ -14,7 +14,7 @@ exports[`ld-radio creates hidden input field, if inside a form 1`] = `
exports[`ld-radio danger 1`] = `
<ld-radio class="ld-radio ld-radio--danger" mode="danger" part="root">
<mock:shadow-root>
<input part="input focusable" type="radio">
<input part="input focusable" tabindex="-1" type="radio">
<div class="ld-radio__dot" part="dot"></div>
<div class="ld-radio__box" part="box"></div>
</mock:shadow-root>
Expand All @@ -24,7 +24,7 @@ exports[`ld-radio danger 1`] = `
exports[`ld-radio disabled 1`] = `
<ld-radio class="ld-radio" disabled="" part="root">
<mock:shadow-root>
<input disabled="" part="input focusable" type="radio">
<input disabled="" part="input focusable" tabindex="-1" type="radio">
<div class="ld-radio__dot" part="dot"></div>
<div class="ld-radio__box" part="box"></div>
</mock:shadow-root>
Expand All @@ -34,7 +34,7 @@ exports[`ld-radio disabled 1`] = `
exports[`ld-radio heighlight 1`] = `
<ld-radio class="ld-radio ld-radio--highlight" mode="highlight" part="root">
<mock:shadow-root>
<input part="input focusable" type="radio">
<input part="input focusable" tabindex="-1" type="radio">
<div class="ld-radio__dot" part="dot"></div>
<div class="ld-radio__box" part="box"></div>
</mock:shadow-root>
Expand All @@ -44,7 +44,7 @@ exports[`ld-radio heighlight 1`] = `
exports[`ld-radio renders 1`] = `
<ld-radio class="ld-radio" part="root">
<mock:shadow-root>
<input part="input focusable" type="radio">
<input part="input focusable" tabindex="-1" type="radio">
<div class="ld-radio__dot" part="dot"></div>
<div class="ld-radio__box" part="box"></div>
</mock:shadow-root>
Expand All @@ -54,7 +54,7 @@ exports[`ld-radio renders 1`] = `
exports[`ld-radio tone 1`] = `
<ld-radio class="ld-radio ld-radio--dark" part="root" tone="dark">
<mock:shadow-root>
<input part="input focusable" type="radio">
<input part="input focusable" tabindex="-1" type="radio">
<div class="ld-radio__dot" part="dot"></div>
<div class="ld-radio__box" part="box"></div>
</mock:shadow-root>
Expand Down
51 changes: 48 additions & 3 deletions src/liquid/components/ld-radio/test/ld-radio.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,13 @@ describe('ld-radio', () => {
expect(ldRadios[3].getAttribute('checked')).not.toBe(null)
})

it('moves focus', async () => {
it('moves focus and selection', async () => {
const page = await newSpecPage({
components: [LdRadio],
html: `
<ld-radio name="foo" />
<ld-radio name="bar" />
<ld-radio name="foo" checked />
<ld-radio name="bar" />
<ld-radio name="foo" />
<ld-radio name="baz" />
<ld-radio name="foo" />
`,
Expand All @@ -161,6 +161,9 @@ describe('ld-radio', () => {
const radios = ldRadios.map((ldRadio) =>
ldRadio.shadowRoot.querySelector('input')
)
ldRadios.forEach((ldRadio) => {
ldRadio.click = jest.fn()
})
radios.forEach((radio) => {
radio.focus = jest.fn()
})
Expand All @@ -170,6 +173,12 @@ describe('ld-radio', () => {
) // nothing shall happen
await page.waitForChanges()

expect(ldRadios[0].click).toHaveBeenCalledTimes(0)
expect(ldRadios[1].click).toHaveBeenCalledTimes(0)
expect(ldRadios[2].click).toHaveBeenCalledTimes(0)
expect(ldRadios[3].click).toHaveBeenCalledTimes(0)
expect(ldRadios[4].click).toHaveBeenCalledTimes(0)

expect(radios[0].focus).toHaveBeenCalledTimes(0)
expect(radios[1].focus).toHaveBeenCalledTimes(0)
expect(radios[2].focus).toHaveBeenCalledTimes(0)
Expand All @@ -181,6 +190,12 @@ describe('ld-radio', () => {
)
await page.waitForChanges()

expect(ldRadios[0].click).toHaveBeenCalledTimes(0)
expect(ldRadios[1].click).toHaveBeenCalledTimes(0)
expect(ldRadios[2].click).toHaveBeenCalledTimes(1)
expect(ldRadios[3].click).toHaveBeenCalledTimes(0)
expect(ldRadios[4].click).toHaveBeenCalledTimes(0)

expect(radios[0].focus).toHaveBeenCalledTimes(0)
expect(radios[1].focus).toHaveBeenCalledTimes(0)
expect(radios[2].focus).toHaveBeenCalledTimes(1)
Expand All @@ -192,6 +207,12 @@ describe('ld-radio', () => {
)
await page.waitForChanges()

expect(ldRadios[0].click).toHaveBeenCalledTimes(0)
expect(ldRadios[1].click).toHaveBeenCalledTimes(0)
expect(ldRadios[2].click).toHaveBeenCalledTimes(1)
expect(ldRadios[3].click).toHaveBeenCalledTimes(0)
expect(ldRadios[4].click).toHaveBeenCalledTimes(1)

expect(radios[0].focus).toHaveBeenCalledTimes(0)
expect(radios[1].focus).toHaveBeenCalledTimes(0)
expect(radios[2].focus).toHaveBeenCalledTimes(1)
Expand All @@ -203,6 +224,12 @@ describe('ld-radio', () => {
)
await page.waitForChanges()

expect(ldRadios[0].click).toHaveBeenCalledTimes(0)
expect(ldRadios[1].click).toHaveBeenCalledTimes(0)
expect(ldRadios[2].click).toHaveBeenCalledTimes(1)
expect(ldRadios[3].click).toHaveBeenCalledTimes(0)
expect(ldRadios[4].click).toHaveBeenCalledTimes(1)

expect(radios[0].focus).toHaveBeenCalledTimes(0)
expect(radios[1].focus).toHaveBeenCalledTimes(0)
expect(radios[2].focus).toHaveBeenCalledTimes(1)
Expand All @@ -214,6 +241,12 @@ describe('ld-radio', () => {
)
await page.waitForChanges()

expect(ldRadios[0].click).toHaveBeenCalledTimes(0)
expect(ldRadios[1].click).toHaveBeenCalledTimes(0)
expect(ldRadios[2].click).toHaveBeenCalledTimes(2)
expect(ldRadios[3].click).toHaveBeenCalledTimes(0)
expect(ldRadios[4].click).toHaveBeenCalledTimes(1)

expect(radios[0].focus).toHaveBeenCalledTimes(0)
expect(radios[1].focus).toHaveBeenCalledTimes(0)
expect(radios[2].focus).toHaveBeenCalledTimes(2)
Expand All @@ -225,6 +258,12 @@ describe('ld-radio', () => {
)
await page.waitForChanges()

expect(ldRadios[0].click).toHaveBeenCalledTimes(1)
expect(ldRadios[1].click).toHaveBeenCalledTimes(0)
expect(ldRadios[2].click).toHaveBeenCalledTimes(2)
expect(ldRadios[3].click).toHaveBeenCalledTimes(0)
expect(ldRadios[4].click).toHaveBeenCalledTimes(1)

expect(radios[0].focus).toHaveBeenCalledTimes(1)
expect(radios[1].focus).toHaveBeenCalledTimes(0)
expect(radios[2].focus).toHaveBeenCalledTimes(2)
Expand All @@ -236,6 +275,12 @@ describe('ld-radio', () => {
)
await page.waitForChanges()

expect(ldRadios[0].click).toHaveBeenCalledTimes(1)
expect(ldRadios[1].click).toHaveBeenCalledTimes(0)
expect(ldRadios[2].click).toHaveBeenCalledTimes(2)
expect(ldRadios[3].click).toHaveBeenCalledTimes(0)
expect(ldRadios[4].click).toHaveBeenCalledTimes(1)

expect(radios[0].focus).toHaveBeenCalledTimes(1)
expect(radios[1].focus).toHaveBeenCalledTimes(0)
expect(radios[2].focus).toHaveBeenCalledTimes(2)
Expand Down

0 comments on commit a071221

Please sign in to comment.