@oslokommune/punkt-elements 14.5.4 → 15.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.
Files changed (123) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/{accordionitem-DB3tAjIZ.js → accordionitem-BbeS44TD.js} +1 -1
  3. package/dist/{accordionitem-DHYmPA-o.cjs → accordionitem-DUWhTUEI.cjs} +1 -1
  4. package/dist/{alert-DVCenNTM.cjs → alert-B9flMht5.cjs} +1 -1
  5. package/dist/{alert-Cc5FtxHN.js → alert-BpFxQviu.js} +2 -2
  6. package/dist/{button-Ju4zPhVx.cjs → button-BgCKV0zW.cjs} +1 -1
  7. package/dist/{button-DrTXtc-n.js → button-CKgpX5QA.js} +1 -1
  8. package/dist/{calendar-CTx8PD1L.js → calendar-BMarIeVp.js} +332 -325
  9. package/dist/calendar-C6xgAJ7Z.cjs +90 -0
  10. package/dist/{card-DvHL7pNu.cjs → card-DI3KodEc.cjs} +1 -1
  11. package/dist/{card-CTtmPB2n.js → card-h8ekgJRr.js} +2 -2
  12. package/dist/{checkbox-B-0FOdwi.cjs → checkbox-B2t7wfxe.cjs} +1 -1
  13. package/dist/{checkbox-CkAwPK_E.js → checkbox-BJ9pz3kV.js} +1 -1
  14. package/dist/{combobox-DNPfpTjW.js → combobox-BjAvk8Y-.js} +5 -5
  15. package/dist/{combobox-DvL3SKz2.cjs → combobox-HNN7GTzh.cjs} +1 -1
  16. package/dist/{consent-DJW7YEat.cjs → consent-C37tuFwZ.cjs} +1 -1
  17. package/dist/{consent-OdhmtIK-.js → consent-DAk2BJ7I.js} +1 -1
  18. package/dist/datepicker-2bneToiA.cjs +275 -0
  19. package/dist/datepicker-DvcH2QD9.js +1160 -0
  20. package/dist/{helptext-7fyVJK2C.cjs → helptext-BG1P_9j0.cjs} +1 -1
  21. package/dist/{helptext-CfR0SYe9.js → helptext-Cm6FLBVf.js} +1 -1
  22. package/dist/index.d.ts +10 -42
  23. package/dist/input-element-BBv4xjPb.cjs +1 -0
  24. package/dist/{input-element-DVZhYDJ_.js → input-element-CbjYtVou.js} +143 -147
  25. package/dist/{input-wrapper-DVUh5rxv.js → input-wrapper-Bwmva-69.js} +3 -3
  26. package/dist/{input-wrapper-Bta4FZe3.cjs → input-wrapper-CJqmwe3I.cjs} +1 -1
  27. package/dist/{link-40XAFlYS.js → link-BKnT-97D.js} +1 -1
  28. package/dist/{link-CBQ7uKqb.cjs → link-DRPFqqEn.cjs} +1 -1
  29. package/dist/{linkcard-D8hxLedl.cjs → linkcard-02fxYQ2g.cjs} +1 -1
  30. package/dist/{linkcard-Opb42K2k.js → linkcard-C2UENcqo.js} +1 -1
  31. package/dist/{loader-Bv1R6-AA.js → loader-BW-AWQiE.js} +1 -1
  32. package/dist/{loader-Dh_5sihO.cjs → loader-Cj4kUNRE.cjs} +1 -1
  33. package/dist/{messagebox-B9MCodIz.cjs → messagebox-CK0sSRep.cjs} +1 -1
  34. package/dist/{messagebox-DEXCTOrz.js → messagebox-DB8tEXrV.js} +1 -1
  35. package/dist/{modal-Bw61rVrQ.cjs → modal-BzVQSQy2.cjs} +1 -1
  36. package/dist/{modal-B4adxB6X.js → modal-ClYfWW2a.js} +1 -1
  37. package/dist/pkt-accordion.cjs +1 -1
  38. package/dist/pkt-accordion.js +2 -2
  39. package/dist/pkt-alert.cjs +1 -1
  40. package/dist/pkt-alert.js +1 -1
  41. package/dist/pkt-button.cjs +1 -1
  42. package/dist/pkt-button.js +1 -1
  43. package/dist/pkt-calendar.cjs +1 -1
  44. package/dist/pkt-calendar.js +1 -1
  45. package/dist/pkt-card.cjs +1 -1
  46. package/dist/pkt-card.js +1 -1
  47. package/dist/pkt-checkbox.cjs +1 -1
  48. package/dist/pkt-checkbox.js +1 -1
  49. package/dist/pkt-combobox.cjs +1 -1
  50. package/dist/pkt-combobox.js +1 -1
  51. package/dist/pkt-consent.cjs +1 -1
  52. package/dist/pkt-consent.js +1 -1
  53. package/dist/pkt-datepicker.cjs +1 -1
  54. package/dist/pkt-datepicker.js +2 -2
  55. package/dist/pkt-header.cjs +1 -1
  56. package/dist/pkt-header.js +4 -4
  57. package/dist/pkt-helptext.cjs +1 -1
  58. package/dist/pkt-helptext.js +1 -1
  59. package/dist/pkt-index.cjs +1 -1
  60. package/dist/pkt-index.js +22 -22
  61. package/dist/pkt-input-wrapper.cjs +1 -1
  62. package/dist/pkt-input-wrapper.js +1 -1
  63. package/dist/pkt-link.cjs +1 -1
  64. package/dist/pkt-link.js +1 -1
  65. package/dist/pkt-linkcard.cjs +1 -1
  66. package/dist/pkt-linkcard.js +1 -1
  67. package/dist/pkt-loader.cjs +1 -1
  68. package/dist/pkt-loader.js +1 -1
  69. package/dist/pkt-messagebox.cjs +1 -1
  70. package/dist/pkt-messagebox.js +1 -1
  71. package/dist/pkt-modal.cjs +1 -1
  72. package/dist/pkt-modal.js +1 -1
  73. package/dist/{pkt-options-controller-zn5cmMvL.js → pkt-options-controller-BcGywCmf.js} +1 -1
  74. package/dist/{pkt-options-controller-DjBCEHU4.cjs → pkt-options-controller-BnTmkl3g.cjs} +1 -1
  75. package/dist/pkt-radiobutton.cjs +1 -1
  76. package/dist/pkt-radiobutton.js +1 -1
  77. package/dist/pkt-select.cjs +1 -1
  78. package/dist/pkt-select.js +1 -1
  79. package/dist/pkt-slot-controller-D4nKlom5.cjs +1 -0
  80. package/dist/{pkt-slot-controller-BPGj-LC5.js → pkt-slot-controller-D7CrjM52.js} +27 -25
  81. package/dist/pkt-tabs.cjs +1 -1
  82. package/dist/pkt-tabs.js +2 -2
  83. package/dist/pkt-tag.cjs +1 -1
  84. package/dist/pkt-tag.js +1 -1
  85. package/dist/pkt-textarea.cjs +1 -1
  86. package/dist/pkt-textarea.js +1 -1
  87. package/dist/pkt-textinput.cjs +1 -1
  88. package/dist/pkt-textinput.js +1 -1
  89. package/dist/{radiobutton-oA20HijB.js → radiobutton-CvKKNFMd.js} +1 -1
  90. package/dist/{radiobutton-iHuLnuAn.cjs → radiobutton-DWoYQn8H.cjs} +1 -1
  91. package/dist/{select--wvwpJ0_.cjs → select-BQUp88lY.cjs} +1 -1
  92. package/dist/{select-DfsNb_Yi.js → select-CFkxir_l.js} +4 -4
  93. package/dist/{tabitem-CypTmORF.js → tabitem-C8-tZyc_.js} +1 -1
  94. package/dist/{tabitem-CtltSqDK.cjs → tabitem-DaYfUaxw.cjs} +1 -1
  95. package/dist/{tag-Cw3OQqLW.js → tag-DIJMJhyp.js} +1 -1
  96. package/dist/{tag-P9lfQZbM.cjs → tag-h0vD2Na0.cjs} +1 -1
  97. package/dist/{textarea-CM_bj81t.js → textarea-CMuiBUee.js} +3 -3
  98. package/dist/{textarea-DcEKhXia.cjs → textarea-DcCOfNlr.cjs} +1 -1
  99. package/dist/{textinput-AVll6Nh7.js → textinput-D30TCADP.js} +3 -3
  100. package/dist/{textinput-BzuYzKZ6.cjs → textinput-DR3aaHTH.cjs} +1 -1
  101. package/package.json +4 -4
  102. package/src/components/calendar/calendar.core.test.ts +1 -1
  103. package/src/components/calendar/calendar.selection.test.ts +1 -1
  104. package/src/components/calendar/calendar.ts +32 -22
  105. package/src/components/datepicker/datepicker-popup.test.ts +1 -1
  106. package/src/components/datepicker/datepicker-popup.ts +73 -30
  107. package/src/components/datepicker/datepicker-range.ts +5 -1
  108. package/src/components/datepicker/datepicker-types.ts +4 -54
  109. package/src/components/datepicker/datepicker-utils.ts +38 -517
  110. package/src/components/datepicker/datepicker.core.test.ts +12 -10
  111. package/src/components/datepicker/datepicker.selection.test.ts +8 -6
  112. package/src/components/datepicker/datepicker.ts +26 -7
  113. package/src/components/icon/icon.test.ts +8 -8
  114. package/dist/calendar-5Obd0ZT3.cjs +0 -90
  115. package/dist/datepicker-CTCaZuZU.cjs +0 -271
  116. package/dist/datepicker-t0W9fA1e.js +0 -1444
  117. package/dist/input-element-RBQVA8i0.cjs +0 -1
  118. package/dist/pkt-slot-controller-BzddBp7z.cjs +0 -1
  119. package/src/components/calendar/helpers/calendar-grid.ts +0 -93
  120. package/src/components/calendar/helpers/date-validation.ts +0 -86
  121. package/src/components/calendar/helpers/index.ts +0 -49
  122. package/src/components/calendar/helpers/keyboard-navigation.ts +0 -54
  123. package/src/components/calendar/helpers/selection-manager.ts +0 -184
@@ -1,9 +1,10 @@
1
- import { html } from 'lit'
1
+ import { html, nothing, PropertyValues } from 'lit'
2
2
  import { PktElement } from '@/base-elements/element'
3
- import { customElement, property } from 'lit/decorators.js'
3
+ import { customElement, property, state } from 'lit/decorators.js'
4
4
  import { classMap } from 'lit/directives/class-map.js'
5
5
  import { ref, createRef, Ref } from 'lit/directives/ref.js'
6
6
 
7
+ import { formatISODate, newDate } from 'shared-utils/date-utils'
7
8
  import { PktCalendar } from '../calendar/calendar'
8
9
  import { calendarUtils } from './datepicker-utils'
9
10
 
@@ -21,6 +22,9 @@ export class PktDatepickerPopup extends PktElement {
21
22
  @property({ type: Array }) excludedates: string[] = []
22
23
  @property({ type: Array }) excludeweekdays: string[] = []
23
24
  @property({ type: String }) currentmonth: string | null = null
25
+ @property({ type: String }) today: string | null = null
26
+
27
+ @state() private _hasBeenOpened = false
24
28
 
25
29
  popupRef: Ref<HTMLElement> = createRef()
26
30
  calendarRef: Ref<HTMLElement> = createRef()
@@ -28,9 +32,21 @@ export class PktDatepickerPopup extends PktElement {
28
32
  firstUpdated() {
29
33
  // expose calendarRef for external use
30
34
  this.calRef = this.calendarRef
35
+ }
31
36
 
32
- document.addEventListener('keydown', this.handleDocumentKeydown)
33
- document.addEventListener('click', this.handleDocumentClick)
37
+ updated(changedProperties: PropertyValues) {
38
+ super.updated(changedProperties)
39
+
40
+ if (changedProperties.has('open')) {
41
+ if (this.open) {
42
+ this._hasBeenOpened = true
43
+ document.addEventListener('keydown', this.handleDocumentKeydown)
44
+ document.addEventListener('click', this.handleDocumentClick)
45
+ } else {
46
+ document.removeEventListener('click', this.handleDocumentClick)
47
+ document.removeEventListener('keydown', this.handleDocumentKeydown)
48
+ }
49
+ }
34
50
  }
35
51
 
36
52
  disconnectedCallback() {
@@ -85,15 +101,39 @@ export class PktDatepickerPopup extends PktElement {
85
101
  }
86
102
 
87
103
  addToSelected(e: Event, min?: string | null, max?: string | null) {
88
- if (typeof calendarUtils.addToSelected === 'function') {
104
+ const cal = this.calendarRef.value as PktCalendar
105
+ if (cal && typeof calendarUtils.addToSelected === 'function') {
89
106
  return calendarUtils.addToSelected(e, this.calendarRef as any, min, max)
90
107
  }
91
- return undefined
108
+
109
+ // Calendar not rendered yet — handle add directly
110
+ const target = e.target as HTMLInputElement
111
+ if (!target.value) return
112
+
113
+ const minAsDate = min ? newDate(min) : null
114
+ const maxAsDate = max ? newDate(max) : null
115
+ const date = newDate(target.value.split(',')[0])
116
+
117
+ if (date && !isNaN(date.getTime()) && (!minAsDate || date >= minAsDate) && (!maxAsDate || date <= maxAsDate)) {
118
+ this.handleDateSelect(date)
119
+ }
120
+ target.value = ''
92
121
  }
93
122
 
94
123
  handleDateSelect(date: Date) {
95
124
  const cal = this.calendarRef.value as PktCalendar
96
125
  if (cal && typeof cal.handleDateSelect === 'function') return cal.handleDateSelect(date)
126
+
127
+ // Calendar not rendered yet — handle selection toggle directly
128
+ const dateStr = formatISODate(date)
129
+ const index = this.selected.indexOf(dateStr)
130
+ const newSelected = index >= 0
131
+ ? this.selected.filter((d) => d !== dateStr)
132
+ : [...this.selected, dateStr]
133
+ this.selected = newSelected
134
+ this.dispatchEvent(
135
+ new CustomEvent('date-selected', { detail: newSelected, bubbles: true, composed: true }),
136
+ )
97
137
  return undefined
98
138
  }
99
139
 
@@ -107,30 +147,33 @@ export class PktDatepickerPopup extends PktElement {
107
147
  ?hidden=${!this.open}
108
148
  aria-hidden="${!this.open}"
109
149
  >
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>
150
+ ${this.open || this._hasBeenOpened
151
+ ? html`<pkt-calendar
152
+ ${ref(this.calendarRef)}
153
+ ?multiple=${this.multiple}
154
+ ?range=${this.range}
155
+ ?weeknumbers=${this.weeknumbers}
156
+ ?withcontrols=${this.withcontrols}
157
+ .maxMultiple=${this.maxMultiple}
158
+ .selected=${this.selected}
159
+ .earliest=${this.earliest}
160
+ .latest=${this.latest}
161
+ .excludedates=${this.excludedates}
162
+ .excludeweekdays=${this.excludeweekdays}
163
+ .currentmonth=${this.currentmonth}
164
+ .today=${this.today}
165
+ @date-selected=${(e: CustomEvent) => {
166
+ this.selected = e.detail
167
+ this.dispatchEvent(
168
+ new CustomEvent('date-selected', { detail: e.detail, bubbles: true, composed: true }),
169
+ )
170
+ }}
171
+ @close=${() => {
172
+ this.hide()
173
+ this.dispatchEvent(new CustomEvent('close', { bubbles: true, composed: true }))
174
+ }}
175
+ ></pkt-calendar>`
176
+ : nothing}
134
177
  </div>
135
178
  `
136
179
  }
@@ -14,6 +14,9 @@ export class PktDatepickerRange extends PktDatepickerBase {
14
14
  @property({ type: Array })
15
15
  value: string[] = []
16
16
 
17
+ @property({ type: String })
18
+ label: string = ''
19
+
17
20
  @property({ type: Boolean })
18
21
  showRangeLabels: boolean = false
19
22
 
@@ -38,6 +41,7 @@ export class PktDatepickerRange extends PktDatepickerBase {
38
41
  class=${classMap(this.inputClasses)}
39
42
  .type=${this.inputType}
40
43
  id="${this.id}-input"
44
+ aria-label="${this.label} ${this.strings.generic?.from ?? 'Fra'}"
41
45
  .value=${this.value[0] ?? ''}
42
46
  min=${ifDefined(this.min)}
43
47
  max=${ifDefined(this.max)}
@@ -101,7 +105,7 @@ export class PktDatepickerRange extends PktDatepickerBase {
101
105
  class=${classMap(this.inputClasses)}
102
106
  .type=${this.inputType}
103
107
  id="${this.id}-to"
104
- aria-labelledby="${this.id}-to-label"
108
+ aria-label="${this.label} ${this.strings.generic?.to ?? 'Til'}"
105
109
  .value=${this.value[1] ?? ''}
106
110
  min=${ifDefined(this.min)}
107
111
  max=${ifDefined(this.max)}
@@ -1,56 +1,6 @@
1
1
  /**
2
- * Type definitions for the datepicker component family
2
+ * Type definitions for the datepicker component family.
3
+ * Re-exports from shared-types for backward compatibility.
3
4
  */
4
-
5
- /**
6
- * Internationalization strings for the datepicker components
7
- */
8
- export interface IDatepickerStrings {
9
- /** Calendar-related strings */
10
- calendar?: {
11
- /** Alt text for calendar button */
12
- buttonAltText?: string
13
- }
14
- /** Generic UI strings (used in range datepicker) */
15
- generic?: {
16
- /** Label for range start input */
17
- from?: string
18
- /** Label for range end input */
19
- to?: string
20
- }
21
- /** Form validation messages */
22
- forms?: {
23
- messages?: {
24
- /** Error message when date is before minimum */
25
- rangeUnderflow?: string
26
- /** Error message when date is after maximum */
27
- rangeOverflow?: string
28
- /** Error message for invalid date format */
29
- badInput?: string
30
- /** Error message when required field is empty */
31
- valueMissing?: string
32
- }
33
- }
34
- /** Date-related strings */
35
- dates?: {
36
- /** Month label */
37
- month?: string
38
- /** Year label */
39
- year?: string
40
- }
41
- }
42
-
43
- /**
44
- * Default strings for single/multiple datepicker
45
- */
46
- export const defaultSingleStrings: IDatepickerStrings = {
47
- calendar: { buttonAltText: 'Åpne kalender' },
48
- }
49
-
50
- /**
51
- * Default strings for range datepicker
52
- */
53
- export const defaultRangeStrings: IDatepickerStrings = {
54
- calendar: { buttonAltText: 'Åpne kalender' },
55
- generic: { from: 'Fra', to: 'Til' },
56
- }
5
+ export type { IDatepickerStrings } from 'shared-types/datepicker'
6
+ export { defaultSingleStrings, defaultRangeStrings } from 'shared-types/datepicker'