@oslokommune/punkt-elements 13.4.2 → 13.5.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 +18 -0
- package/dist/calendar-32W9p9uc.cjs +115 -0
- package/dist/{calendar-DevQhOup.js → calendar-CJSxvwAq.js} +353 -340
- package/dist/{datepicker-CYOn3tRm.js → datepicker-BJKJBoy_.js} +102 -59
- package/dist/datepicker-CmTrG5GE.cjs +164 -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-datepicker.cjs +1 -1
- package/dist/pkt-datepicker.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +3 -3
- 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/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/dist/calendar-BZe2D4Sr.cjs +0 -108
- package/dist/datepicker-B9rhz_AF.cjs +0 -154
|
@@ -28,6 +28,18 @@ afterEach(() => {
|
|
|
28
28
|
document.body.innerHTML = ''
|
|
29
29
|
})
|
|
30
30
|
|
|
31
|
+
// Global console.warn spy to suppress validation warnings in tests
|
|
32
|
+
let consoleWarnSpy: jest.SpyInstance
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
if (consoleWarnSpy) {
|
|
39
|
+
consoleWarnSpy.mockRestore()
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
|
|
31
43
|
describe('PktCard', () => {
|
|
32
44
|
describe('Rendering and basic functionality', () => {
|
|
33
45
|
test('renders without errors', async () => {
|
|
@@ -138,23 +150,25 @@ describe('PktCard', () => {
|
|
|
138
150
|
})
|
|
139
151
|
|
|
140
152
|
test('validates skin values and logs warnings for invalid skins', async () => {
|
|
141
|
-
//
|
|
142
|
-
|
|
153
|
+
// Clear the global spy and create a new one for this specific test
|
|
154
|
+
consoleWarnSpy.mockRestore()
|
|
155
|
+
const localConsoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
143
156
|
|
|
144
157
|
const container = await createCard(`skin="zebra"`)
|
|
145
158
|
const card = container.querySelector('pkt-card') as PktCard
|
|
146
159
|
await card.updateComplete
|
|
147
160
|
|
|
148
161
|
// Should have logged a warning with the correct default value from spec
|
|
149
|
-
expect(
|
|
162
|
+
expect(localConsoleSpy).toHaveBeenCalledWith(
|
|
150
163
|
'Invalid skin value "zebra". Using default skin "outlined".',
|
|
151
164
|
)
|
|
152
165
|
|
|
153
166
|
// Should fall back to default from spec
|
|
154
167
|
expect(card.skin).toBe('outlined')
|
|
155
168
|
|
|
156
|
-
// Restore
|
|
157
|
-
|
|
169
|
+
// Restore and recreate global spy for subsequent tests
|
|
170
|
+
localConsoleSpy.mockRestore()
|
|
171
|
+
consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
158
172
|
})
|
|
159
173
|
|
|
160
174
|
test('applies different layout properties correctly', async () => {
|
|
@@ -0,0 +1,193 @@
|
|
|
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 './datepicker'
|
|
8
|
+
import '../calendar/calendar'
|
|
9
|
+
import { PktDatepicker } from './datepicker'
|
|
10
|
+
|
|
11
|
+
const waitForCustomElements = async () => {
|
|
12
|
+
await customElements.whenDefined('pkt-datepicker')
|
|
13
|
+
await customElements.whenDefined('pkt-calendar')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Helper function to create datepicker markup
|
|
17
|
+
const createDatepicker = async (datepickerProps = '') => {
|
|
18
|
+
const container = document.createElement('div')
|
|
19
|
+
container.innerHTML = `
|
|
20
|
+
<pkt-datepicker ${datepickerProps}></pkt-datepicker>
|
|
21
|
+
`
|
|
22
|
+
document.body.appendChild(container)
|
|
23
|
+
await waitForCustomElements()
|
|
24
|
+
return container
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Cleanup after each test
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
document.body.innerHTML = ''
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
describe('PktDatepicker', () => {
|
|
33
|
+
describe('Event handling', () => {
|
|
34
|
+
test('dispatches change event when value changes', async () => {
|
|
35
|
+
const container = await createDatepicker()
|
|
36
|
+
|
|
37
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
38
|
+
await datepicker.updateComplete
|
|
39
|
+
|
|
40
|
+
let changeEventFired = false
|
|
41
|
+
datepicker.addEventListener('change', () => {
|
|
42
|
+
changeEventFired = true
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const input = datepicker.querySelector('input') as HTMLInputElement
|
|
46
|
+
fireEvent.change(input, { target: { value: '2024-06-15' } })
|
|
47
|
+
fireEvent.blur(input)
|
|
48
|
+
await datepicker.updateComplete
|
|
49
|
+
|
|
50
|
+
expect(changeEventFired).toBe(true)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
test('dispatches input event during typing', async () => {
|
|
54
|
+
const container = await createDatepicker()
|
|
55
|
+
|
|
56
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
57
|
+
await datepicker.updateComplete
|
|
58
|
+
|
|
59
|
+
let inputEventFired = false
|
|
60
|
+
datepicker.addEventListener('input', () => {
|
|
61
|
+
inputEventFired = true
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const input = datepicker.querySelector('input') as HTMLInputElement
|
|
65
|
+
fireEvent.input(input, { target: { value: '2024-06-15' } })
|
|
66
|
+
await datepicker.updateComplete
|
|
67
|
+
|
|
68
|
+
expect(inputEventFired).toBe(true)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
test('dispatches focus and blur events', async () => {
|
|
72
|
+
const container = await createDatepicker()
|
|
73
|
+
|
|
74
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
75
|
+
await datepicker.updateComplete
|
|
76
|
+
|
|
77
|
+
let focusEventFired = false
|
|
78
|
+
let blurEventFired = false
|
|
79
|
+
|
|
80
|
+
datepicker.addEventListener('focus', () => {
|
|
81
|
+
focusEventFired = true
|
|
82
|
+
})
|
|
83
|
+
datepicker.addEventListener('blur', () => {
|
|
84
|
+
blurEventFired = true
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
const input = datepicker.querySelector('input') as HTMLInputElement
|
|
88
|
+
fireEvent.focus(input)
|
|
89
|
+
await datepicker.updateComplete
|
|
90
|
+
fireEvent.blur(input)
|
|
91
|
+
await datepicker.updateComplete
|
|
92
|
+
|
|
93
|
+
expect(focusEventFired).toBe(true)
|
|
94
|
+
expect(blurEventFired).toBe(true)
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
describe('Accessibility', () => {
|
|
99
|
+
test('has no accessibility violations', async () => {
|
|
100
|
+
const container = await createDatepicker(
|
|
101
|
+
'label="Test Datepicker" helptext="Select your date"',
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
105
|
+
await datepicker.updateComplete
|
|
106
|
+
|
|
107
|
+
const results = await axe(datepicker)
|
|
108
|
+
expect(results).toHaveNoViolations()
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
test('associates label with input correctly', async () => {
|
|
112
|
+
const container = await createDatepicker('id="test-datepicker" label="Test Label"')
|
|
113
|
+
|
|
114
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
115
|
+
await datepicker.updateComplete
|
|
116
|
+
|
|
117
|
+
const label = datepicker.querySelector('label')
|
|
118
|
+
const input = datepicker.querySelector('input')
|
|
119
|
+
|
|
120
|
+
expect(label).toHaveAttribute('for')
|
|
121
|
+
expect(input).toHaveAttribute('id')
|
|
122
|
+
expect(label?.getAttribute('for')).toBe(input?.getAttribute('id'))
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
test('has proper ARIA attributes for calendar button', async () => {
|
|
126
|
+
const container = await createDatepicker('label="Test Datepicker"')
|
|
127
|
+
|
|
128
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
129
|
+
await datepicker.updateComplete
|
|
130
|
+
|
|
131
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
132
|
+
expect(calendarButton).toBeInTheDocument()
|
|
133
|
+
|
|
134
|
+
// Check initial state
|
|
135
|
+
expect(datepicker.calendarOpen).toBe(false)
|
|
136
|
+
|
|
137
|
+
// Open calendar
|
|
138
|
+
fireEvent.click(calendarButton!)
|
|
139
|
+
await datepicker.updateComplete
|
|
140
|
+
|
|
141
|
+
expect(datepicker.calendarOpen).toBe(true)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
test('provides proper screen reader announcements', async () => {
|
|
145
|
+
const container = await createDatepicker('label="Test Datepicker"')
|
|
146
|
+
|
|
147
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
148
|
+
await datepicker.updateComplete
|
|
149
|
+
|
|
150
|
+
const input = datepicker.querySelector('input')
|
|
151
|
+
expect(input).toHaveAttribute('aria-describedby')
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
test('handles focus management correctly', async () => {
|
|
155
|
+
const container = await createDatepicker()
|
|
156
|
+
|
|
157
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
158
|
+
await datepicker.updateComplete
|
|
159
|
+
|
|
160
|
+
const calendarButton = datepicker.querySelector('button[type="button"]') as HTMLElement
|
|
161
|
+
|
|
162
|
+
// Focus should be manageable
|
|
163
|
+
if (calendarButton) {
|
|
164
|
+
calendarButton.focus()
|
|
165
|
+
expect(document.activeElement).toBe(calendarButton)
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
test('supports keyboard-only interaction', async () => {
|
|
170
|
+
const container = await createDatepicker()
|
|
171
|
+
|
|
172
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
173
|
+
await datepicker.updateComplete
|
|
174
|
+
|
|
175
|
+
const calendarButton = datepicker.querySelector('button[type="button"]') as HTMLElement
|
|
176
|
+
|
|
177
|
+
// Should open with keyboard
|
|
178
|
+
if (calendarButton) {
|
|
179
|
+
calendarButton.focus()
|
|
180
|
+
fireEvent.keyDown(calendarButton, { key: 'Enter' })
|
|
181
|
+
await datepicker.updateComplete
|
|
182
|
+
|
|
183
|
+
expect(datepicker.calendarOpen).toBe(true)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Should close with keyboard
|
|
187
|
+
fireEvent.keyDown(datepicker, { key: 'Escape' })
|
|
188
|
+
await datepicker.updateComplete
|
|
189
|
+
|
|
190
|
+
expect(datepicker.calendarOpen).toBe(false)
|
|
191
|
+
})
|
|
192
|
+
})
|
|
193
|
+
})
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import '@testing-library/jest-dom'
|
|
2
|
+
import { toHaveNoViolations } from 'jest-axe'
|
|
3
|
+
import { fireEvent } from '@testing-library/dom'
|
|
4
|
+
import { parseISODateString } from '@/utils/dateutils'
|
|
5
|
+
|
|
6
|
+
expect.extend(toHaveNoViolations)
|
|
7
|
+
|
|
8
|
+
import './datepicker'
|
|
9
|
+
import '../calendar/calendar'
|
|
10
|
+
import { PktDatepicker } from './datepicker'
|
|
11
|
+
import { PktCalendar } from '../calendar/calendar'
|
|
12
|
+
|
|
13
|
+
const waitForCustomElements = async () => {
|
|
14
|
+
await customElements.whenDefined('pkt-datepicker')
|
|
15
|
+
await customElements.whenDefined('pkt-calendar')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Helper function to create datepicker markup
|
|
19
|
+
const createDatepicker = async (datepickerProps = '') => {
|
|
20
|
+
const container = document.createElement('div')
|
|
21
|
+
container.innerHTML = `
|
|
22
|
+
<pkt-datepicker ${datepickerProps}></pkt-datepicker>
|
|
23
|
+
`
|
|
24
|
+
document.body.appendChild(container)
|
|
25
|
+
await waitForCustomElements()
|
|
26
|
+
return container
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Cleanup after each test
|
|
30
|
+
afterEach(() => {
|
|
31
|
+
document.body.innerHTML = ''
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('PktDatepicker', () => {
|
|
35
|
+
describe('Rendering and basic functionality', () => {
|
|
36
|
+
test('renders without errors', async () => {
|
|
37
|
+
const container = await createDatepicker()
|
|
38
|
+
|
|
39
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
40
|
+
expect(datepicker).toBeInTheDocument()
|
|
41
|
+
|
|
42
|
+
await datepicker.updateComplete
|
|
43
|
+
expect(datepicker).toBeTruthy()
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
test('renders with correct structure', async () => {
|
|
47
|
+
const container = await createDatepicker('label="Test Datepicker"')
|
|
48
|
+
|
|
49
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
50
|
+
await datepicker.updateComplete
|
|
51
|
+
|
|
52
|
+
const inputWrapper = datepicker.querySelector('pkt-input-wrapper')
|
|
53
|
+
const input = datepicker.querySelector('input')
|
|
54
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
55
|
+
|
|
56
|
+
expect(inputWrapper).toBeInTheDocument()
|
|
57
|
+
expect(input).toBeInTheDocument()
|
|
58
|
+
expect(calendarButton).toBeInTheDocument()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('renders calendar when opened', async () => {
|
|
62
|
+
const container = await createDatepicker('label="Test Datepicker"')
|
|
63
|
+
|
|
64
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
65
|
+
await datepicker.updateComplete
|
|
66
|
+
|
|
67
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
68
|
+
fireEvent.click(calendarButton!)
|
|
69
|
+
await datepicker.updateComplete
|
|
70
|
+
|
|
71
|
+
const calendar = datepicker.querySelector('pkt-calendar')
|
|
72
|
+
expect(calendar).toBeInTheDocument()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('closes calendar when clicking outside', async () => {
|
|
76
|
+
const container = await createDatepicker('label="Test Datepicker"')
|
|
77
|
+
|
|
78
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
79
|
+
await datepicker.updateComplete
|
|
80
|
+
|
|
81
|
+
// Open calendar
|
|
82
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
83
|
+
fireEvent.click(calendarButton!)
|
|
84
|
+
await datepicker.updateComplete
|
|
85
|
+
|
|
86
|
+
// Click outside
|
|
87
|
+
fireEvent.click(document.body)
|
|
88
|
+
await datepicker.updateComplete
|
|
89
|
+
|
|
90
|
+
expect(datepicker.calendarOpen).toBe(false)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
test('closes calendar when clicking outside', async () => {
|
|
94
|
+
const container = await createDatepicker('label="Test Datepicker"')
|
|
95
|
+
|
|
96
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
97
|
+
await datepicker.updateComplete
|
|
98
|
+
|
|
99
|
+
// Open calendar
|
|
100
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
101
|
+
fireEvent.click(calendarButton!)
|
|
102
|
+
await datepicker.updateComplete
|
|
103
|
+
|
|
104
|
+
// Click outside
|
|
105
|
+
fireEvent.click(document.body)
|
|
106
|
+
await datepicker.updateComplete
|
|
107
|
+
|
|
108
|
+
expect(datepicker.calendarOpen).toBe(false)
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
describe('Properties and attributes', () => {
|
|
113
|
+
test('applies default properties correctly', async () => {
|
|
114
|
+
const container = await createDatepicker('name="test" id="test"')
|
|
115
|
+
|
|
116
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
117
|
+
await datepicker.updateComplete
|
|
118
|
+
|
|
119
|
+
expect(datepicker.value).toBe('')
|
|
120
|
+
expect(datepicker.label).toBe('Datovelger')
|
|
121
|
+
expect(datepicker.multiple).toBe(false)
|
|
122
|
+
expect(datepicker.range).toBe(false)
|
|
123
|
+
expect(datepicker.maxlength).toBe(null)
|
|
124
|
+
expect(datepicker.showRangeLabels).toBe(false)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
test('handles value property correctly', async () => {
|
|
128
|
+
const testDate = '2024-06-15'
|
|
129
|
+
const container = await createDatepicker(`value="${testDate}"`)
|
|
130
|
+
|
|
131
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
132
|
+
await datepicker.updateComplete
|
|
133
|
+
|
|
134
|
+
expect(datepicker.value).toBe(testDate)
|
|
135
|
+
|
|
136
|
+
const input = datepicker.querySelector('input') as HTMLInputElement
|
|
137
|
+
expect(input.value).toBeTruthy()
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
test('handles multiple values correctly', async () => {
|
|
141
|
+
const testDates = '2024-06-15,2024-06-20,2024-06-25'
|
|
142
|
+
const container = await createDatepicker(`value="${testDates}" multiple`)
|
|
143
|
+
|
|
144
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
145
|
+
await datepicker.updateComplete
|
|
146
|
+
|
|
147
|
+
expect(datepicker.value).toBe(testDates)
|
|
148
|
+
expect(datepicker.multiple).toBe(true)
|
|
149
|
+
|
|
150
|
+
// Should show tags for multiple values
|
|
151
|
+
const tags = datepicker.querySelectorAll('pkt-tag')
|
|
152
|
+
expect(tags.length).toBe(3)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
test('handles range values correctly', async () => {
|
|
156
|
+
const rangeValue = '2024-06-15,2024-06-20'
|
|
157
|
+
const container = await createDatepicker(`value="${rangeValue}" range`)
|
|
158
|
+
|
|
159
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
160
|
+
await datepicker.updateComplete
|
|
161
|
+
|
|
162
|
+
expect(datepicker.value).toBe(rangeValue)
|
|
163
|
+
expect(datepicker.range).toBe(true)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('handles label property correctly', async () => {
|
|
167
|
+
const testLabel = 'Select your date'
|
|
168
|
+
const container = await createDatepicker(`label="${testLabel}"`)
|
|
169
|
+
|
|
170
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
171
|
+
await datepicker.updateComplete
|
|
172
|
+
|
|
173
|
+
expect(datepicker.label).toBe(testLabel)
|
|
174
|
+
|
|
175
|
+
const label = datepicker.querySelector('label')
|
|
176
|
+
expect(label?.textContent).toContain(testLabel)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('handles dateformat property correctly', async () => {
|
|
180
|
+
const customFormat = 'MM/dd/yyyy'
|
|
181
|
+
const container = await createDatepicker(
|
|
182
|
+
`dateformat="${customFormat}" value="2024-06-15" multiple`,
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
186
|
+
await datepicker.updateComplete
|
|
187
|
+
|
|
188
|
+
expect(datepicker.dateformat).toBe(customFormat)
|
|
189
|
+
|
|
190
|
+
// Multiple mode input should be empty (for new input)
|
|
191
|
+
const input = datepicker.querySelector('input') as HTMLInputElement
|
|
192
|
+
expect(input.value).toBe('')
|
|
193
|
+
|
|
194
|
+
// Selected dates should show in tags with custom format
|
|
195
|
+
const tag = datepicker.querySelector('pkt-tag time')
|
|
196
|
+
expect(tag).toBeInTheDocument()
|
|
197
|
+
if (tag) {
|
|
198
|
+
expect(tag.textContent).toMatch(/\d{2}\/\d{2}\/\d{4}/)
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
test('handles maxlength property correctly', async () => {
|
|
203
|
+
const container = await createDatepicker('multiple maxlength="3"')
|
|
204
|
+
|
|
205
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
206
|
+
await datepicker.updateComplete
|
|
207
|
+
|
|
208
|
+
expect(datepicker.maxlength).toBe(3)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
test('handles disabled property correctly', async () => {
|
|
212
|
+
const container = await createDatepicker('disabled')
|
|
213
|
+
|
|
214
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
215
|
+
await datepicker.updateComplete
|
|
216
|
+
|
|
217
|
+
expect(datepicker.disabled).toBe(true)
|
|
218
|
+
|
|
219
|
+
const input = datepicker.querySelector('input') as HTMLInputElement
|
|
220
|
+
const calendarButton = datepicker.querySelector('button[type="button"]') as HTMLButtonElement
|
|
221
|
+
|
|
222
|
+
expect(input.disabled).toBe(true)
|
|
223
|
+
expect(calendarButton.disabled).toBe(true)
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
test('handles currentmonth property correctly', async () => {
|
|
227
|
+
const testMonth = '2024-03-01'
|
|
228
|
+
const container = await createDatepicker(`currentmonth="${testMonth}"`)
|
|
229
|
+
|
|
230
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
231
|
+
await datepicker.updateComplete
|
|
232
|
+
|
|
233
|
+
// Open calendar to see the month
|
|
234
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
235
|
+
fireEvent.click(calendarButton!)
|
|
236
|
+
await datepicker.updateComplete
|
|
237
|
+
|
|
238
|
+
const calendar = datepicker.querySelector('pkt-calendar') as PktCalendar
|
|
239
|
+
expect(calendar.currentmonth).toEqual(parseISODateString(testMonth))
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
describe('Calendar integration', () => {
|
|
244
|
+
test('passes properties to calendar correctly', async () => {
|
|
245
|
+
const container = await createDatepicker(
|
|
246
|
+
'min="2024-06-01" max="2024-06-30" excludeweekdays="0,6"',
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
250
|
+
await datepicker.updateComplete
|
|
251
|
+
|
|
252
|
+
// Open calendar
|
|
253
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
254
|
+
fireEvent.click(calendarButton!)
|
|
255
|
+
await datepicker.updateComplete
|
|
256
|
+
|
|
257
|
+
const calendar = datepicker.querySelector('pkt-calendar') as PktCalendar
|
|
258
|
+
expect(calendar.earliest).toBe('2024-06-01')
|
|
259
|
+
expect(calendar.latest).toBe('2024-06-30')
|
|
260
|
+
expect(calendar.excludeweekdays).toEqual(['0', '6'])
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
test('syncs selected dates between input and calendar', async () => {
|
|
264
|
+
const testDate = '2024-06-15'
|
|
265
|
+
const container = await createDatepicker(`value="${testDate}"`)
|
|
266
|
+
|
|
267
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
268
|
+
await datepicker.updateComplete
|
|
269
|
+
|
|
270
|
+
// Open calendar
|
|
271
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
272
|
+
fireEvent.click(calendarButton!)
|
|
273
|
+
await datepicker.updateComplete
|
|
274
|
+
|
|
275
|
+
const calendar = datepicker.querySelector('pkt-calendar') as PktCalendar
|
|
276
|
+
expect(calendar.selected).toContain(testDate)
|
|
277
|
+
|
|
278
|
+
const selectedDate = datepicker.querySelector('.pkt-calendar__date--selected')
|
|
279
|
+
expect(selectedDate).toBeInTheDocument()
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
test('updates input when date selected in calendar', async () => {
|
|
283
|
+
const container = await createDatepicker()
|
|
284
|
+
|
|
285
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
286
|
+
await datepicker.updateComplete
|
|
287
|
+
|
|
288
|
+
// Open calendar
|
|
289
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
290
|
+
fireEvent.click(calendarButton!)
|
|
291
|
+
await datepicker.updateComplete
|
|
292
|
+
|
|
293
|
+
// Select a date
|
|
294
|
+
const availableDate = datepicker.querySelector(
|
|
295
|
+
'.pkt-calendar__date:not(.pkt-calendar__date--disabled)',
|
|
296
|
+
)
|
|
297
|
+
fireEvent.click(availableDate!)
|
|
298
|
+
await datepicker.updateComplete
|
|
299
|
+
|
|
300
|
+
// Input should be updated
|
|
301
|
+
const input = datepicker.querySelector('input') as HTMLInputElement
|
|
302
|
+
expect(input.value).toBeTruthy()
|
|
303
|
+
expect(datepicker.value).toBeTruthy()
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
test('shows current month correctly in calendar', async () => {
|
|
307
|
+
const currentMonth = '2024-06-01'
|
|
308
|
+
const container = await createDatepicker(`currentmonth="${currentMonth}"`)
|
|
309
|
+
|
|
310
|
+
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
|
|
311
|
+
await datepicker.updateComplete
|
|
312
|
+
|
|
313
|
+
// Open calendar
|
|
314
|
+
const calendarButton = datepicker.querySelector('button[type="button"]')
|
|
315
|
+
fireEvent.click(calendarButton!)
|
|
316
|
+
await datepicker.updateComplete
|
|
317
|
+
|
|
318
|
+
const monthTitle = datepicker.querySelector('.pkt-calendar__month-title')
|
|
319
|
+
expect(monthTitle?.textContent).toContain('2024')
|
|
320
|
+
})
|
|
321
|
+
})
|
|
322
|
+
})
|