@oslokommune/punkt-elements 20.1.0 → 20.1.3
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 +31 -0
- package/dist/{calendar-xYEsKilS.cjs → calendar-KZlln5k8.cjs} +2 -2
- package/dist/{calendar-CkAAgviq.js → calendar-T_iFl5mR.js} +2 -2
- package/dist/{checkbox-Cg7wnn8U.cjs → checkbox-BS0iHeSP.cjs} +1 -1
- package/dist/{checkbox-XvlUQmg5.js → checkbox-DCaSNEjy.js} +1 -1
- package/dist/{checkbox-group-BF29zyLd.cjs → checkbox-group-BZhrLn4e.cjs} +1 -1
- package/dist/{checkbox-group-CRIV5CX0.js → checkbox-group-GsfZSfMs.js} +2 -2
- package/dist/{combobox-DuXavWEY.cjs → combobox-DoUwp_6k.cjs} +2 -1
- package/dist/{combobox-CDJcIkNJ.js → combobox-_2jd4CHR.js} +4 -3
- package/dist/components/datepicker/datepicker-popup.d.ts +0 -1
- package/dist/components/datepicker/datepicker-utils.d.ts +2 -13
- package/dist/components/datepicker/datepicker.d.ts +32 -4
- package/dist/components/datepicker/index.d.ts +1 -0
- package/dist/{datepicker-DHdFA8Dx.js → datepicker-D60fq9D5.js} +227 -472
- package/dist/datepicker-DErgngTf.cjs +286 -0
- package/dist/{fileupload-Cjde62AR.cjs → fileupload-Cn7CvQtX.cjs} +1 -1
- package/dist/{fileupload-BQw5nlzQ.js → fileupload-dmzxRqGF.js} +4 -4
- package/dist/{header-YbbGgmsD.cjs → header-BQCGdOPT.cjs} +1 -1
- package/dist/{header-CZnKVVt4.js → header-Djjhqu7w.js} +2 -2
- package/dist/{helptext-CQaNvbiv.cjs → helptext-4xBIABJJ.cjs} +1 -1
- package/dist/{helptext-kKmVQkwo.js → helptext-CNg695BI.js} +1 -1
- package/dist/{input-element-CfZIyfon.cjs → input-element-BPzDBWdd.cjs} +1 -1
- package/dist/{input-element-DE0FzjgP.js → input-element-DsWlt-6T.js} +1 -1
- package/dist/{input-wrapper-DYg1VHPv.js → input-wrapper-BBUcHEKx.js} +2 -2
- package/dist/{input-wrapper-CbYMk21W.cjs → input-wrapper-EKGhSUKU.cjs} +1 -1
- package/dist/{listbox-df8gHweY.js → listbox-BcJbeoAT.js} +1 -1
- package/dist/{listbox-Du8llYth.cjs → listbox-gjzS_z0P.cjs} +1 -1
- package/dist/{modal-SBJ8aGvM.js → modal-CvqH9R3w.js} +1 -1
- package/dist/{modal-B3rnE83a.cjs → modal-Du-2AmLz.cjs} +1 -1
- package/dist/{option-group-element-dN0ntPZk.cjs → option-group-element-DgqdU9HX.cjs} +1 -1
- package/dist/{option-group-element-DtSw52Dr.js → option-group-element-Dr2FR6v7.js} +2 -2
- package/dist/pkt-calendar.cjs +1 -1
- package/dist/pkt-calendar.js +1 -1
- package/dist/pkt-checkbox-group.cjs +1 -1
- package/dist/pkt-checkbox-group.js +1 -1
- package/dist/pkt-checkbox.cjs +1 -1
- package/dist/pkt-checkbox.js +1 -1
- 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-fileupload.cjs +1 -1
- package/dist/pkt-fileupload.js +1 -1
- package/dist/pkt-header.cjs +1 -1
- package/dist/pkt-header.js +1 -1
- package/dist/pkt-helptext.cjs +1 -1
- package/dist/pkt-helptext.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +18 -18
- package/dist/pkt-input-wrapper.cjs +1 -1
- package/dist/pkt-input-wrapper.js +1 -1
- package/dist/pkt-listbox.cjs +1 -1
- package/dist/pkt-listbox.js +1 -1
- package/dist/pkt-modal.cjs +1 -1
- package/dist/pkt-modal.js +1 -1
- package/dist/pkt-progressbar.cjs +1 -1
- package/dist/pkt-progressbar.js +1 -1
- package/dist/pkt-radio-group.cjs +1 -1
- package/dist/pkt-radio-group.js +1 -1
- package/dist/pkt-radiobutton.cjs +1 -1
- package/dist/pkt-radiobutton.js +1 -1
- package/dist/pkt-searchinput.cjs +1 -1
- package/dist/pkt-searchinput.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/pkt-timepicker.cjs +1 -1
- package/dist/pkt-timepicker.js +1 -1
- package/dist/{progressbar-Wyq_Q1Ur.cjs → progressbar-BKA9zFnE.cjs} +1 -1
- package/dist/{progressbar-DlbkKRgP.js → progressbar-aKjj5VZg.js} +1 -1
- package/dist/{radio-group-u1IH7g-4.cjs → radio-group-BLVe7aMS.cjs} +1 -1
- package/dist/{radio-group-bRF8fnPW.js → radio-group-DDymupLt.js} +2 -2
- package/dist/{radiobutton-Bf6aFfYt.js → radiobutton-CnExI3Vj.js} +1 -1
- package/dist/{radiobutton-86ZvvDmJ.cjs → radiobutton-XX3zhblA.cjs} +1 -1
- package/dist/{searchinput-D5l64Mkb.cjs → searchinput-C8UHexyf.cjs} +1 -1
- package/dist/{searchinput-DN8kDZQ1.js → searchinput-DUJlxKHH.js} +1 -1
- package/dist/{select-CXIEM2qY.js → select-C4RDEc9h.js} +2 -2
- package/dist/{select-C7kAlSxs.cjs → select-CbVmSYmi.cjs} +1 -1
- package/dist/shared-types/datepicker.d.ts +76 -0
- package/dist/shared-types/index.d.ts +2 -2
- package/dist/shared-utils/datepicker-utils.d.ts +18 -0
- package/dist/shared-utils/forms/focus-within.d.ts +13 -0
- package/dist/{textarea-CRcSfWgX.cjs → textarea-D4yCdiFY.cjs} +1 -1
- package/dist/{textarea-12le8b4I.js → textarea-WktT3N3w.js} +2 -2
- package/dist/{textinput-CC0zxUBT.js → textinput-BPrC2neL.js} +2 -2
- package/dist/{textinput-Dooq2n8W.cjs → textinput-C6AcbxnQ.cjs} +1 -1
- package/dist/{timepicker-Cz81VQu3.js → timepicker-D77gssQg.js} +2 -2
- package/dist/{timepicker-BM4I5w-i.cjs → timepicker-DaqrwM-g.cjs} +1 -1
- package/dist/{utils-Dn5ykFtS.js → utils-BtXhdgpe.js} +2 -2
- package/dist/utils-dl1XA5EE.cjs +1 -0
- package/package.json +2 -2
- package/src/components/calendar/calendar.selection.test.ts +16 -0
- package/src/components/calendar/calendar.ts +4 -3
- package/src/components/combobox/combobox.interaction.test.ts +23 -0
- package/src/components/combobox/combobox.ts +1 -0
- package/src/components/datepicker/datepicker-multiple.ts +2 -6
- package/src/components/datepicker/datepicker-popup.ts +3 -6
- package/src/components/datepicker/datepicker-utils.test.ts +40 -203
- package/src/components/datepicker/datepicker-utils.ts +3 -94
- package/src/components/datepicker/datepicker.accessibility.test.ts +2 -2
- package/src/components/datepicker/datepicker.core.test.ts +236 -0
- package/src/components/datepicker/datepicker.ts +179 -115
- package/src/components/datepicker/index.ts +1 -0
- package/dist/datepicker-Cnrbqm62.cjs +0 -294
- package/dist/utils-63cRpWut.cjs +0 -1
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { customElement, property, state } from 'lit/decorators.js'
|
|
2
|
-
import {
|
|
2
|
+
import { fromISOToDate, parseISODateString } from 'shared-utils/date-utils'
|
|
3
3
|
import { html, nothing, PropertyValues } from 'lit'
|
|
4
4
|
import { PktCalendar } from '@/components/calendar/calendar'
|
|
5
5
|
import { PktInputElement } from '@/base-elements/input-element'
|
|
6
6
|
import { Ref, createRef, ref } from 'lit/directives/ref.js'
|
|
7
7
|
import converters from '@/helpers/converters'
|
|
8
|
-
import specs from 'componentSpecs/datepicker.json'
|
|
9
8
|
import '@/components/calendar'
|
|
10
9
|
import '@/components/icon'
|
|
11
10
|
import '@/components/input-wrapper'
|
|
@@ -18,20 +17,25 @@ import { forwardSlots } from '@/directives/slot-content'
|
|
|
18
17
|
import {
|
|
19
18
|
valueUtils,
|
|
20
19
|
inputTypeUtils,
|
|
21
|
-
calendarUtils,
|
|
22
20
|
cssUtils,
|
|
23
21
|
dateProcessingUtils,
|
|
24
|
-
formUtils,
|
|
25
22
|
} from './datepicker-utils'
|
|
26
23
|
import { valueToArray, arrayToCsv } from 'shared-utils/value-utils'
|
|
27
|
-
import { sleep } from 'shared-utils/utils'
|
|
28
24
|
import { isIOS } from 'shared-utils/device-utils'
|
|
25
|
+
import { createFocusWithinTracker } from 'shared-utils/forms/focus-within'
|
|
26
|
+
import {
|
|
27
|
+
completeRangeWithTo,
|
|
28
|
+
datepickerHasCounter,
|
|
29
|
+
rangeCalendarSelection,
|
|
30
|
+
handleCalendarPosition as positionCalendarPopup,
|
|
31
|
+
} from 'shared-utils/datepicker-utils'
|
|
29
32
|
import { PktDatepickerPopup } from './datepicker-popup'
|
|
30
33
|
import { PktDatepickerSingle } from './datepicker-single'
|
|
31
34
|
import { PktDatepickerRange } from './datepicker-range'
|
|
32
35
|
import { PktDatepickerMultiple } from './datepicker-multiple'
|
|
33
36
|
import { ElementProps } from '@/types/typeUtils'
|
|
34
37
|
import type { IPktStringsProps } from 'shared-strings'
|
|
38
|
+
import { DATEPICKER_DEFAULTS, type Booleanish, type IPktDatepickerBase } from 'shared-types'
|
|
35
39
|
|
|
36
40
|
type Props = ElementProps<
|
|
37
41
|
PktDatepicker,
|
|
@@ -53,7 +57,30 @@ type Props = ElementProps<
|
|
|
53
57
|
> &
|
|
54
58
|
IPktStringsProps<'generic' | 'datepicker' | 'dates' | 'calendar'>
|
|
55
59
|
|
|
56
|
-
export
|
|
60
|
+
export interface IPktDatepicker extends Omit<
|
|
61
|
+
IPktDatepickerBase,
|
|
62
|
+
| 'form'
|
|
63
|
+
| 'min'
|
|
64
|
+
| 'max'
|
|
65
|
+
| 'maxlength'
|
|
66
|
+
| 'currentmonth'
|
|
67
|
+
| 'today'
|
|
68
|
+
| 'ariaDescribedby'
|
|
69
|
+
| 'helptextDropdownButton'
|
|
70
|
+
| 'useWrapper'
|
|
71
|
+
> {
|
|
72
|
+
min?: string | null
|
|
73
|
+
max?: string | null
|
|
74
|
+
maxlength?: number | null
|
|
75
|
+
currentmonth?: string | null
|
|
76
|
+
today?: string | null
|
|
77
|
+
ariaDescribedby?: string | null
|
|
78
|
+
/** @deprecated Bruk `strings={{ forms: { readMore: '…' } }}` eller `setPktStrings()`. */
|
|
79
|
+
helptextDropdownButton?: string | null
|
|
80
|
+
useWrapper?: Booleanish
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class PktDatepicker extends PktInputElement<Props> implements IPktDatepicker {
|
|
57
84
|
/**
|
|
58
85
|
* Element attributes and properties
|
|
59
86
|
*/
|
|
@@ -79,19 +106,19 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
79
106
|
label: string = 'Datovelger'
|
|
80
107
|
|
|
81
108
|
@property({ type: String })
|
|
82
|
-
dateformat: string =
|
|
109
|
+
dateformat: string = DATEPICKER_DEFAULTS.dateformat
|
|
83
110
|
|
|
84
111
|
@property({ type: Boolean, reflect: true })
|
|
85
|
-
multiple: boolean =
|
|
112
|
+
multiple: boolean = DATEPICKER_DEFAULTS.multiple
|
|
86
113
|
|
|
87
114
|
@property({ type: Number, reflect: true })
|
|
88
115
|
maxlength: number | null = null
|
|
89
116
|
|
|
90
117
|
@property({ type: Boolean, reflect: true })
|
|
91
|
-
range: boolean =
|
|
118
|
+
range: boolean = DATEPICKER_DEFAULTS.range
|
|
92
119
|
|
|
93
120
|
@property({ type: Boolean, attribute: 'show-range-labels' })
|
|
94
|
-
showRangeLabels: boolean =
|
|
121
|
+
showRangeLabels: boolean = DATEPICKER_DEFAULTS.showRangeLabels
|
|
95
122
|
|
|
96
123
|
@property({ type: String, reflect: true })
|
|
97
124
|
min: string | null = null
|
|
@@ -100,10 +127,10 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
100
127
|
max: string | null = null
|
|
101
128
|
|
|
102
129
|
@property({ type: Boolean })
|
|
103
|
-
weeknumbers: boolean =
|
|
130
|
+
weeknumbers: boolean = DATEPICKER_DEFAULTS.weeknumbers
|
|
104
131
|
|
|
105
132
|
@property({ type: Boolean, reflect: true })
|
|
106
|
-
withcontrols: boolean =
|
|
133
|
+
withcontrols: boolean = DATEPICKER_DEFAULTS.withcontrols
|
|
107
134
|
|
|
108
135
|
@property({ converter: converters.csvToArray })
|
|
109
136
|
excludedates: string[] = []
|
|
@@ -118,13 +145,17 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
118
145
|
today: string | null = null
|
|
119
146
|
|
|
120
147
|
@property({ type: Boolean, reflect: true, attribute: 'calendar-open' })
|
|
121
|
-
calendarOpen: boolean =
|
|
148
|
+
calendarOpen: boolean = DATEPICKER_DEFAULTS.calendarOpen
|
|
122
149
|
|
|
123
150
|
@property({ type: String })
|
|
124
151
|
timezone: string = 'Europe/Oslo'
|
|
125
152
|
|
|
126
153
|
@state() inputClasses = {}
|
|
127
154
|
|
|
155
|
+
@state() private toWithoutFrom: string | null = null
|
|
156
|
+
|
|
157
|
+
@state() private editedRangeFields: [string, string] | null = null
|
|
158
|
+
|
|
128
159
|
/**
|
|
129
160
|
* Computed properties
|
|
130
161
|
*/
|
|
@@ -132,6 +163,10 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
132
163
|
return inputTypeUtils.getInputType()
|
|
133
164
|
}
|
|
134
165
|
|
|
166
|
+
get hasCounter(): boolean {
|
|
167
|
+
return datepickerHasCounter(this.counter, this.multiple, this.maxlength)
|
|
168
|
+
}
|
|
169
|
+
|
|
135
170
|
/**
|
|
136
171
|
* Housekeeping / lifecycle methods
|
|
137
172
|
*/
|
|
@@ -141,10 +176,87 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
141
176
|
if (this.timezone && this.timezone !== window.pktTz) {
|
|
142
177
|
window.pktTz = this.timezone
|
|
143
178
|
}
|
|
179
|
+
this.addEventListener('focusin', this.handleFocusIn)
|
|
180
|
+
this.addEventListener('focusout', this.handleFocusOut)
|
|
144
181
|
}
|
|
145
182
|
|
|
146
183
|
disconnectedCallback(): void {
|
|
147
184
|
super.disconnectedCallback()
|
|
185
|
+
this.removeEventListener('focusin', this.handleFocusIn)
|
|
186
|
+
this.removeEventListener('focusout', this.handleFocusOut)
|
|
187
|
+
this.focusTracker.reset()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private focusTracker = createFocusWithinTracker(
|
|
191
|
+
(node) => this.contains(node),
|
|
192
|
+
(type, relatedTarget) => {
|
|
193
|
+
if (type === 'blur') this.dropToWithoutFrom()
|
|
194
|
+
this.dispatchEvent(new FocusEvent(type, { bubbles: true, composed: true, relatedTarget }))
|
|
195
|
+
},
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
private get rangeFieldValues(): string[] {
|
|
199
|
+
return this._value[0] ? this._value : ['', this.toWithoutFrom ?? '']
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private lastCalendarSelected: string[] = []
|
|
203
|
+
|
|
204
|
+
private get calendarSelected(): string[] {
|
|
205
|
+
if (!this.range) return this._value
|
|
206
|
+
const [from, to] = this.editedRangeFields ?? this._value
|
|
207
|
+
const next = rangeCalendarSelection(from, to)
|
|
208
|
+
if (arrayToCsv(next) !== arrayToCsv(this.lastCalendarSelected)) this.lastCalendarSelected = next
|
|
209
|
+
return this.lastCalendarSelected
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private trackRangeFields() {
|
|
213
|
+
this.editedRangeFields = [
|
|
214
|
+
this.currentInputElement?.value ?? '',
|
|
215
|
+
this.currentInputElementTo?.value ?? '',
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private syncRangeFromFields(e: FocusEvent) {
|
|
220
|
+
const fromInput = this.currentInputElement
|
|
221
|
+
const toInput = this.currentInputElementTo
|
|
222
|
+
if (!fromInput || !toInput) return
|
|
223
|
+
const from = fromInput.value
|
|
224
|
+
if (from && toInput.value && from > toInput.value) toInput.value = ''
|
|
225
|
+
const to = toInput.value
|
|
226
|
+
this.toWithoutFrom = from ? null : to || null
|
|
227
|
+
this.editedRangeFields = null
|
|
228
|
+
if (e.target instanceof HTMLInputElement && e.target.value) this.manageValidity(e.target)
|
|
229
|
+
this.value = from ? [from, to].filter(Boolean).join(',') : ''
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private dropToWithoutFrom() {
|
|
233
|
+
const toInput = this.currentInputElementTo
|
|
234
|
+
if (this.range && toInput && !this.currentInputElement?.value) toInput.value = ''
|
|
235
|
+
this.toWithoutFrom = null
|
|
236
|
+
this.editedRangeFields = null
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
protected formResetCallback(): void {
|
|
240
|
+
this.toWithoutFrom = null
|
|
241
|
+
this.editedRangeFields = null
|
|
242
|
+
super.formResetCallback()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
protected setFormValue(value: string | string[]): void {
|
|
246
|
+
super.setFormValue(this.multiple || this.range ? valueToArray(value) : value)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
private handleFocusIn = (e: FocusEvent) => this.focusTracker.focusin(e.relatedTarget)
|
|
250
|
+
|
|
251
|
+
private handleFocusOut = (e: FocusEvent) => this.focusTracker.focusout(e.relatedTarget)
|
|
252
|
+
|
|
253
|
+
private focusField() {
|
|
254
|
+
this.currentInputElement?.focus()
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private get focusIsInPopup(): boolean {
|
|
258
|
+
const popup = this.datepickerPopupRef.value?.popupRef.value
|
|
259
|
+
return !!popup && popup.contains(document.activeElement)
|
|
148
260
|
}
|
|
149
261
|
|
|
150
262
|
onInput(): void {
|
|
@@ -184,7 +296,14 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
184
296
|
this._valueProperty = arrayToCsv(filteredValue)
|
|
185
297
|
|
|
186
298
|
// Én dato er ingen fullført periode. Tom er en fullført endring.
|
|
187
|
-
if (
|
|
299
|
+
if (this.range && filteredValue.length === 1) {
|
|
300
|
+
this.setFormValue(this._valueProperty)
|
|
301
|
+
if (this.hasUpdated && this._valueProperty !== oldValue) {
|
|
302
|
+
this.dispatchEvent(
|
|
303
|
+
new CustomEvent('value-change', { detail: filteredValue, bubbles: true, composed: true }),
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
188
307
|
super.valueChanged(this._valueProperty, oldValue)
|
|
189
308
|
}
|
|
190
309
|
|
|
@@ -213,6 +332,8 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
213
332
|
'excludeweekdays',
|
|
214
333
|
]
|
|
215
334
|
|
|
335
|
+
private static readonly POSITIONED_BY = ['calendarOpen', 'counter', 'multiple', 'maxlength']
|
|
336
|
+
|
|
216
337
|
protected willUpdate(changedProperties: PropertyValues): void {
|
|
217
338
|
super.willUpdate(changedProperties)
|
|
218
339
|
|
|
@@ -230,6 +351,12 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
230
351
|
this.classList.toggle('pkt-datepicker--small', this.inputSize === 'small')
|
|
231
352
|
this.classList.toggle('pkt-datepicker--xsmall', this.inputSize === 'xsmall')
|
|
232
353
|
super.updated(changedProperties)
|
|
354
|
+
if (
|
|
355
|
+
this.calendarOpen &&
|
|
356
|
+
PktDatepicker.POSITIONED_BY.some((prop) => changedProperties.has(prop))
|
|
357
|
+
) {
|
|
358
|
+
this.positionOpenCalendar()
|
|
359
|
+
}
|
|
233
360
|
}
|
|
234
361
|
|
|
235
362
|
/**
|
|
@@ -247,7 +374,6 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
247
374
|
return { value: element } as Ref<HTMLInputElement>
|
|
248
375
|
}
|
|
249
376
|
|
|
250
|
-
calRef: Ref<PktCalendar> = createRef()
|
|
251
377
|
popupRef: Ref<HTMLDivElement> = createRef()
|
|
252
378
|
|
|
253
379
|
// Child component refs
|
|
@@ -311,12 +437,6 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
311
437
|
.strings=${this.strings}
|
|
312
438
|
@toggle-calendar=${(e: CustomEvent) => this.toggleCalendar(e.detail)}
|
|
313
439
|
@input-change=${() => this.onInput()}
|
|
314
|
-
@input-focus=${() => this.onFocus()}
|
|
315
|
-
@input-blur=${(e: CustomEvent) => {
|
|
316
|
-
if (!this.calRef.value?.contains(e.detail.relatedTarget as Node)) {
|
|
317
|
-
this.onBlur()
|
|
318
|
-
}
|
|
319
|
-
}}
|
|
320
440
|
@manage-validity=${(e: CustomEvent) => this.manageValidity(e.detail)}
|
|
321
441
|
@value-change=${(e: CustomEvent) => {
|
|
322
442
|
this.value = e.detail
|
|
@@ -332,7 +452,7 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
332
452
|
renderRangeInput() {
|
|
333
453
|
return html`
|
|
334
454
|
<pkt-datepicker-range
|
|
335
|
-
.value=${this.
|
|
455
|
+
.value=${this.rangeFieldValues}
|
|
336
456
|
.inputType=${this.inputType}
|
|
337
457
|
.id=${this.id}
|
|
338
458
|
.label=${this.label}
|
|
@@ -349,67 +469,12 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
349
469
|
.hasHelptext=${Boolean(this.helptext || this.helptextDropdown || this.hasSlotContent('helptext'))}
|
|
350
470
|
.strings=${this.strings}
|
|
351
471
|
@toggle-calendar=${(e: CustomEvent) => this.toggleCalendar(e.detail)}
|
|
352
|
-
@input-change=${() =>
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (!this.calRef.value?.contains(e.detail.relatedTarget as Node)) {
|
|
356
|
-
this.onBlur()
|
|
357
|
-
}
|
|
358
|
-
}}
|
|
359
|
-
@range-blur=${(e: CustomEvent) => {
|
|
360
|
-
const inputFrom = this.currentInputElement
|
|
361
|
-
const inputTo = this.currentInputElementTo
|
|
362
|
-
|
|
363
|
-
// Update _value with current input values to sync with calendar
|
|
364
|
-
if (inputFrom && inputTo) {
|
|
365
|
-
const fromValue = inputFrom.value
|
|
366
|
-
const toValue = inputTo.value
|
|
367
|
-
|
|
368
|
-
// If from date is after to date, clear the to date
|
|
369
|
-
if (fromValue && toValue && fromValue > toValue) {
|
|
370
|
-
inputTo.value = ''
|
|
371
|
-
this._value = [fromValue]
|
|
372
|
-
this.value = fromValue
|
|
373
|
-
} else {
|
|
374
|
-
const newValues = [fromValue, toValue].filter(Boolean)
|
|
375
|
-
if (
|
|
376
|
-
newValues.length > 0 &&
|
|
377
|
-
(newValues[0] !== this._value[0] || newValues[1] !== this._value[1])
|
|
378
|
-
) {
|
|
379
|
-
this._value = newValues
|
|
380
|
-
this.value = newValues.join(',')
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
dateProcessingUtils.processRangeBlur(
|
|
386
|
-
e.detail.event,
|
|
387
|
-
e.detail.values,
|
|
388
|
-
this.calRef,
|
|
389
|
-
() => this.clearInputValue(),
|
|
390
|
-
(input) => this.manageValidity(input),
|
|
391
|
-
)
|
|
472
|
+
@input-change=${() => {
|
|
473
|
+
this.trackRangeFields()
|
|
474
|
+
this.onInput()
|
|
392
475
|
}}
|
|
476
|
+
@range-blur=${(e: CustomEvent) => this.syncRangeFromFields(e.detail.event)}
|
|
393
477
|
@manage-validity=${(e: CustomEvent) => this.manageValidity(e.detail)}
|
|
394
|
-
@validate-date-input=${(e: CustomEvent) => {
|
|
395
|
-
formUtils.validateDateInput(
|
|
396
|
-
e.detail,
|
|
397
|
-
this.internals,
|
|
398
|
-
this.min,
|
|
399
|
-
this.max,
|
|
400
|
-
this.pktStrings.get('validation'),
|
|
401
|
-
)
|
|
402
|
-
}}
|
|
403
|
-
@handle-date-select=${(e: CustomEvent) => {
|
|
404
|
-
const date = fromISOToDate(e.detail)
|
|
405
|
-
if (date) {
|
|
406
|
-
const formattedDate = formatISODate(date)
|
|
407
|
-
// Only update calendar if the date is different from current values
|
|
408
|
-
if (this._value[0] !== formattedDate && this._value[1] !== formattedDate) {
|
|
409
|
-
this.calRef?.value?.handleDateSelect(date)
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}}
|
|
413
478
|
@input-changed=${() => {
|
|
414
479
|
this.touched = true
|
|
415
480
|
}}
|
|
@@ -438,12 +503,6 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
438
503
|
.strings=${this.strings}
|
|
439
504
|
@toggle-calendar=${(e: CustomEvent) => this.toggleCalendar(e.detail)}
|
|
440
505
|
@input-change=${() => this.onInput()}
|
|
441
|
-
@input-focus=${() => this.onFocus()}
|
|
442
|
-
@input-blur=${(e: CustomEvent) => {
|
|
443
|
-
if (!this.calRef.value?.contains(e.detail.relatedTarget as Node)) {
|
|
444
|
-
this.onBlur()
|
|
445
|
-
}
|
|
446
|
-
}}
|
|
447
506
|
@add-to-selected=${(e: CustomEvent) => this.addToSelected(e.detail)}
|
|
448
507
|
@input-changed=${() => {
|
|
449
508
|
this.touched = true
|
|
@@ -463,7 +522,7 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
463
522
|
?weeknumbers=${this.weeknumbers}
|
|
464
523
|
?withcontrols=${this.withcontrols}
|
|
465
524
|
.maxMultiple=${this.maxlength}
|
|
466
|
-
.selected=${this.
|
|
525
|
+
.selected=${this.calendarSelected}
|
|
467
526
|
.earliest=${this.min}
|
|
468
527
|
.latest=${this.max}
|
|
469
528
|
.excludedates=${Array.isArray(this.excludedates)
|
|
@@ -473,8 +532,18 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
473
532
|
.currentmonth=${this.currentmonth ? parseISODateString(this.currentmonth) : null}
|
|
474
533
|
.today=${this.today}
|
|
475
534
|
@date-selected=${(e: CustomEvent) => {
|
|
476
|
-
|
|
477
|
-
|
|
535
|
+
const selected: string[] = this.range
|
|
536
|
+
? completeRangeWithTo(
|
|
537
|
+
e.detail,
|
|
538
|
+
this._value[0] ? null : this.toWithoutFrom,
|
|
539
|
+
valueToArray(this.excludedates),
|
|
540
|
+
this.excludeweekdays,
|
|
541
|
+
)
|
|
542
|
+
: e.detail
|
|
543
|
+
this.toWithoutFrom = null
|
|
544
|
+
this.editedRangeFields = null
|
|
545
|
+
this.value = dateProcessingUtils.processDateSelection(selected, this.multiple, this.range)
|
|
546
|
+
this._value = selected
|
|
478
547
|
dateProcessingUtils.updateInputValues(
|
|
479
548
|
this.inputRef,
|
|
480
549
|
this.inputRefTo,
|
|
@@ -483,9 +552,11 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
483
552
|
this.multiple,
|
|
484
553
|
(input) => this.manageValidity(input),
|
|
485
554
|
)
|
|
555
|
+
if (!this.multiple && (!this.range || this._value.length === 2)) this.focusField()
|
|
556
|
+
if (selected !== e.detail) this.hideCalendar()
|
|
486
557
|
}}
|
|
487
558
|
@close=${() => {
|
|
488
|
-
this.
|
|
559
|
+
if (this.focusIsInPopup) this.focusField()
|
|
489
560
|
this.hideCalendar()
|
|
490
561
|
}}
|
|
491
562
|
${ref(this.datepickerPopupRef)}
|
|
@@ -510,7 +581,7 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
510
581
|
.strings=${this.strings}
|
|
511
582
|
label="${this.label}"
|
|
512
583
|
forId="${this.id}-input"
|
|
513
|
-
?counter=${this.
|
|
584
|
+
?counter=${this.hasCounter}
|
|
514
585
|
.counterCurrent=${this.value ? this._value.length : 0}
|
|
515
586
|
.counterMaxLength=${this.maxlength}
|
|
516
587
|
?disabled=${this.isDisabled}
|
|
@@ -538,13 +609,8 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
538
609
|
strings=${this.strings}
|
|
539
610
|
id-base=${this.id}
|
|
540
611
|
@date-tag-removed=${(e: CustomEvent) => {
|
|
541
|
-
const popup = this.datepickerPopupRef.value
|
|
542
612
|
const date = fromISOToDate(e.detail)
|
|
543
|
-
if (
|
|
544
|
-
popup.handleDateSelect(date)
|
|
545
|
-
} else {
|
|
546
|
-
this.calRef.value?.handleDateSelect(date)
|
|
547
|
-
}
|
|
613
|
+
if (date) this.datepickerPopupRef.value?.handleDateSelect(date)
|
|
548
614
|
}}
|
|
549
615
|
></pkt-date-tags>`
|
|
550
616
|
: nothing}
|
|
@@ -565,31 +631,29 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
565
631
|
*/
|
|
566
632
|
|
|
567
633
|
handleCalendarPosition() {
|
|
568
|
-
|
|
569
|
-
|
|
634
|
+
positionCalendarPopup(
|
|
635
|
+
this.datepickerPopupRef.value?.popupRef.value ?? null,
|
|
636
|
+
this.currentInputElement ?? null,
|
|
637
|
+
this.hasCounter,
|
|
638
|
+
)
|
|
570
639
|
}
|
|
571
640
|
|
|
572
|
-
|
|
641
|
+
private async positionOpenCalendar() {
|
|
573
642
|
const popup = this.datepickerPopupRef.value
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
return calendarUtils.addToSelected(e, this.calRef, this.min, this.max)
|
|
643
|
+
await popup?.updateComplete
|
|
644
|
+
await (popup?.calendarRef.value as PktCalendar | undefined)?.updateComplete
|
|
645
|
+
if (this.calendarOpen) this.handleCalendarPosition()
|
|
578
646
|
}
|
|
579
647
|
|
|
648
|
+
addToSelected = (e: Event | KeyboardEvent) =>
|
|
649
|
+
this.datepickerPopupRef.value?.addToSelected(e, this.min, this.max)
|
|
650
|
+
|
|
580
651
|
public async showCalendar() {
|
|
581
652
|
const popup = this.datepickerPopupRef.value
|
|
582
653
|
this.calendarOpen = true
|
|
583
|
-
if (popup
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
return
|
|
587
|
-
}
|
|
588
|
-
await sleep(20)
|
|
589
|
-
this.handleCalendarPosition()
|
|
590
|
-
if (isIOS()) {
|
|
591
|
-
this.calRef.value?.focusOnCurrentDate()
|
|
592
|
-
}
|
|
654
|
+
if (!popup) return
|
|
655
|
+
popup.show()
|
|
656
|
+
if (isIOS()) popup.focusOnCurrentDate()
|
|
593
657
|
}
|
|
594
658
|
|
|
595
659
|
public hideCalendar() {
|
|
@@ -4,4 +4,5 @@ import { PktDatepickerRange } from './datepicker-range'
|
|
|
4
4
|
import { PktDatepickerMultiple } from './datepicker-multiple'
|
|
5
5
|
|
|
6
6
|
export { PktDatepicker, PktDatepickerSingle, PktDatepickerRange, PktDatepickerMultiple }
|
|
7
|
+
export type { IPktDatepicker } from './datepicker'
|
|
7
8
|
export default PktDatepicker
|