@oslokommune/punkt-react 15.4.6 → 16.0.0
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 +74 -0
- package/dist/index.d.ts +38 -15
- package/dist/punkt-react.es.js +12025 -10664
- package/dist/punkt-react.umd.js +562 -549
- package/package.json +5 -5
- package/src/components/accordion/Accordion.test.tsx +3 -2
- package/src/components/alert/Alert.test.tsx +2 -1
- package/src/components/backlink/BackLink.test.tsx +2 -1
- package/src/components/button/Button.test.tsx +4 -3
- package/src/components/calendar/Calendar.interaction.test.tsx +2 -1
- package/src/components/checkbox/Checkbox.test.tsx +2 -1
- package/src/components/combobox/Combobox.accessibility.test.tsx +277 -0
- package/src/components/combobox/Combobox.core.test.tsx +469 -0
- package/src/components/combobox/Combobox.interaction.test.tsx +607 -0
- package/src/components/combobox/Combobox.selection.test.tsx +548 -0
- package/src/components/combobox/Combobox.tsx +59 -54
- package/src/components/combobox/ComboboxInput.tsx +140 -0
- package/src/components/combobox/ComboboxTags.tsx +110 -0
- package/src/components/combobox/Listbox.tsx +172 -0
- package/src/components/combobox/types.ts +145 -0
- package/src/components/combobox/useComboboxState.ts +1141 -0
- package/src/components/datepicker/Datepicker.accessibility.test.tsx +5 -4
- package/src/components/datepicker/Datepicker.input.test.tsx +3 -2
- package/src/components/datepicker/Datepicker.selection.test.tsx +8 -8
- package/src/components/datepicker/Datepicker.validation.test.tsx +2 -1
- package/src/components/radio/RadioButton.test.tsx +3 -2
- package/src/components/searchinput/SearchInput.test.tsx +6 -5
- package/src/components/tabs/Tabs.test.tsx +13 -12
- package/src/components/tag/Tag.test.tsx +2 -1
|
@@ -2,6 +2,7 @@ import '@testing-library/jest-dom'
|
|
|
2
2
|
|
|
3
3
|
import { fireEvent, render, screen } from '@testing-library/react'
|
|
4
4
|
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
5
|
+
import { vi } from 'vitest'
|
|
5
6
|
|
|
6
7
|
import { IPktDatepicker, PktDatepicker } from './Datepicker'
|
|
7
8
|
|
|
@@ -23,7 +24,7 @@ const createDatepickerTest = (props: Partial<IPktDatepicker> = {}) => {
|
|
|
23
24
|
describe('PktDatepicker', () => {
|
|
24
25
|
describe('Event handling', () => {
|
|
25
26
|
test('dispatches onChange event when value changes', () => {
|
|
26
|
-
const handleChange =
|
|
27
|
+
const handleChange = vi.fn()
|
|
27
28
|
const { container } = createDatepickerTest({
|
|
28
29
|
onChange: handleChange,
|
|
29
30
|
})
|
|
@@ -35,7 +36,7 @@ describe('PktDatepicker', () => {
|
|
|
35
36
|
})
|
|
36
37
|
|
|
37
38
|
test('dispatches onValueChange event when value changes', () => {
|
|
38
|
-
const handleValueChange =
|
|
39
|
+
const handleValueChange = vi.fn()
|
|
39
40
|
const { container } = createDatepickerTest({
|
|
40
41
|
onValueChange: handleValueChange,
|
|
41
42
|
})
|
|
@@ -67,8 +68,8 @@ describe('PktDatepicker', () => {
|
|
|
67
68
|
})
|
|
68
69
|
|
|
69
70
|
test('dispatches both onChange and onValueChange', () => {
|
|
70
|
-
const handleChange =
|
|
71
|
-
const handleValueChange =
|
|
71
|
+
const handleChange = vi.fn()
|
|
72
|
+
const handleValueChange = vi.fn()
|
|
72
73
|
const { container } = createDatepickerTest({
|
|
73
74
|
onChange: handleChange,
|
|
74
75
|
onValueChange: handleValueChange,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '@testing-library/jest-dom'
|
|
2
2
|
|
|
3
3
|
import { fireEvent, render, screen } from '@testing-library/react'
|
|
4
|
+
import { vi } from 'vitest'
|
|
4
5
|
|
|
5
6
|
import { IPktDatepicker, PktDatepicker } from './Datepicker'
|
|
6
7
|
|
|
@@ -20,7 +21,7 @@ const createDatepickerTest = (props: Partial<IPktDatepicker> = {}) => {
|
|
|
20
21
|
describe('PktDatepicker', () => {
|
|
21
22
|
describe('Input field behavior', () => {
|
|
22
23
|
test('allows manual date entry via change event', () => {
|
|
23
|
-
const handleValueChange =
|
|
24
|
+
const handleValueChange = vi.fn()
|
|
24
25
|
const { container } = createDatepickerTest({
|
|
25
26
|
onValueChange: handleValueChange,
|
|
26
27
|
})
|
|
@@ -62,7 +63,7 @@ describe('PktDatepicker', () => {
|
|
|
62
63
|
})
|
|
63
64
|
|
|
64
65
|
test('clears value when empty string entered', () => {
|
|
65
|
-
const handleValueChange =
|
|
66
|
+
const handleValueChange = vi.fn()
|
|
66
67
|
const { container } = createDatepickerTest({
|
|
67
68
|
value: '2024-06-15',
|
|
68
69
|
onValueChange: handleValueChange,
|
|
@@ -32,7 +32,7 @@ describe('PktDatepicker', () => {
|
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
test('removes dates when clicking tag close button', async () => {
|
|
35
|
-
const handleValueChange =
|
|
35
|
+
const handleValueChange = vi.fn()
|
|
36
36
|
const { container } = createDatepickerTest({
|
|
37
37
|
multiple: true,
|
|
38
38
|
value: ['2024-06-15', '2024-06-20'],
|
|
@@ -107,7 +107,7 @@ describe('PktDatepicker', () => {
|
|
|
107
107
|
})
|
|
108
108
|
|
|
109
109
|
test('dispatches onValueChange with remaining dates when tag removed', async () => {
|
|
110
|
-
const handleValueChange =
|
|
110
|
+
const handleValueChange = vi.fn()
|
|
111
111
|
const { container } = createDatepickerTest({
|
|
112
112
|
multiple: true,
|
|
113
113
|
value: ['2024-06-15', '2024-06-20', '2024-06-25'],
|
|
@@ -199,7 +199,7 @@ describe('PktDatepicker', () => {
|
|
|
199
199
|
})
|
|
200
200
|
|
|
201
201
|
test('dispatches onValueChange for partial range (only from)', () => {
|
|
202
|
-
const handleValueChange =
|
|
202
|
+
const handleValueChange = vi.fn()
|
|
203
203
|
const { container } = createDatepickerTest({
|
|
204
204
|
range: true,
|
|
205
205
|
onValueChange: handleValueChange,
|
|
@@ -212,7 +212,7 @@ describe('PktDatepicker', () => {
|
|
|
212
212
|
})
|
|
213
213
|
|
|
214
214
|
test('dispatches onValueChange when both range dates are present', () => {
|
|
215
|
-
const handleValueChange =
|
|
215
|
+
const handleValueChange = vi.fn()
|
|
216
216
|
const { container } = createDatepickerTest({
|
|
217
217
|
range: true,
|
|
218
218
|
value: ['2024-06-15'],
|
|
@@ -226,7 +226,7 @@ describe('PktDatepicker', () => {
|
|
|
226
226
|
})
|
|
227
227
|
|
|
228
228
|
test('validates range order on blur (rejects end before start)', () => {
|
|
229
|
-
const handleValueChange =
|
|
229
|
+
const handleValueChange = vi.fn()
|
|
230
230
|
const { container } = createDatepickerTest({
|
|
231
231
|
range: true,
|
|
232
232
|
value: ['2024-06-25', '2024-06-15'],
|
|
@@ -300,7 +300,7 @@ describe('PktDatepicker', () => {
|
|
|
300
300
|
|
|
301
301
|
describe('Single date selection', () => {
|
|
302
302
|
test('dispatches onChange when input value changes', () => {
|
|
303
|
-
const handleChange =
|
|
303
|
+
const handleChange = vi.fn()
|
|
304
304
|
const { container } = createDatepickerTest({
|
|
305
305
|
onChange: handleChange,
|
|
306
306
|
})
|
|
@@ -312,7 +312,7 @@ describe('PktDatepicker', () => {
|
|
|
312
312
|
})
|
|
313
313
|
|
|
314
314
|
test('dispatches onValueChange with array when input value changes', () => {
|
|
315
|
-
const handleValueChange =
|
|
315
|
+
const handleValueChange = vi.fn()
|
|
316
316
|
const { container } = createDatepickerTest({
|
|
317
317
|
onValueChange: handleValueChange,
|
|
318
318
|
})
|
|
@@ -324,7 +324,7 @@ describe('PktDatepicker', () => {
|
|
|
324
324
|
})
|
|
325
325
|
|
|
326
326
|
test('dispatches onValueChange with empty array when cleared', () => {
|
|
327
|
-
const handleValueChange =
|
|
327
|
+
const handleValueChange = vi.fn()
|
|
328
328
|
const { container } = createDatepickerTest({
|
|
329
329
|
value: '2024-06-15',
|
|
330
330
|
onValueChange: handleValueChange,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '@testing-library/jest-dom'
|
|
2
2
|
|
|
3
3
|
import { fireEvent, render } from '@testing-library/react'
|
|
4
|
+
import { vi } from 'vitest'
|
|
4
5
|
|
|
5
6
|
import { IPktDatepicker, PktDatepicker } from './Datepicker'
|
|
6
7
|
|
|
@@ -301,7 +302,7 @@ describe('PktDatepicker', () => {
|
|
|
301
302
|
})
|
|
302
303
|
|
|
303
304
|
test('submits form on Enter key press', () => {
|
|
304
|
-
const submitHandler =
|
|
305
|
+
const submitHandler = vi.fn((e: Event) => e.preventDefault())
|
|
305
306
|
const { container } = render(
|
|
306
307
|
<form onSubmit={submitHandler as unknown as React.FormEventHandler}>
|
|
307
308
|
<PktDatepicker id={datePickerId} label={label} value="2024-06-15" />
|
|
@@ -2,6 +2,7 @@ import '@testing-library/jest-dom'
|
|
|
2
2
|
|
|
3
3
|
import { fireEvent, render } from '@testing-library/react'
|
|
4
4
|
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
5
|
+
import { vi } from 'vitest'
|
|
5
6
|
|
|
6
7
|
import { PktInputWrapper } from '../inputwrapper/InputWrapper'
|
|
7
8
|
import { PktRadioButton } from './RadioButton'
|
|
@@ -21,7 +22,7 @@ describe('PktRadiobutton', () => {
|
|
|
21
22
|
})
|
|
22
23
|
|
|
23
24
|
it('allows selecting one option from the group', async () => {
|
|
24
|
-
const handleChange =
|
|
25
|
+
const handleChange = vi.fn()
|
|
25
26
|
const { container } = render(
|
|
26
27
|
<PktInputWrapper forId="radioGroup" label="Etikett" hasFieldset>
|
|
27
28
|
<PktRadioButton
|
|
@@ -42,7 +43,7 @@ describe('PktRadiobutton', () => {
|
|
|
42
43
|
expect(option1).toBeInTheDocument()
|
|
43
44
|
expect(option2).toBeInTheDocument()
|
|
44
45
|
|
|
45
|
-
const changeHandler =
|
|
46
|
+
const changeHandler = vi.fn()
|
|
46
47
|
option2?.addEventListener('change', changeHandler)
|
|
47
48
|
|
|
48
49
|
// Manually dispatch a change event
|
|
@@ -3,6 +3,7 @@ import '@testing-library/jest-dom'
|
|
|
3
3
|
import { fireEvent, render, screen } from '@testing-library/react'
|
|
4
4
|
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
5
5
|
import { ChangeEvent, useState } from 'react'
|
|
6
|
+
import { vi } from 'vitest'
|
|
6
7
|
|
|
7
8
|
import { PktSearchInput } from './SearchInput'
|
|
8
9
|
|
|
@@ -49,7 +50,7 @@ describe('PktSearchInput', () => {
|
|
|
49
50
|
})
|
|
50
51
|
|
|
51
52
|
it('calls onSearch prop with input value on button click', async () => {
|
|
52
|
-
const mockOnSearch =
|
|
53
|
+
const mockOnSearch = vi.fn()
|
|
53
54
|
const { getByRole, getByPlaceholderText } = render(<Wrapper onChange={mockOnSearch} />)
|
|
54
55
|
await window.customElements.whenDefined('pkt-icon')
|
|
55
56
|
|
|
@@ -70,8 +71,8 @@ describe('PktSearchInput', () => {
|
|
|
70
71
|
|
|
71
72
|
it('renders search suggestions when suggestions prop exists', async () => {
|
|
72
73
|
const suggestions = [
|
|
73
|
-
{ title: 'Suggestion 1', onClick:
|
|
74
|
-
{ title: 'Suggestion 2', onClick:
|
|
74
|
+
{ title: 'Suggestion 1', onClick: vi.fn() },
|
|
75
|
+
{ title: 'Suggestion 2', onClick: vi.fn() },
|
|
75
76
|
]
|
|
76
77
|
|
|
77
78
|
render(<PktSearchInput id="test-search-input" suggestions={suggestions} />)
|
|
@@ -86,8 +87,8 @@ describe('PktSearchInput', () => {
|
|
|
86
87
|
describe('accessibility', () => {
|
|
87
88
|
it('renders with no wcag errors with axe', async () => {
|
|
88
89
|
const suggestions = [
|
|
89
|
-
{ title: 'Suggestion 1', onClick:
|
|
90
|
-
{ title: 'Suggestion 2', onClick:
|
|
90
|
+
{ title: 'Suggestion 1', onClick: vi.fn() },
|
|
91
|
+
{ title: 'Suggestion 2', onClick: vi.fn() },
|
|
91
92
|
]
|
|
92
93
|
const { container } = render(<PktSearchInput id="test-search-input" label="My label" suggestions={suggestions} />)
|
|
93
94
|
await window.customElements.whenDefined('pkt-icon')
|
|
@@ -2,6 +2,7 @@ import '@testing-library/jest-dom'
|
|
|
2
2
|
|
|
3
3
|
import { fireEvent, render } from '@testing-library/react'
|
|
4
4
|
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
5
|
+
import { vi } from 'vitest'
|
|
5
6
|
|
|
6
7
|
import { PktTabItem, PktTabs } from './Tabs'
|
|
7
8
|
|
|
@@ -9,8 +10,8 @@ expect.extend(toHaveNoViolations)
|
|
|
9
10
|
|
|
10
11
|
describe('Tabs component', () => {
|
|
11
12
|
const tabs = [
|
|
12
|
-
{ text: 'Tab 1', href: '#', action:
|
|
13
|
-
{ text: 'Tab 2', action:
|
|
13
|
+
{ text: 'Tab 1', href: '#', action: vi.fn() },
|
|
14
|
+
{ text: 'Tab 2', action: vi.fn() },
|
|
14
15
|
]
|
|
15
16
|
|
|
16
17
|
it('renders tabs with links and buttons', () => {
|
|
@@ -36,7 +37,7 @@ describe('Tabs component', () => {
|
|
|
36
37
|
})
|
|
37
38
|
|
|
38
39
|
it('calls onTabSelected prop when a tab is clicked', () => {
|
|
39
|
-
const onTabSelected =
|
|
40
|
+
const onTabSelected = vi.fn()
|
|
40
41
|
const { getByText } = render(<PktTabs tabs={tabs} onTabSelected={onTabSelected} />)
|
|
41
42
|
tabs.forEach((tab, index) => {
|
|
42
43
|
const tabElement = getByText(tab.text)
|
|
@@ -47,8 +48,8 @@ describe('Tabs component', () => {
|
|
|
47
48
|
describe('accessibility', () => {
|
|
48
49
|
it('renders with no wcag errors with axe', async () => {
|
|
49
50
|
const tabs = [
|
|
50
|
-
{ text: 'Tab 1', href: '/page1', action:
|
|
51
|
-
{ text: 'Tab 2', action:
|
|
51
|
+
{ text: 'Tab 1', href: '/page1', action: vi.fn() },
|
|
52
|
+
{ text: 'Tab 2', action: vi.fn() },
|
|
52
53
|
]
|
|
53
54
|
const { container } = render(<PktTabs tabs={tabs} />)
|
|
54
55
|
const results = await axe(container)
|
|
@@ -89,7 +90,7 @@ describe('PktTabItem children format', () => {
|
|
|
89
90
|
})
|
|
90
91
|
|
|
91
92
|
it('calls onClick handler when tab is clicked', () => {
|
|
92
|
-
const handleClick =
|
|
93
|
+
const handleClick = vi.fn()
|
|
93
94
|
const { getByText } = render(
|
|
94
95
|
<PktTabs>
|
|
95
96
|
<PktTabItem index={0}>First Tab</PktTabItem>
|
|
@@ -106,7 +107,7 @@ describe('PktTabItem children format', () => {
|
|
|
106
107
|
})
|
|
107
108
|
|
|
108
109
|
it('calls onTabSelected when tab is clicked', () => {
|
|
109
|
-
const handleTabSelected =
|
|
110
|
+
const handleTabSelected = vi.fn()
|
|
110
111
|
const { getByText } = render(
|
|
111
112
|
<PktTabs onTabSelected={handleTabSelected}>
|
|
112
113
|
<PktTabItem index={0}>First Tab</PktTabItem>
|
|
@@ -120,8 +121,8 @@ describe('PktTabItem children format', () => {
|
|
|
120
121
|
})
|
|
121
122
|
|
|
122
123
|
it('calls both onClick and onTabSelected when tab is clicked', () => {
|
|
123
|
-
const handleClick =
|
|
124
|
-
const handleTabSelected =
|
|
124
|
+
const handleClick = vi.fn()
|
|
125
|
+
const handleTabSelected = vi.fn()
|
|
125
126
|
const { getByText } = render(
|
|
126
127
|
<PktTabs onTabSelected={handleTabSelected}>
|
|
127
128
|
<PktTabItem index={0}>First Tab</PktTabItem>
|
|
@@ -268,7 +269,7 @@ describe('PktTabItem children format', () => {
|
|
|
268
269
|
})
|
|
269
270
|
|
|
270
271
|
it('selects tab when Space key is pressed', () => {
|
|
271
|
-
const handleTabSelected =
|
|
272
|
+
const handleTabSelected = vi.fn()
|
|
272
273
|
const { getByText } = render(
|
|
273
274
|
<PktTabs onTabSelected={handleTabSelected}>
|
|
274
275
|
<PktTabItem index={0}>First Tab</PktTabItem>
|
|
@@ -283,7 +284,7 @@ describe('PktTabItem children format', () => {
|
|
|
283
284
|
})
|
|
284
285
|
|
|
285
286
|
it('selects tab when ArrowDown key is pressed', () => {
|
|
286
|
-
const handleTabSelected =
|
|
287
|
+
const handleTabSelected = vi.fn()
|
|
287
288
|
const { getByText } = render(
|
|
288
289
|
<PktTabs onTabSelected={handleTabSelected}>
|
|
289
290
|
<PktTabItem index={0}>First Tab</PktTabItem>
|
|
@@ -357,7 +358,7 @@ describe('PktTabItem children format', () => {
|
|
|
357
358
|
|
|
358
359
|
it('works with mapped children when explicit index is provided', () => {
|
|
359
360
|
const items = ['First', 'Second', 'Third']
|
|
360
|
-
const handleTabSelected =
|
|
361
|
+
const handleTabSelected = vi.fn()
|
|
361
362
|
|
|
362
363
|
const { getByText } = render(
|
|
363
364
|
<PktTabs onTabSelected={handleTabSelected}>
|
|
@@ -3,6 +3,7 @@ import '@testing-library/jest-dom'
|
|
|
3
3
|
import { fireEvent, render as originalRender, RenderOptions, RenderResult } from '@testing-library/react'
|
|
4
4
|
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
5
5
|
import { createRef, ReactNode } from 'react'
|
|
6
|
+
import { vi } from 'vitest'
|
|
6
7
|
|
|
7
8
|
import { PktTag } from './Tag'
|
|
8
9
|
|
|
@@ -68,7 +69,7 @@ describe('PktTag', () => {
|
|
|
68
69
|
})
|
|
69
70
|
|
|
70
71
|
it('calls onClose when tag is clicked', async () => {
|
|
71
|
-
const onClose =
|
|
72
|
+
const onClose = vi.fn()
|
|
72
73
|
const { getByText } = await render(
|
|
73
74
|
<PktTag closeTag={true} onClose={onClose}>
|
|
74
75
|
Closeable Tag
|