@oslokommune/punkt-elements 13.6.10 → 13.6.12
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 +34 -0
- package/dist/{combobox-cK_746ek.cjs → combobox-BFOjlFIj.cjs} +1 -1
- package/dist/{combobox-DxNotM0u.js → combobox-DaiEdUKx.js} +1 -1
- package/dist/datepicker-C244h82t.cjs +190 -0
- package/dist/datepicker-DwOkktaP.js +859 -0
- package/dist/index.d.ts +48 -13
- package/dist/{input-wrapper-D_JdEqcO.js → input-wrapper-CQzXG44g.js} +22 -22
- package/dist/{input-wrapper-C9rZEgju.cjs → input-wrapper-DVjNwf8-.cjs} +11 -12
- package/dist/pkt-combobox.cjs +1 -1
- package/dist/pkt-combobox.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 +6 -6
- package/dist/pkt-input-wrapper.cjs +1 -1
- package/dist/pkt-input-wrapper.js +1 -1
- package/dist/pkt-select.cjs +1 -1
- package/dist/pkt-select.js +1 -1
- package/dist/pkt-textarea.cjs +1 -1
- package/dist/pkt-textarea.js +1 -1
- package/dist/pkt-textinput.cjs +1 -1
- package/dist/pkt-textinput.js +1 -1
- package/dist/{select-D7OQaUrQ.js → select-DKkoxmgj.js} +1 -1
- package/dist/{select-Cf1RWSsI.cjs → select-DynzsPo0.cjs} +1 -1
- package/dist/{textarea-CXu8UUsY.cjs → textarea-BS1tgktz.cjs} +1 -1
- package/dist/{textarea-C0vTWTov.js → textarea-COG1CH_s.js} +1 -1
- package/dist/{textinput-C6wccDhZ.cjs → textinput-CCK8ti2y.cjs} +1 -1
- package/dist/{textinput-CmZrfH4A.js → textinput-CTOtfcTR.js} +1 -1
- package/package.json +2 -2
- package/src/components/checkbox/checkbox.ts +17 -1
- package/src/components/datepicker/datepicker-popup.test.ts +77 -0
- package/src/components/datepicker/datepicker-popup.ts +137 -0
- package/src/components/datepicker/datepicker-utils.ts +13 -8
- package/src/components/datepicker/datepicker.ts +64 -48
- package/src/components/input-wrapper/input-wrapper.ts +7 -7
- package/src/components/radiobutton/radiobutton.ts +14 -1
- package/src/components/textarea/textarea.ts +4 -1
- package/dist/datepicker-BEMo4X9s.js +0 -770
- package/dist/datepicker-n49TAIAt.cjs +0 -169
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import '@testing-library/jest-dom'
|
|
2
|
+
import { fireEvent } from '@testing-library/dom'
|
|
3
|
+
import { vi } from 'vitest'
|
|
4
|
+
|
|
5
|
+
import { createElementTest, BaseTestConfig } from '../../tests/test-framework'
|
|
6
|
+
import './datepicker-popup'
|
|
7
|
+
import '../calendar/calendar'
|
|
8
|
+
|
|
9
|
+
import { PktDatepickerPopup } from './datepicker-popup'
|
|
10
|
+
import { PktCalendar } from '../calendar/calendar'
|
|
11
|
+
|
|
12
|
+
export interface IDatepickerPopupTest extends BaseTestConfig {
|
|
13
|
+
open?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const createPopupTest = async (config: IDatepickerPopupTest = {}) => {
|
|
17
|
+
const { container, element } = await createElementTest('pkt-datepicker-popup' as any, config)
|
|
18
|
+
return { container, popup: element as PktDatepickerPopup }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
document.body.innerHTML = ''
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
describe('PktDatepickerPopup', () => {
|
|
26
|
+
test('opens when show() is called', async () => {
|
|
27
|
+
const { popup } = await createPopupTest()
|
|
28
|
+
await popup.updateComplete
|
|
29
|
+
|
|
30
|
+
popup.show()
|
|
31
|
+
await popup.updateComplete
|
|
32
|
+
expect(popup.open).toBe(true)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('closes when clicking outside', async () => {
|
|
36
|
+
const { popup } = await createPopupTest()
|
|
37
|
+
await popup.updateComplete
|
|
38
|
+
|
|
39
|
+
popup.show()
|
|
40
|
+
await popup.updateComplete
|
|
41
|
+
expect(popup.open).toBe(true)
|
|
42
|
+
|
|
43
|
+
fireEvent.click(document.body)
|
|
44
|
+
await popup.updateComplete
|
|
45
|
+
expect(popup.open).toBe(false)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
test('closes on Escape key', async () => {
|
|
49
|
+
const { popup } = await createPopupTest()
|
|
50
|
+
await popup.updateComplete
|
|
51
|
+
|
|
52
|
+
popup.show()
|
|
53
|
+
await popup.updateComplete
|
|
54
|
+
expect(popup.open).toBe(true)
|
|
55
|
+
|
|
56
|
+
fireEvent.keyDown(popup, { key: 'Escape' })
|
|
57
|
+
await popup.updateComplete
|
|
58
|
+
expect(popup.open).toBe(false)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
test('re-dispatches date-selected from child calendar', async () => {
|
|
62
|
+
const { popup } = await createPopupTest()
|
|
63
|
+
await popup.updateComplete
|
|
64
|
+
|
|
65
|
+
const handler = vi.fn()
|
|
66
|
+
popup.addEventListener('date-selected', (e: any) => handler(e))
|
|
67
|
+
|
|
68
|
+
const cal = popup.querySelector('pkt-calendar') as PktCalendar | null
|
|
69
|
+
expect(cal).toBeTruthy()
|
|
70
|
+
const detail = ['2025-09-17']
|
|
71
|
+
cal?.dispatchEvent(new CustomEvent('date-selected', { detail, bubbles: true, composed: true }))
|
|
72
|
+
|
|
73
|
+
expect(handler).toHaveBeenCalled()
|
|
74
|
+
const eventArg = handler.mock.calls[0][0]
|
|
75
|
+
expect(eventArg.detail).toEqual(detail)
|
|
76
|
+
})
|
|
77
|
+
})
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { html } from 'lit'
|
|
2
|
+
import { PktElement } from '@/base-elements/element'
|
|
3
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
4
|
+
import { classMap } from 'lit/directives/class-map.js'
|
|
5
|
+
import { ref, createRef, Ref } from 'lit/directives/ref.js'
|
|
6
|
+
|
|
7
|
+
import { PktCalendar } from '../calendar/calendar'
|
|
8
|
+
import { calendarUtils } from './datepicker-utils'
|
|
9
|
+
|
|
10
|
+
@customElement('pkt-datepicker-popup')
|
|
11
|
+
export class PktDatepickerPopup extends PktElement {
|
|
12
|
+
@property({ type: Boolean, reflect: true }) open = false
|
|
13
|
+
@property({ type: Boolean }) multiple = false
|
|
14
|
+
@property({ type: Boolean }) range = false
|
|
15
|
+
@property({ type: Boolean }) weeknumbers = false
|
|
16
|
+
@property({ type: Boolean }) withcontrols = false
|
|
17
|
+
@property({ type: Number }) maxMultiple: number | null = null
|
|
18
|
+
@property({ type: Array }) selected: string[] = []
|
|
19
|
+
@property({ type: String }) earliest: string | null = null
|
|
20
|
+
@property({ type: String }) latest: string | null = null
|
|
21
|
+
@property({ type: Array }) excludedates: string[] = []
|
|
22
|
+
@property({ type: Array }) excludeweekdays: string[] = []
|
|
23
|
+
@property({ type: String }) currentmonth: string | null = null
|
|
24
|
+
|
|
25
|
+
popupRef: Ref<HTMLElement> = createRef()
|
|
26
|
+
calendarRef: Ref<HTMLElement> = createRef()
|
|
27
|
+
|
|
28
|
+
firstUpdated() {
|
|
29
|
+
// expose calendarRef for external use
|
|
30
|
+
this.calRef = this.calendarRef
|
|
31
|
+
|
|
32
|
+
document.addEventListener('keydown', this.handleDocumentKeydown)
|
|
33
|
+
document.addEventListener('click', this.handleDocumentClick)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
disconnectedCallback() {
|
|
37
|
+
super.disconnectedCallback()
|
|
38
|
+
document.removeEventListener('click', this.handleDocumentClick)
|
|
39
|
+
document.removeEventListener('keydown', this.handleDocumentKeydown)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
handleDocumentClick = (e: MouseEvent) => {
|
|
43
|
+
if (!this.open) return
|
|
44
|
+
const path = e.composedPath() as EventTarget[]
|
|
45
|
+
const host = this.parentElement as EventTarget | null
|
|
46
|
+
const popupNode = this.popupRef.value as EventTarget | null
|
|
47
|
+
if (
|
|
48
|
+
!path.includes(this) &&
|
|
49
|
+
!path.includes(popupNode as EventTarget) &&
|
|
50
|
+
!(host && path.includes(host))
|
|
51
|
+
) {
|
|
52
|
+
this.hide()
|
|
53
|
+
this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
handleDocumentKeydown = (e: KeyboardEvent) => {
|
|
58
|
+
if (!this.open) return
|
|
59
|
+
if (e.key === 'Escape') {
|
|
60
|
+
this.hide()
|
|
61
|
+
this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }))
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
show() {
|
|
66
|
+
this.open = true
|
|
67
|
+
;(this.calendarRef.value as HTMLElement | null)?.focus()
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
hide() {
|
|
71
|
+
this.open = false
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
toggle() {
|
|
75
|
+
this.open ? this.hide() : this.show()
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
contains(node: Node | null) {
|
|
79
|
+
return !!node && !!(this.popupRef.value as HTMLElement | null)?.contains(node as Node)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
focusOnCurrentDate() {
|
|
83
|
+
const cal = this.calendarRef.value as PktCalendar
|
|
84
|
+
if (cal && typeof cal.focusOnCurrentDate === 'function') cal.focusOnCurrentDate()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
addToSelected(e: Event, min?: string | null, max?: string | null) {
|
|
88
|
+
if (typeof calendarUtils.addToSelected === 'function') {
|
|
89
|
+
return calendarUtils.addToSelected(e, this.calendarRef as any, min, max)
|
|
90
|
+
}
|
|
91
|
+
return undefined
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
handleDateSelect(date: Date) {
|
|
95
|
+
const cal = this.calendarRef.value as PktCalendar
|
|
96
|
+
if (cal && typeof cal.handleDateSelect === 'function') return cal.handleDateSelect(date)
|
|
97
|
+
return undefined
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
render() {
|
|
101
|
+
const classes = { 'pkt-calendar-popup': true, show: this.open, hide: !this.open }
|
|
102
|
+
return html`
|
|
103
|
+
<div
|
|
104
|
+
class="${classMap(classes)}"
|
|
105
|
+
${ref(this.popupRef)}
|
|
106
|
+
id="date-popup"
|
|
107
|
+
?hidden=${!this.open}
|
|
108
|
+
aria-hidden="${!this.open}"
|
|
109
|
+
>
|
|
110
|
+
<pkt-calendar
|
|
111
|
+
${ref(this.calendarRef)}
|
|
112
|
+
?multiple=${this.multiple}
|
|
113
|
+
?range=${this.range}
|
|
114
|
+
?weeknumbers=${this.weeknumbers}
|
|
115
|
+
?withcontrols=${this.withcontrols}
|
|
116
|
+
.maxMultiple=${this.maxMultiple}
|
|
117
|
+
.selected=${this.selected}
|
|
118
|
+
.earliest=${this.earliest}
|
|
119
|
+
.latest=${this.latest}
|
|
120
|
+
.excludedates=${this.excludedates}
|
|
121
|
+
.excludeweekdays=${this.excludeweekdays}
|
|
122
|
+
.currentmonth=${this.currentmonth}
|
|
123
|
+
@date-selected=${(e: CustomEvent) => {
|
|
124
|
+
this.selected = e.detail
|
|
125
|
+
this.dispatchEvent(
|
|
126
|
+
new CustomEvent('date-selected', { detail: e.detail, bubbles: true, composed: true }),
|
|
127
|
+
)
|
|
128
|
+
}}
|
|
129
|
+
@close=${() => {
|
|
130
|
+
this.hide()
|
|
131
|
+
this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }))
|
|
132
|
+
}}
|
|
133
|
+
></pkt-calendar>
|
|
134
|
+
</div>
|
|
135
|
+
`
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -24,18 +24,23 @@ export const sleep = (ms: number): Promise<void> =>
|
|
|
24
24
|
export const deviceDetection = {
|
|
25
25
|
/**
|
|
26
26
|
* Detects if the current device is iOS (iPhone, iPad, iPod)
|
|
27
|
+
* Handles modern iPad Safari which uses desktop user agent since iOS 13
|
|
27
28
|
*/
|
|
28
29
|
isIOS(): boolean {
|
|
29
30
|
const ua = navigator.userAgent
|
|
30
|
-
return /iP(hone|od|ad)/.test(ua)
|
|
31
|
-
},
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
// Legacy iOS detection (iPhone, iPod, older iPads)
|
|
33
|
+
if (/iP(hone|od|ad)/.test(ua)) {
|
|
34
|
+
return true
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Modern iPad detection (iOS 13+ iPads identify as Mac)
|
|
38
|
+
// Check for Mac + touch support
|
|
39
|
+
if (/Macintosh/.test(ua) && 'ontouchend' in document) {
|
|
40
|
+
return true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return false
|
|
39
44
|
},
|
|
40
45
|
}
|
|
41
46
|
|
|
@@ -12,6 +12,7 @@ import '@/components/calendar'
|
|
|
12
12
|
import '@/components/icon'
|
|
13
13
|
import '@/components/input-wrapper'
|
|
14
14
|
import './date-tags'
|
|
15
|
+
import './datepicker-popup'
|
|
15
16
|
import { PktSlotController } from '@/controllers/pkt-slot-controller'
|
|
16
17
|
import { keyboardUtils } from './datepicker-utils'
|
|
17
18
|
import {
|
|
@@ -20,19 +21,39 @@ import {
|
|
|
20
21
|
valueUtils,
|
|
21
22
|
inputTypeUtils,
|
|
22
23
|
calendarUtils,
|
|
23
|
-
eventUtils,
|
|
24
24
|
cssUtils,
|
|
25
25
|
dateProcessingUtils,
|
|
26
26
|
formUtils,
|
|
27
27
|
} from './datepicker-utils'
|
|
28
|
+
import { PktDatepickerPopup } from './datepicker-popup'
|
|
29
|
+
import { ElementProps } from '@/types/typeUtils'
|
|
30
|
+
|
|
31
|
+
type Props = ElementProps<
|
|
32
|
+
PktDatepicker,
|
|
33
|
+
| 'label'
|
|
34
|
+
| 'dateformat'
|
|
35
|
+
| 'multiple'
|
|
36
|
+
| 'maxlength'
|
|
37
|
+
| 'range'
|
|
38
|
+
| 'showRangeLabels'
|
|
39
|
+
| 'min'
|
|
40
|
+
| 'max'
|
|
41
|
+
| 'weeknumbers'
|
|
42
|
+
| 'withcontrols'
|
|
43
|
+
| 'excludedates'
|
|
44
|
+
| 'excludeweekdays'
|
|
45
|
+
| 'currentmonth'
|
|
46
|
+
| 'calendarOpen'
|
|
47
|
+
| 'timezone'
|
|
48
|
+
>
|
|
49
|
+
|
|
28
50
|
@customElement('pkt-datepicker')
|
|
29
|
-
export class PktDatepicker extends PktInputElement {
|
|
51
|
+
export class PktDatepicker extends PktInputElement<Props> {
|
|
30
52
|
/**
|
|
31
53
|
* Element attributes and properties
|
|
32
54
|
*/
|
|
33
55
|
private _valueProperty: string = ''
|
|
34
|
-
|
|
35
|
-
private documentKeydownListener?: (e: KeyboardEvent) => void
|
|
56
|
+
datepickerPopupRef: Ref<PktDatepickerPopup> = createRef()
|
|
36
57
|
|
|
37
58
|
@property({ type: String, reflect: true })
|
|
38
59
|
get value(): string {
|
|
@@ -120,30 +141,10 @@ export class PktDatepicker extends PktInputElement {
|
|
|
120
141
|
}
|
|
121
142
|
this.name =
|
|
122
143
|
valueUtils.normalizeNameForMultiple(this.name, this.multiple, this.range) || this.name
|
|
123
|
-
this.documentClickListener = eventUtils.createDocumentClickListener(
|
|
124
|
-
this.inputRef,
|
|
125
|
-
this.inputRefTo,
|
|
126
|
-
this.btnRef,
|
|
127
|
-
() => this.calendarOpen,
|
|
128
|
-
this.onBlur.bind(this),
|
|
129
|
-
this.hideCalendar.bind(this),
|
|
130
|
-
)
|
|
131
|
-
this.documentKeydownListener = eventUtils.createDocumentKeydownListener(
|
|
132
|
-
() => this.calendarOpen,
|
|
133
|
-
this.hideCalendar.bind(this),
|
|
134
|
-
)
|
|
135
|
-
document.addEventListener('click', this.documentClickListener)
|
|
136
|
-
document.addEventListener('keydown', this.documentKeydownListener)
|
|
137
144
|
}
|
|
138
145
|
|
|
139
146
|
disconnectedCallback(): void {
|
|
140
147
|
super.disconnectedCallback()
|
|
141
|
-
if (this.documentClickListener) {
|
|
142
|
-
document.removeEventListener('click', this.documentClickListener)
|
|
143
|
-
}
|
|
144
|
-
if (this.documentKeydownListener) {
|
|
145
|
-
document.removeEventListener('keydown', this.documentKeydownListener)
|
|
146
|
-
}
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
onInput(): void {
|
|
@@ -271,7 +272,7 @@ export class PktDatepicker extends PktInputElement {
|
|
|
271
272
|
}}
|
|
272
273
|
@focus=${() => {
|
|
273
274
|
this.onFocus()
|
|
274
|
-
if (deviceDetection.
|
|
275
|
+
if (deviceDetection.isIOS()) {
|
|
275
276
|
this.showCalendar()
|
|
276
277
|
}
|
|
277
278
|
}}
|
|
@@ -327,7 +328,7 @@ export class PktDatepicker extends PktInputElement {
|
|
|
327
328
|
}}
|
|
328
329
|
@focus=${() => {
|
|
329
330
|
this.onFocus()
|
|
330
|
-
if (deviceDetection.
|
|
331
|
+
if (deviceDetection.isIOS()) {
|
|
331
332
|
this.showCalendar()
|
|
332
333
|
}
|
|
333
334
|
}}
|
|
@@ -380,7 +381,7 @@ export class PktDatepicker extends PktInputElement {
|
|
|
380
381
|
}}
|
|
381
382
|
@focus=${() => {
|
|
382
383
|
this.onFocus()
|
|
383
|
-
if (deviceDetection.
|
|
384
|
+
if (deviceDetection.isIOS()) {
|
|
384
385
|
this.showCalendar()
|
|
385
386
|
}
|
|
386
387
|
}}
|
|
@@ -441,7 +442,7 @@ export class PktDatepicker extends PktInputElement {
|
|
|
441
442
|
}}
|
|
442
443
|
@focus=${() => {
|
|
443
444
|
this.onFocus()
|
|
444
|
-
if (deviceDetection.
|
|
445
|
+
if (deviceDetection.isIOS()) {
|
|
445
446
|
this.showCalendar()
|
|
446
447
|
}
|
|
447
448
|
}}
|
|
@@ -465,16 +466,10 @@ export class PktDatepicker extends PktInputElement {
|
|
|
465
466
|
}
|
|
466
467
|
|
|
467
468
|
renderCalendar() {
|
|
468
|
-
return html
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}}
|
|
473
|
-
id="${this.id}-popup"
|
|
474
|
-
${ref(this.popupRef)}
|
|
475
|
-
>
|
|
476
|
-
<pkt-calendar
|
|
477
|
-
id="${this.id}-calendar"
|
|
469
|
+
return html`
|
|
470
|
+
<pkt-datepicker-popup
|
|
471
|
+
class="pkt-contents"
|
|
472
|
+
?open=${this.calendarOpen}
|
|
478
473
|
?multiple=${this.multiple}
|
|
479
474
|
?range=${this.range}
|
|
480
475
|
?weeknumbers=${this.weeknumbers}
|
|
@@ -504,9 +499,9 @@ export class PktDatepicker extends PktInputElement {
|
|
|
504
499
|
this.onBlur()
|
|
505
500
|
this.hideCalendar()
|
|
506
501
|
}}
|
|
507
|
-
${ref(this.
|
|
508
|
-
></pkt-
|
|
509
|
-
|
|
502
|
+
${ref(this.datepickerPopupRef)}
|
|
503
|
+
></pkt-datepicker-popup>
|
|
504
|
+
`
|
|
510
505
|
}
|
|
511
506
|
|
|
512
507
|
render() {
|
|
@@ -551,7 +546,13 @@ export class PktDatepicker extends PktInputElement {
|
|
|
551
546
|
strings=${this.strings}
|
|
552
547
|
id-base=${this.id}
|
|
553
548
|
@date-tag-removed=${(e: CustomEvent) => {
|
|
554
|
-
this.
|
|
549
|
+
const popup = this.datepickerPopupRef.value
|
|
550
|
+
const date = fromISOToDate(e.detail)
|
|
551
|
+
if (popup && date && typeof popup.handleDateSelect === 'function') {
|
|
552
|
+
popup.handleDateSelect(date)
|
|
553
|
+
} else {
|
|
554
|
+
this.calRef.value?.handleDateSelect(date)
|
|
555
|
+
}
|
|
555
556
|
}}
|
|
556
557
|
></pkt-date-tags>`
|
|
557
558
|
: nothing}
|
|
@@ -595,28 +596,43 @@ export class PktDatepicker extends PktInputElement {
|
|
|
595
596
|
}
|
|
596
597
|
|
|
597
598
|
addToSelected = (e: Event | KeyboardEvent) => {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
599
|
+
const popup = this.datepickerPopupRef.value
|
|
600
|
+
if (popup && typeof popup.addToSelected === 'function') {
|
|
601
|
+
return popup.addToSelected(e, this.min, this.max)
|
|
602
|
+
}
|
|
603
|
+
return calendarUtils.addToSelected(e, this.calRef, this.min, this.max)
|
|
603
604
|
}
|
|
604
605
|
|
|
605
606
|
public async showCalendar() {
|
|
607
|
+
const popup = this.datepickerPopupRef.value
|
|
606
608
|
this.calendarOpen = true
|
|
609
|
+
if (popup && typeof popup.show === 'function') {
|
|
610
|
+
popup.show()
|
|
611
|
+
if (deviceDetection.isIOS()) popup.focusOnCurrentDate()
|
|
612
|
+
return
|
|
613
|
+
}
|
|
607
614
|
await sleep(20)
|
|
608
615
|
this.handleCalendarPosition()
|
|
609
|
-
if (deviceDetection.
|
|
616
|
+
if (deviceDetection.isIOS()) {
|
|
610
617
|
this.calRef.value?.focusOnCurrentDate()
|
|
611
618
|
}
|
|
612
619
|
}
|
|
613
620
|
|
|
614
621
|
public hideCalendar() {
|
|
622
|
+
const popup = this.datepickerPopupRef.value
|
|
615
623
|
this.calendarOpen = false
|
|
624
|
+
if (popup && typeof popup.hide === 'function') return popup.hide()
|
|
616
625
|
}
|
|
617
626
|
|
|
618
627
|
public async toggleCalendar(e: Event) {
|
|
619
628
|
e.preventDefault()
|
|
629
|
+
const popup = this.datepickerPopupRef.value
|
|
630
|
+
if (popup && typeof popup.toggle === 'function') {
|
|
631
|
+
const wasOpen = !!popup.open
|
|
632
|
+
popup.toggle()
|
|
633
|
+
this.calendarOpen = !wasOpen
|
|
634
|
+
return
|
|
635
|
+
}
|
|
620
636
|
this.calendarOpen ? this.hideCalendar() : this.showCalendar()
|
|
621
637
|
}
|
|
622
638
|
|
|
@@ -11,6 +11,7 @@ import { uuidish } from '@/utils/stringutils'
|
|
|
11
11
|
import specs from 'componentSpecs/input-wrapper.json'
|
|
12
12
|
import '@/components/helptext'
|
|
13
13
|
import '@/components/icon'
|
|
14
|
+
import '@/components/alert'
|
|
14
15
|
|
|
15
16
|
type TCounterPosition = 'top' | 'bottom'
|
|
16
17
|
type Props = ElementProps<
|
|
@@ -190,16 +191,15 @@ export class PktInputWrapper extends PktElement<Props> {
|
|
|
190
191
|
|
|
191
192
|
const errorElement = () => {
|
|
192
193
|
if (this.hasError && this.errorMessage) {
|
|
193
|
-
return html`<
|
|
194
|
-
|
|
195
|
-
|
|
194
|
+
return html`<pkt-alert
|
|
195
|
+
skin="error"
|
|
196
|
+
compact
|
|
197
|
+
id=${`${this.forId}-error`}
|
|
196
198
|
aria-live="assertive"
|
|
197
199
|
aria-atomic="true"
|
|
198
|
-
id="${this.forId}-error"
|
|
199
200
|
>
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
</div>`
|
|
201
|
+
${unsafeHTML(this.errorMessage)}
|
|
202
|
+
</pkt-alert>`
|
|
203
203
|
} else {
|
|
204
204
|
return nothing
|
|
205
205
|
}
|
|
@@ -4,9 +4,22 @@ import { PktInputElement } from '@/base-elements/input-element'
|
|
|
4
4
|
import { Ref, createRef, ref } from 'lit/directives/ref.js'
|
|
5
5
|
import { html, nothing } from 'lit'
|
|
6
6
|
import { classMap } from 'lit/directives/class-map.js'
|
|
7
|
+
import { ElementProps } from '@/types/typeUtils'
|
|
8
|
+
|
|
9
|
+
type Props = ElementProps<
|
|
10
|
+
PktRadioButton,
|
|
11
|
+
| 'checkHelptext'
|
|
12
|
+
| 'defaultChecked'
|
|
13
|
+
| 'hasTile'
|
|
14
|
+
| 'tagText'
|
|
15
|
+
| 'optionalTag'
|
|
16
|
+
| 'optionalText'
|
|
17
|
+
| 'requiredTag'
|
|
18
|
+
| 'requiredText'
|
|
19
|
+
>
|
|
7
20
|
|
|
8
21
|
@customElement('pkt-radiobutton')
|
|
9
|
-
export class PktRadioButton extends PktInputElement {
|
|
22
|
+
export class PktRadioButton extends PktInputElement<Props> {
|
|
10
23
|
private inputRef: Ref<HTMLInputElement> = createRef()
|
|
11
24
|
|
|
12
25
|
@property({ type: String, reflect: true }) value: string = ''
|
|
@@ -9,9 +9,12 @@ import { PktSlotController } from '@/controllers/pkt-slot-controller'
|
|
|
9
9
|
|
|
10
10
|
import '@/components/input-wrapper'
|
|
11
11
|
import '@/components/icon'
|
|
12
|
+
import { ElementProps } from '@/types/typeUtils'
|
|
13
|
+
|
|
14
|
+
type Props = ElementProps<PktTextarea, 'autocomplete' | 'rows'>
|
|
12
15
|
|
|
13
16
|
@customElement('pkt-textarea')
|
|
14
|
-
export class PktTextarea extends PktInputElement {
|
|
17
|
+
export class PktTextarea extends PktInputElement<Props> {
|
|
15
18
|
private inputRef: Ref<HTMLTextAreaElement> = createRef()
|
|
16
19
|
private helptextSlot: Ref<HTMLElement> = createRef()
|
|
17
20
|
|