Skip to content

Commit f2403c7

Browse files
committed
lint fix
1 parent a1cd4d3 commit f2403c7

10 files changed

Lines changed: 365 additions & 365 deletions

File tree

src/v2/components/combobox/Combobox.test.ts

Lines changed: 189 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -2,198 +2,198 @@ import { beforeEach, describe, expect, it, jest } from '@jest/globals'
22
import { Combobox } from './Combobox'
33
import './index'
44

5-
function getPortalRoot() {
6-
const portalHost = document.querySelector('[data-solid-ui-combobox-portal]') as HTMLDivElement | null
7-
return portalHost?.shadowRoot ?? null
5+
function getPortalRoot () {
6+
const portalHost = document.querySelector('[data-solid-ui-combobox-portal]') as HTMLDivElement | null
7+
return portalHost?.shadowRoot ?? null
88
}
99

10-
async function flushUpdates() {
11-
await Promise.resolve()
12-
await Promise.resolve()
10+
async function flushUpdates () {
11+
await Promise.resolve()
12+
await Promise.resolve()
1313
}
1414

1515
describe('SolidUICombobox', () => {
16-
beforeEach(() => {
17-
document.body.innerHTML = ''
18-
})
19-
20-
it('is defined as a custom element', () => {
21-
expect(customElements.get('solid-ui-combobox')).toBe(Combobox)
22-
})
23-
24-
it('renders the input with label and placeholder', async () => {
25-
const combobox = new Combobox()
26-
combobox.label = 'Person'
27-
combobox.placeholder = 'Search people'
28-
29-
document.body.appendChild(combobox)
30-
await combobox.updateComplete
31-
32-
const label = combobox.shadowRoot?.querySelector('label.text-label') as HTMLLabelElement
33-
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
34-
const toggle = combobox.shadowRoot?.querySelector('button.dropdown-toggle') as HTMLButtonElement
35-
36-
expect(label).not.toBeNull()
37-
expect(label.textContent).toContain('Person')
38-
expect(input).not.toBeNull()
39-
expect(input.placeholder).toBe('Search people')
40-
expect(input.getAttribute('role')).toBe('combobox')
41-
expect(input.getAttribute('aria-expanded')).toBe('false')
42-
expect(toggle).not.toBeNull()
43-
})
44-
45-
it('loads suggestions from suggestionProvider and emits input events', async () => {
46-
const combobox = new Combobox()
47-
const inputEvents = jest.fn()
48-
const suggestionProvider = jest.fn(async (query: string) => [
49-
{ label: `Alice ${query}`, value: 'alice' },
50-
{ label: `Bob ${query}`, value: 'bob' }
51-
])
52-
53-
combobox.suggestionProvider = suggestionProvider
54-
combobox.addEventListener('input', (event: Event) => {
55-
inputEvents((event as CustomEvent).detail)
56-
})
57-
58-
document.body.appendChild(combobox)
59-
await combobox.updateComplete
60-
61-
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
62-
input.value = 'al'
63-
input.dispatchEvent(new Event('input', { bubbles: true, composed: true }))
64-
65-
await flushUpdates()
66-
await combobox.updateComplete
67-
68-
const portalRoot = getPortalRoot()
69-
const options = Array.from(portalRoot?.querySelectorAll('[role="option"]') as NodeListOf<HTMLElement>)
70-
71-
expect(suggestionProvider).toHaveBeenCalledWith('al')
72-
expect(inputEvents).toHaveBeenCalledWith({ value: 'al' })
73-
expect(combobox.inputValue).toBe('al')
74-
expect(options).toHaveLength(2)
75-
expect(options[0].textContent).toContain('Alice al')
76-
})
77-
78-
it('renders the selected option first in the popup', async () => {
79-
const combobox = new Combobox()
80-
combobox.options = [
81-
{ label: 'English', value: 'en' },
82-
{ label: 'French', value: 'fr' },
83-
{ label: 'Spanish', value: 'es' }
84-
]
85-
combobox.value = 'fr'
86-
87-
document.body.appendChild(combobox)
88-
await combobox.updateComplete
89-
90-
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
91-
input.dispatchEvent(new Event('focus'))
92-
await combobox.updateComplete
93-
94-
const portalRoot = getPortalRoot()
95-
const options = Array.from(portalRoot?.querySelectorAll('[role="option"]') as NodeListOf<HTMLElement>)
96-
97-
expect(options).toHaveLength(3)
98-
expect(options[0].textContent).toContain('French')
99-
expect(options[0].getAttribute('aria-selected')).toBe('true')
100-
})
101-
102-
it('updates value and emits change when an option is clicked', async () => {
103-
const combobox = new Combobox()
104-
const changed = jest.fn()
105-
106-
combobox.options = [
107-
{ label: 'Alice', value: 'alice', publicId: 'https://example.com/alice' },
108-
{ label: 'Bob', value: 'bob' }
109-
]
110-
111-
combobox.addEventListener('change', (event: Event) => {
112-
changed((event as CustomEvent).detail)
113-
})
114-
115-
document.body.appendChild(combobox)
116-
await combobox.updateComplete
117-
118-
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
119-
input.dispatchEvent(new Event('focus'))
120-
await combobox.updateComplete
121-
122-
const portalRoot = getPortalRoot()
123-
const options = portalRoot?.querySelectorAll('[role="option"]') as NodeListOf<HTMLElement>
124-
options[1].click()
125-
await combobox.updateComplete
126-
127-
expect(combobox.value).toBe('bob')
128-
expect(combobox.inputValue).toBe('Bob')
129-
expect(input.getAttribute('aria-expanded')).toBe('false')
130-
expect(changed).toHaveBeenCalledWith({
131-
value: 'bob',
132-
label: 'Bob',
133-
option: { label: 'Bob', value: 'bob' }
134-
})
135-
})
136-
137-
it('supports keyboard selection from the input', async () => {
138-
const combobox = new Combobox()
139-
const changed = jest.fn()
140-
141-
combobox.options = [
142-
{ label: 'Alice', value: 'alice' },
143-
{ label: 'Bob', value: 'bob' },
144-
{ label: 'Carol', value: 'carol' }
145-
]
146-
147-
combobox.addEventListener('change', (event: Event) => {
148-
changed((event as CustomEvent).detail)
149-
})
150-
151-
document.body.appendChild(combobox)
152-
await combobox.updateComplete
153-
154-
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
155-
156-
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
157-
await combobox.updateComplete
158-
159-
expect(input.getAttribute('aria-expanded')).toBe('true')
160-
expect(input.getAttribute('aria-activedescendant')).toBeTruthy()
161-
162-
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
163-
await combobox.updateComplete
164-
165-
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }))
166-
await combobox.updateComplete
167-
168-
expect(combobox.value).toBe('bob')
169-
expect(combobox.inputValue).toBe('Bob')
170-
expect(changed).toHaveBeenCalledWith({
171-
value: 'bob',
172-
label: 'Bob',
173-
option: { label: 'Bob', value: 'bob' }
174-
})
175-
})
176-
177-
it('closes the popup when clicking outside the component', async () => {
178-
const combobox = new Combobox()
179-
combobox.options = [
180-
{ label: 'Alice', value: 'alice' },
181-
{ label: 'Bob', value: 'bob' }
182-
]
183-
184-
document.body.appendChild(combobox)
185-
await combobox.updateComplete
186-
187-
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
188-
input.dispatchEvent(new Event('focus'))
189-
await combobox.updateComplete
190-
191-
expect(input.getAttribute('aria-expanded')).toBe('true')
192-
expect(getPortalRoot()).not.toBeNull()
193-
194-
document.body.dispatchEvent(new Event('pointerdown', { bubbles: true, composed: true }))
195-
await combobox.updateComplete
196-
197-
expect(input.getAttribute('aria-expanded')).toBe('false')
198-
})
16+
beforeEach(() => {
17+
document.body.innerHTML = ''
18+
})
19+
20+
it('is defined as a custom element', () => {
21+
expect(customElements.get('solid-ui-combobox')).toBe(Combobox)
22+
})
23+
24+
it('renders the input with label and placeholder', async () => {
25+
const combobox = new Combobox()
26+
combobox.label = 'Person'
27+
combobox.placeholder = 'Search people'
28+
29+
document.body.appendChild(combobox)
30+
await combobox.updateComplete
31+
32+
const label = combobox.shadowRoot?.querySelector('label.text-label') as HTMLLabelElement
33+
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
34+
const toggle = combobox.shadowRoot?.querySelector('button.dropdown-toggle') as HTMLButtonElement
35+
36+
expect(label).not.toBeNull()
37+
expect(label.textContent).toContain('Person')
38+
expect(input).not.toBeNull()
39+
expect(input.placeholder).toBe('Search people')
40+
expect(input.getAttribute('role')).toBe('combobox')
41+
expect(input.getAttribute('aria-expanded')).toBe('false')
42+
expect(toggle).not.toBeNull()
43+
})
44+
45+
it('loads suggestions from suggestionProvider and emits input events', async () => {
46+
const combobox = new Combobox()
47+
const inputEvents = jest.fn()
48+
const suggestionProvider = jest.fn(async (query: string) => [
49+
{ label: `Alice ${query}`, value: 'alice' },
50+
{ label: `Bob ${query}`, value: 'bob' }
51+
])
52+
53+
combobox.suggestionProvider = suggestionProvider
54+
combobox.addEventListener('input', (event: Event) => {
55+
inputEvents((event as CustomEvent).detail)
56+
})
57+
58+
document.body.appendChild(combobox)
59+
await combobox.updateComplete
60+
61+
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
62+
input.value = 'al'
63+
input.dispatchEvent(new Event('input', { bubbles: true, composed: true }))
64+
65+
await flushUpdates()
66+
await combobox.updateComplete
67+
68+
const portalRoot = getPortalRoot()
69+
const options = Array.from(portalRoot?.querySelectorAll('[role="option"]') as NodeListOf<HTMLElement>)
70+
71+
expect(suggestionProvider).toHaveBeenCalledWith('al')
72+
expect(inputEvents).toHaveBeenCalledWith({ value: 'al' })
73+
expect(combobox.inputValue).toBe('al')
74+
expect(options).toHaveLength(2)
75+
expect(options[0].textContent).toContain('Alice al')
76+
})
77+
78+
it('renders the selected option first in the popup', async () => {
79+
const combobox = new Combobox()
80+
combobox.options = [
81+
{ label: 'English', value: 'en' },
82+
{ label: 'French', value: 'fr' },
83+
{ label: 'Spanish', value: 'es' }
84+
]
85+
combobox.value = 'fr'
86+
87+
document.body.appendChild(combobox)
88+
await combobox.updateComplete
89+
90+
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
91+
input.dispatchEvent(new Event('focus'))
92+
await combobox.updateComplete
93+
94+
const portalRoot = getPortalRoot()
95+
const options = Array.from(portalRoot?.querySelectorAll('[role="option"]') as NodeListOf<HTMLElement>)
96+
97+
expect(options).toHaveLength(3)
98+
expect(options[0].textContent).toContain('French')
99+
expect(options[0].getAttribute('aria-selected')).toBe('true')
100+
})
101+
102+
it('updates value and emits change when an option is clicked', async () => {
103+
const combobox = new Combobox()
104+
const changed = jest.fn()
105+
106+
combobox.options = [
107+
{ label: 'Alice', value: 'alice', publicId: 'https://example.com/alice' },
108+
{ label: 'Bob', value: 'bob' }
109+
]
110+
111+
combobox.addEventListener('change', (event: Event) => {
112+
changed((event as CustomEvent).detail)
113+
})
114+
115+
document.body.appendChild(combobox)
116+
await combobox.updateComplete
117+
118+
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
119+
input.dispatchEvent(new Event('focus'))
120+
await combobox.updateComplete
121+
122+
const portalRoot = getPortalRoot()
123+
const options = portalRoot?.querySelectorAll('[role="option"]') as NodeListOf<HTMLElement>
124+
options[1].click()
125+
await combobox.updateComplete
126+
127+
expect(combobox.value).toBe('bob')
128+
expect(combobox.inputValue).toBe('Bob')
129+
expect(input.getAttribute('aria-expanded')).toBe('false')
130+
expect(changed).toHaveBeenCalledWith({
131+
value: 'bob',
132+
label: 'Bob',
133+
option: { label: 'Bob', value: 'bob' }
134+
})
135+
})
136+
137+
it('supports keyboard selection from the input', async () => {
138+
const combobox = new Combobox()
139+
const changed = jest.fn()
140+
141+
combobox.options = [
142+
{ label: 'Alice', value: 'alice' },
143+
{ label: 'Bob', value: 'bob' },
144+
{ label: 'Carol', value: 'carol' }
145+
]
146+
147+
combobox.addEventListener('change', (event: Event) => {
148+
changed((event as CustomEvent).detail)
149+
})
150+
151+
document.body.appendChild(combobox)
152+
await combobox.updateComplete
153+
154+
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
155+
156+
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
157+
await combobox.updateComplete
158+
159+
expect(input.getAttribute('aria-expanded')).toBe('true')
160+
expect(input.getAttribute('aria-activedescendant')).toBeTruthy()
161+
162+
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
163+
await combobox.updateComplete
164+
165+
input.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }))
166+
await combobox.updateComplete
167+
168+
expect(combobox.value).toBe('bob')
169+
expect(combobox.inputValue).toBe('Bob')
170+
expect(changed).toHaveBeenCalledWith({
171+
value: 'bob',
172+
label: 'Bob',
173+
option: { label: 'Bob', value: 'bob' }
174+
})
175+
})
176+
177+
it('closes the popup when clicking outside the component', async () => {
178+
const combobox = new Combobox()
179+
combobox.options = [
180+
{ label: 'Alice', value: 'alice' },
181+
{ label: 'Bob', value: 'bob' }
182+
]
183+
184+
document.body.appendChild(combobox)
185+
await combobox.updateComplete
186+
187+
const input = combobox.shadowRoot?.querySelector('input.text-input') as HTMLInputElement
188+
input.dispatchEvent(new Event('focus'))
189+
await combobox.updateComplete
190+
191+
expect(input.getAttribute('aria-expanded')).toBe('true')
192+
expect(getPortalRoot()).not.toBeNull()
193+
194+
document.body.dispatchEvent(new Event('pointerdown', { bubbles: true, composed: true }))
195+
await combobox.updateComplete
196+
197+
expect(input.getAttribute('aria-expanded')).toBe('false')
198+
})
199199
})

0 commit comments

Comments
 (0)