@oslokommune/punkt-elements 13.4.2 → 13.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/calendar-32W9p9uc.cjs +115 -0
- package/dist/{calendar-DevQhOup.js → calendar-CJSxvwAq.js} +353 -340
- package/dist/{card-Dtw26f7i.js → card-BDz4RWxK.js} +1 -1
- package/dist/{card-BUITGoqX.cjs → card-DBlFf1ry.cjs} +1 -1
- package/dist/{datepicker-CYOn3tRm.js → datepicker-BJKJBoy_.js} +102 -59
- package/dist/datepicker-CmTrG5GE.cjs +164 -0
- package/dist/{heading-D6jXE_Mz.js → heading-Bdh9absf.js} +22 -22
- package/dist/heading-CNycsyMj.cjs +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/pkt-calendar.cjs +1 -1
- package/dist/pkt-calendar.js +1 -1
- package/dist/pkt-card.cjs +1 -1
- package/dist/pkt-card.js +1 -1
- package/dist/pkt-datepicker.cjs +1 -1
- package/dist/pkt-datepicker.js +1 -1
- package/dist/pkt-heading.cjs +1 -1
- package/dist/pkt-heading.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +5 -5
- package/package.json +3 -3
- package/src/components/calendar/calendar.accessibility.test.ts +111 -0
- package/src/components/calendar/calendar.constraints.test.ts +110 -0
- package/src/components/calendar/calendar.core.test.ts +367 -0
- package/src/components/calendar/calendar.interaction.test.ts +139 -0
- package/src/components/calendar/calendar.selection.test.ts +273 -0
- package/src/components/calendar/calendar.ts +74 -42
- package/src/components/card/card.test.ts +19 -5
- package/src/components/consent/consent.test.ts +436 -0
- package/src/components/datepicker/datepicker.accessibility.test.ts +193 -0
- package/src/components/datepicker/datepicker.core.test.ts +322 -0
- package/src/components/datepicker/datepicker.input.test.ts +268 -0
- package/src/components/datepicker/datepicker.selection.test.ts +286 -0
- package/src/components/datepicker/datepicker.ts +121 -19
- package/src/components/datepicker/datepicker.validation.test.ts +176 -0
- package/src/components/heading/heading.test.ts +458 -0
- package/src/components/heading/heading.ts +3 -0
- package/src/components/helptext/helptext.test.ts +474 -0
- package/dist/calendar-BZe2D4Sr.cjs +0 -108
- package/dist/datepicker-B9rhz_AF.cjs +0 -154
- package/dist/heading-BRE_iFtR.cjs +0 -1
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import '@testing-library/jest-dom'
|
|
2
|
+
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
3
|
+
import { fireEvent } from '@testing-library/dom'
|
|
4
|
+
|
|
5
|
+
expect.extend(toHaveNoViolations)
|
|
6
|
+
|
|
7
|
+
import './helptext'
|
|
8
|
+
import { PktHelptext } from './helptext'
|
|
9
|
+
|
|
10
|
+
const waitForCustomElements = async () => {
|
|
11
|
+
await customElements.whenDefined('pkt-helptext')
|
|
12
|
+
await customElements.whenDefined('pkt-icon')
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Helper function to create helptext markup
|
|
16
|
+
const createHelptext = async (helptextProps = '', content = '') => {
|
|
17
|
+
const container = document.createElement('div')
|
|
18
|
+
container.innerHTML = `
|
|
19
|
+
<pkt-helptext ${helptextProps}>
|
|
20
|
+
${content}
|
|
21
|
+
</pkt-helptext>
|
|
22
|
+
`
|
|
23
|
+
document.body.appendChild(container)
|
|
24
|
+
await waitForCustomElements()
|
|
25
|
+
return container
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Cleanup after each test
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
document.body.innerHTML = ''
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('PktHelptext', () => {
|
|
34
|
+
describe('Rendering and basic functionality', () => {
|
|
35
|
+
test('renders without errors', async () => {
|
|
36
|
+
const container = await createHelptext()
|
|
37
|
+
|
|
38
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
39
|
+
expect(helptext).toBeInTheDocument()
|
|
40
|
+
|
|
41
|
+
await helptext.updateComplete
|
|
42
|
+
expect(helptext).toBeTruthy()
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('renders with basic helptext', async () => {
|
|
46
|
+
const helptextContent = 'This is helpful information'
|
|
47
|
+
const container = await createHelptext(`helptext="${helptextContent}"`)
|
|
48
|
+
|
|
49
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
50
|
+
await helptext.updateComplete
|
|
51
|
+
|
|
52
|
+
expect(helptext.helptext).toBe(helptextContent)
|
|
53
|
+
|
|
54
|
+
const helptextContainer = helptext.querySelector('.pkt-inputwrapper__helptext-container')
|
|
55
|
+
expect(helptextContainer).toBeInTheDocument()
|
|
56
|
+
expect(helptextContainer).toHaveClass('pkt-inputwrapper__has-helptext')
|
|
57
|
+
|
|
58
|
+
const helptextDiv = helptext.querySelector('.pkt-inputwrapper__helptext')
|
|
59
|
+
expect(helptextDiv).toBeInTheDocument()
|
|
60
|
+
expect(helptextDiv?.textContent?.trim()).toContain(helptextContent)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('renders with slot content', async () => {
|
|
64
|
+
const slotContent = '<p>Slot helptext content</p>'
|
|
65
|
+
const container = await createHelptext('', slotContent)
|
|
66
|
+
|
|
67
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
68
|
+
await helptext.updateComplete
|
|
69
|
+
|
|
70
|
+
const contentSlot = helptext.querySelector('.pkt-contents')
|
|
71
|
+
expect(contentSlot).toBeInTheDocument()
|
|
72
|
+
expect(helptext.textContent).toContain('Slot helptext content')
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('renders with dropdown helptext', async () => {
|
|
76
|
+
const dropdownContent = 'This is expandable helptext content'
|
|
77
|
+
const container = await createHelptext(`helptextDropdown="${dropdownContent}"`)
|
|
78
|
+
|
|
79
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
80
|
+
await helptext.updateComplete
|
|
81
|
+
|
|
82
|
+
expect(helptext.helptextDropdown).toBe(dropdownContent)
|
|
83
|
+
|
|
84
|
+
const expandableContainer = helptext.querySelector('.pkt-inputwrapper__helptext-expandable')
|
|
85
|
+
expect(expandableContainer).toBeInTheDocument()
|
|
86
|
+
|
|
87
|
+
const button = expandableContainer?.querySelector('button')
|
|
88
|
+
expect(button).toBeInTheDocument()
|
|
89
|
+
expect(button).toHaveClass('pkt-link')
|
|
90
|
+
|
|
91
|
+
const icon = button?.querySelector('pkt-icon')
|
|
92
|
+
expect(icon).toBeInTheDocument()
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
describe('Properties and attributes', () => {
|
|
97
|
+
test('applies default properties correctly', async () => {
|
|
98
|
+
const container = await createHelptext()
|
|
99
|
+
|
|
100
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
101
|
+
await helptext.updateComplete
|
|
102
|
+
|
|
103
|
+
expect(helptext.forId).toBeTruthy() // Should have a generated ID
|
|
104
|
+
expect(helptext.helptext).toBe('')
|
|
105
|
+
expect(helptext.helptextDropdown).toBe('')
|
|
106
|
+
expect(helptext.helptextDropdownButton).toBeTruthy() // Should have default from specs
|
|
107
|
+
expect(helptext.isHelpTextOpen).toBe(false)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
test('sets forId correctly', async () => {
|
|
111
|
+
const customId = 'custom-helptext-id'
|
|
112
|
+
const container = await createHelptext(`forId="${customId}"`)
|
|
113
|
+
|
|
114
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
115
|
+
await helptext.updateComplete
|
|
116
|
+
|
|
117
|
+
expect(helptext.forId).toBe(customId)
|
|
118
|
+
|
|
119
|
+
const helptextDiv = helptext.querySelector('.pkt-inputwrapper__helptext')
|
|
120
|
+
expect(helptextDiv?.id).toBe(`${customId}-helptext`)
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('sets helptext content correctly', async () => {
|
|
124
|
+
const helptextContent = 'Custom helptext message'
|
|
125
|
+
const container = await createHelptext(`helptext="${helptextContent}"`)
|
|
126
|
+
|
|
127
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
128
|
+
await helptext.updateComplete
|
|
129
|
+
|
|
130
|
+
expect(helptext.helptext).toBe(helptextContent)
|
|
131
|
+
expect(helptext.textContent).toContain(helptextContent)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
test('sets dropdown helptext correctly', async () => {
|
|
135
|
+
const dropdownContent = 'Dropdown helptext content'
|
|
136
|
+
const container = await createHelptext(`helptextDropdown="${dropdownContent}"`)
|
|
137
|
+
|
|
138
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
139
|
+
await helptext.updateComplete
|
|
140
|
+
|
|
141
|
+
expect(helptext.helptextDropdown).toBe(dropdownContent)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
test('sets dropdown button text correctly', async () => {
|
|
145
|
+
const buttonText = 'Custom button text'
|
|
146
|
+
const container = await createHelptext(`helptextDropdownButton="${buttonText}"`)
|
|
147
|
+
|
|
148
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
149
|
+
await helptext.updateComplete
|
|
150
|
+
|
|
151
|
+
expect(helptext.helptextDropdownButton).toBe(buttonText)
|
|
152
|
+
})
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
describe('Dropdown functionality', () => {
|
|
156
|
+
test('does not render dropdown when no dropdown content', async () => {
|
|
157
|
+
const container = await createHelptext('helptext="Regular helptext"')
|
|
158
|
+
|
|
159
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
160
|
+
await helptext.updateComplete
|
|
161
|
+
|
|
162
|
+
const expandableContainer = helptext.querySelector('.pkt-inputwrapper__helptext-expandable')
|
|
163
|
+
expect(expandableContainer).not.toBeInTheDocument()
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('renders dropdown when dropdown content is provided', async () => {
|
|
167
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
168
|
+
|
|
169
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
170
|
+
await helptext.updateComplete
|
|
171
|
+
|
|
172
|
+
const expandableContainer = helptext.querySelector('.pkt-inputwrapper__helptext-expandable')
|
|
173
|
+
expect(expandableContainer).toBeInTheDocument()
|
|
174
|
+
|
|
175
|
+
const button = expandableContainer?.querySelector('button')
|
|
176
|
+
expect(button).toBeInTheDocument()
|
|
177
|
+
|
|
178
|
+
const expandableContent = expandableContainer?.querySelector(
|
|
179
|
+
'.pkt-inputwrapper__helptext-expandable-closed',
|
|
180
|
+
)
|
|
181
|
+
expect(expandableContent).toBeInTheDocument()
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
test('toggles dropdown state on button click', async () => {
|
|
185
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
186
|
+
|
|
187
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
188
|
+
await helptext.updateComplete
|
|
189
|
+
|
|
190
|
+
expect(helptext.isHelpTextOpen).toBe(false)
|
|
191
|
+
|
|
192
|
+
const button = helptext.querySelector('.pkt-inputwrapper__helptext-expandable button')
|
|
193
|
+
expect(button).toBeInTheDocument()
|
|
194
|
+
|
|
195
|
+
// Click to open
|
|
196
|
+
fireEvent.click(button!)
|
|
197
|
+
await helptext.updateComplete
|
|
198
|
+
|
|
199
|
+
expect(helptext.isHelpTextOpen).toBe(true)
|
|
200
|
+
|
|
201
|
+
const openContent = helptext.querySelector('.pkt-inputwrapper__helptext-expandable-open')
|
|
202
|
+
expect(openContent).toBeInTheDocument()
|
|
203
|
+
|
|
204
|
+
const closedContent = helptext.querySelector('.pkt-inputwrapper__helptext-expandable-closed')
|
|
205
|
+
expect(closedContent).not.toBeInTheDocument()
|
|
206
|
+
|
|
207
|
+
// Click to close
|
|
208
|
+
fireEvent.click(button!)
|
|
209
|
+
await helptext.updateComplete
|
|
210
|
+
|
|
211
|
+
expect(helptext.isHelpTextOpen).toBe(false)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
test('changes icon when dropdown is toggled', async () => {
|
|
215
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
216
|
+
|
|
217
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
218
|
+
await helptext.updateComplete
|
|
219
|
+
|
|
220
|
+
const icon = helptext.querySelector('pkt-icon')
|
|
221
|
+
expect(icon?.getAttribute('name')).toBe('chevron-thin-down')
|
|
222
|
+
|
|
223
|
+
const button = helptext.querySelector('.pkt-inputwrapper__helptext-expandable button')
|
|
224
|
+
fireEvent.click(button!)
|
|
225
|
+
await helptext.updateComplete
|
|
226
|
+
|
|
227
|
+
expect(icon?.getAttribute('name')).toBe('chevron-thin-up')
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
test('dispatches toggleHelpText event on dropdown toggle', async () => {
|
|
231
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
232
|
+
|
|
233
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
234
|
+
await helptext.updateComplete
|
|
235
|
+
|
|
236
|
+
let eventFired = false
|
|
237
|
+
let eventDetail: any = null
|
|
238
|
+
|
|
239
|
+
helptext.addEventListener('toggleHelpText', (e: Event) => {
|
|
240
|
+
eventFired = true
|
|
241
|
+
eventDetail = (e as CustomEvent).detail
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
const button = helptext.querySelector('.pkt-inputwrapper__helptext-expandable button')
|
|
245
|
+
fireEvent.click(button!)
|
|
246
|
+
|
|
247
|
+
expect(eventFired).toBe(true)
|
|
248
|
+
expect(eventDetail).toEqual({ isOpen: true })
|
|
249
|
+
})
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
describe('CSS classes and styling', () => {
|
|
253
|
+
test('applies correct classes when no content', async () => {
|
|
254
|
+
const container = await createHelptext()
|
|
255
|
+
|
|
256
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
257
|
+
await helptext.updateComplete
|
|
258
|
+
|
|
259
|
+
const helptextContainer = helptext.querySelector('.pkt-inputwrapper__helptext-container')
|
|
260
|
+
expect(helptextContainer).toBeInTheDocument()
|
|
261
|
+
expect(helptextContainer).not.toHaveClass('pkt-inputwrapper__has-helptext')
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
test('applies correct classes when helptext is provided', async () => {
|
|
265
|
+
const container = await createHelptext('helptext="Some helptext"')
|
|
266
|
+
|
|
267
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
268
|
+
await helptext.updateComplete
|
|
269
|
+
|
|
270
|
+
const helptextContainer = helptext.querySelector('.pkt-inputwrapper__helptext-container')
|
|
271
|
+
expect(helptextContainer).toHaveClass('pkt-inputwrapper__has-helptext')
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
test('applies correct classes when dropdown is provided', async () => {
|
|
275
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
276
|
+
|
|
277
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
278
|
+
await helptext.updateComplete
|
|
279
|
+
|
|
280
|
+
const helptextContainer = helptext.querySelector('.pkt-inputwrapper__helptext-container')
|
|
281
|
+
expect(helptextContainer).toHaveClass('pkt-inputwrapper__has-helptext')
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
test('applies correct classes for closed dropdown', async () => {
|
|
285
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
286
|
+
|
|
287
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
288
|
+
await helptext.updateComplete
|
|
289
|
+
|
|
290
|
+
const dropdownContent = helptext.querySelector(
|
|
291
|
+
'.pkt-inputwrapper__helptext-expandable .pkt-inputwrapper__helptext',
|
|
292
|
+
)
|
|
293
|
+
expect(dropdownContent).toHaveClass('pkt-inputwrapper__helptext-expandable-closed')
|
|
294
|
+
expect(dropdownContent).not.toHaveClass('pkt-inputwrapper__helptext-expandable-open')
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
test('applies correct classes for open dropdown', async () => {
|
|
298
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
299
|
+
|
|
300
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
301
|
+
await helptext.updateComplete
|
|
302
|
+
|
|
303
|
+
const button = helptext.querySelector('.pkt-inputwrapper__helptext-expandable button')
|
|
304
|
+
fireEvent.click(button!)
|
|
305
|
+
await helptext.updateComplete
|
|
306
|
+
|
|
307
|
+
const dropdownContent = helptext.querySelector(
|
|
308
|
+
'.pkt-inputwrapper__helptext-expandable .pkt-inputwrapper__helptext',
|
|
309
|
+
)
|
|
310
|
+
expect(dropdownContent).toHaveClass('pkt-inputwrapper__helptext-expandable-open')
|
|
311
|
+
expect(dropdownContent).not.toHaveClass('pkt-inputwrapper__helptext-expandable-closed')
|
|
312
|
+
})
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
describe('Content rendering', () => {
|
|
316
|
+
test('renders HTML content safely in helptext', async () => {
|
|
317
|
+
const htmlContent = '<strong>Important</strong> information'
|
|
318
|
+
const container = await createHelptext(`helptext="${htmlContent}"`)
|
|
319
|
+
|
|
320
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
321
|
+
await helptext.updateComplete
|
|
322
|
+
|
|
323
|
+
const strong = helptext.querySelector('strong')
|
|
324
|
+
expect(strong).toBeInTheDocument()
|
|
325
|
+
expect(strong?.textContent).toBe('Important')
|
|
326
|
+
})
|
|
327
|
+
|
|
328
|
+
test('renders HTML content safely in dropdown', async () => {
|
|
329
|
+
const htmlContent = '<em>Emphasized</em> dropdown content'
|
|
330
|
+
const container = await createHelptext(`helptextDropdown="${htmlContent}"`)
|
|
331
|
+
|
|
332
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
333
|
+
await helptext.updateComplete
|
|
334
|
+
|
|
335
|
+
const button = helptext.querySelector('.pkt-inputwrapper__helptext-expandable button')
|
|
336
|
+
fireEvent.click(button!)
|
|
337
|
+
await helptext.updateComplete
|
|
338
|
+
|
|
339
|
+
const em = helptext.querySelector('em')
|
|
340
|
+
expect(em).toBeInTheDocument()
|
|
341
|
+
expect(em?.textContent).toBe('Emphasized')
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
test('renders both regular and dropdown content simultaneously', async () => {
|
|
345
|
+
const regularContent = 'Regular helptext'
|
|
346
|
+
const dropdownContent = 'Dropdown helptext'
|
|
347
|
+
const container = await createHelptext(
|
|
348
|
+
`helptext="${regularContent}" helptextDropdown="${dropdownContent}"`,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
352
|
+
await helptext.updateComplete
|
|
353
|
+
|
|
354
|
+
expect(helptext.textContent).toContain(regularContent)
|
|
355
|
+
|
|
356
|
+
const button = helptext.querySelector('.pkt-inputwrapper__helptext-expandable button')
|
|
357
|
+
fireEvent.click(button!)
|
|
358
|
+
await helptext.updateComplete
|
|
359
|
+
|
|
360
|
+
expect(helptext.textContent).toContain(dropdownContent)
|
|
361
|
+
})
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
describe('Slot management', () => {
|
|
365
|
+
test('updates slot state when slots are filled', async () => {
|
|
366
|
+
const container = await createHelptext('', '<span>Slotted content</span>')
|
|
367
|
+
|
|
368
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
369
|
+
await helptext.updateComplete
|
|
370
|
+
|
|
371
|
+
// Simulate slot controller updating filled slots
|
|
372
|
+
const filledSlots = new Set(['default'])
|
|
373
|
+
helptext.updateSlots(filledSlots)
|
|
374
|
+
await helptext.updateComplete
|
|
375
|
+
|
|
376
|
+
expect(helptext.filledSlots.size).toBe(1)
|
|
377
|
+
expect(helptext.filledSlots.has('default')).toBe(true)
|
|
378
|
+
})
|
|
379
|
+
|
|
380
|
+
test('applies has-helptext class when slots are filled', async () => {
|
|
381
|
+
const container = await createHelptext('', '<span>Slotted content</span>')
|
|
382
|
+
|
|
383
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
384
|
+
|
|
385
|
+
// Simulate slot controller updating filled slots
|
|
386
|
+
const filledSlots = new Set(['default'])
|
|
387
|
+
helptext.updateSlots(filledSlots)
|
|
388
|
+
await helptext.updateComplete
|
|
389
|
+
|
|
390
|
+
const helptextContainer = helptext.querySelector('.pkt-inputwrapper__helptext-container')
|
|
391
|
+
expect(helptextContainer).toHaveClass('pkt-inputwrapper__has-helptext')
|
|
392
|
+
})
|
|
393
|
+
})
|
|
394
|
+
|
|
395
|
+
describe('Accessibility', () => {
|
|
396
|
+
test('basic helptext is accessible', async () => {
|
|
397
|
+
const container = await createHelptext('helptext="Accessible helptext" forId="test-input"')
|
|
398
|
+
|
|
399
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
400
|
+
await helptext.updateComplete
|
|
401
|
+
|
|
402
|
+
const results = await axe(container)
|
|
403
|
+
expect(results).toHaveNoViolations()
|
|
404
|
+
|
|
405
|
+
const helptextDiv = helptext.querySelector('.pkt-inputwrapper__helptext')
|
|
406
|
+
expect(helptextDiv?.id).toBe('test-input-helptext')
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
test('dropdown helptext is accessible', async () => {
|
|
410
|
+
const container = await createHelptext(
|
|
411
|
+
'helptextDropdown="Dropdown content" helptextDropdownButton="Show more info"',
|
|
412
|
+
)
|
|
413
|
+
|
|
414
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
415
|
+
await helptext.updateComplete
|
|
416
|
+
|
|
417
|
+
const results = await axe(container)
|
|
418
|
+
expect(results).toHaveNoViolations()
|
|
419
|
+
|
|
420
|
+
const button = helptext.querySelector('button')
|
|
421
|
+
expect(button).toBeInTheDocument()
|
|
422
|
+
expect(button?.type).toBe('button')
|
|
423
|
+
expect(button?.textContent?.trim()).toContain('Show more info')
|
|
424
|
+
})
|
|
425
|
+
|
|
426
|
+
test('dropdown button has proper aria state', async () => {
|
|
427
|
+
const container = await createHelptext('helptextDropdown="Dropdown content"')
|
|
428
|
+
|
|
429
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
430
|
+
await helptext.updateComplete
|
|
431
|
+
|
|
432
|
+
const button = helptext.querySelector('button')
|
|
433
|
+
expect(button).toBeInTheDocument()
|
|
434
|
+
|
|
435
|
+
// Button should be focusable and have proper role
|
|
436
|
+
expect(button?.tagName).toBe('BUTTON')
|
|
437
|
+
expect(button?.type).toBe('button')
|
|
438
|
+
})
|
|
439
|
+
})
|
|
440
|
+
|
|
441
|
+
describe('Integration', () => {
|
|
442
|
+
test('works with input wrapper context', async () => {
|
|
443
|
+
const container = await createHelptext('forId="input-123" helptext="Field help information"')
|
|
444
|
+
|
|
445
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
446
|
+
await helptext.updateComplete
|
|
447
|
+
|
|
448
|
+
// The ID should match what an input would use for aria-describedby
|
|
449
|
+
const helptextDiv = helptext.querySelector('.pkt-inputwrapper__helptext')
|
|
450
|
+
expect(helptextDiv?.id).toBe('input-123-helptext')
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
test('manages multiple content sources correctly', async () => {
|
|
454
|
+
const container = await createHelptext(
|
|
455
|
+
'helptext="Property text" helptextDropdown="Dropdown text"',
|
|
456
|
+
'<span>Slot text</span>',
|
|
457
|
+
)
|
|
458
|
+
|
|
459
|
+
const helptext = container.querySelector('pkt-helptext') as PktHelptext
|
|
460
|
+
await helptext.updateComplete
|
|
461
|
+
|
|
462
|
+
// All content should be present but in correct locations
|
|
463
|
+
expect(helptext.textContent).toContain('Property text')
|
|
464
|
+
expect(helptext.textContent).toContain('Slot text')
|
|
465
|
+
|
|
466
|
+
// Dropdown content should be present but hidden initially
|
|
467
|
+
const dropdownContent = helptext.querySelector(
|
|
468
|
+
'.pkt-inputwrapper__helptext-expandable-closed',
|
|
469
|
+
)
|
|
470
|
+
expect(dropdownContent).toBeInTheDocument()
|
|
471
|
+
expect(dropdownContent?.textContent?.trim()).toContain('Dropdown text')
|
|
472
|
+
})
|
|
473
|
+
})
|
|
474
|
+
})
|