@oslokommune/punkt-elements 19.19.0 → 19.20.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 (184) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/{accordion-Bg4CMrUM.cjs → accordion-5N_ptxrN.cjs} +1 -1
  3. package/dist/{accordion-BHVzR-6Z.js → accordion-C5cu1xXT.js} +5 -5
  4. package/dist/{alert-Dy5N7qK-.cjs → alert-KxCE28nq.cjs} +1 -1
  5. package/dist/{alert-BAaZIR3e.js → alert-UbQzzkXb.js} +5 -5
  6. package/dist/{async-directive-C4LocQwR.js → async-directive-BcS8rfeC.js} +2 -2
  7. package/dist/{async-directive-DpyKp6qv.cjs → async-directive-DCLIOGR8.cjs} +1 -1
  8. package/dist/{backlink-BnWruRuj.cjs → backlink-CqRcFURx.cjs} +1 -1
  9. package/dist/{backlink-Dlkyj0ns.js → backlink-bbYpIZJI.js} +3 -3
  10. package/dist/{breadcrumbs-CyWtnx2B.cjs → breadcrumbs-C_JR4ZI_.cjs} +1 -1
  11. package/dist/{breadcrumbs-Bfv8W2CF.js → breadcrumbs-D7gddV5F.js} +2 -2
  12. package/dist/{button-CF9k3ARf.js → button-BJ6QLwxJ.js} +5 -5
  13. package/dist/{button-BBFI3FuT.cjs → button-pFlrTF2P.cjs} +1 -1
  14. package/dist/{calendar-BX3n3vhs.js → calendar-CYsQEfZn.js} +3 -3
  15. package/dist/{calendar-Dds9KFiE.cjs → calendar-Fk5ubNGR.cjs} +1 -1
  16. package/dist/{card-Ddu0sQ0f.js → card-CKu696QC.js} +6 -6
  17. package/dist/{card-mi3VKIoy.cjs → card-Da0JkVcv.cjs} +1 -1
  18. package/dist/{checkbox-D9-KugOh.js → checkbox-BLmQSdWB.js} +4 -4
  19. package/dist/{checkbox-B8foyiOW.cjs → checkbox-PAtsn1TO.cjs} +1 -1
  20. package/dist/{checkbox-group-BlBgrzKG.cjs → checkbox-group-B9TtWVpG.cjs} +1 -1
  21. package/dist/{checkbox-group-Dz1ypmbU.js → checkbox-group-DFKzbaHC.js} +3 -3
  22. package/dist/{class-map-BkEYw5uE.js → class-map-BDwVSgLb.js} +1 -1
  23. package/dist/{class-map-Bh6toDeV.cjs → class-map-C82GtM1w.cjs} +1 -1
  24. package/dist/{combobox-DLDvyuDh.cjs → combobox-CJAmzQFD.cjs} +1 -1
  25. package/dist/{combobox-BAkblu9M.js → combobox-KnYdXXRm.js} +12 -12
  26. package/dist/components/progressbar/progressbar.d.ts +4 -18
  27. package/dist/components/textinput/index.d.ts +1 -0
  28. package/dist/components/textinput/textinput.d.ts +22 -1
  29. package/dist/{consent-DNHRe0zV.cjs → consent-BjWx64Gv.cjs} +1 -1
  30. package/dist/{consent-BTw6uqFf.js → consent-CeJKY2EB.js} +2 -2
  31. package/dist/{datepicker-9dmdHweu.js → datepicker-Cco0rRLa.js} +11 -11
  32. package/dist/{datepicker-C7F1Yc5N.cjs → datepicker-IMxHS-ex.cjs} +1 -1
  33. package/dist/{directive-helpers-BAinC437.js → directive-helpers-BoDzpPID.js} +1 -1
  34. package/dist/{directive-helpers-Bv70GjQh.cjs → directive-helpers-r7akb6wX.cjs} +1 -1
  35. package/dist/{element-C6WTyJFE.cjs → element-CEarCnHH.cjs} +1 -1
  36. package/dist/{element-ckeMVgMz.js → element-DLgZkx5L.js} +1 -0
  37. package/dist/{element-with-slot-B0Vp_OuR.cjs → element-with-slot-CeKuRE3_.cjs} +1 -1
  38. package/dist/{element-with-slot-Dp2Gzv-Q.js → element-with-slot-mG-h7Sjw.js} +2 -2
  39. package/dist/{fileupload-CEwnpxZj.js → fileupload-BrSWPUcy.js} +8 -8
  40. package/dist/{fileupload-M66Pd-QJ.cjs → fileupload-CjqIhSJ1.cjs} +1 -1
  41. package/dist/{footer-HFL2sjAY.cjs → footer-BJCxJUW9.cjs} +1 -1
  42. package/dist/{footer-DZ4aA6fj.js → footer-DQq09VjI.js} +4 -4
  43. package/dist/{header-Cptdf4fW.js → header-C_BUBeOQ.js} +11 -11
  44. package/dist/{header-Cj08flhl.cjs → header-_KjqW2oJ.cjs} +1 -1
  45. package/dist/{header-menu-DxOSBiTJ.js → header-menu-BV0XlRez.js} +4 -4
  46. package/dist/{header-menu-De2DNAXd.cjs → header-menu-BiW5cNun.cjs} +1 -1
  47. package/dist/{heading-B1Ey3XzB.js → heading-CMZmPEL9.js} +2 -2
  48. package/dist/{heading--hGRDNX9.cjs → heading-DAkjw2Am.cjs} +1 -1
  49. package/dist/{helptext-BbrFE48Y.cjs → helptext-B4h3Xlqa.cjs} +1 -1
  50. package/dist/{helptext-BVYv8Lm9.js → helptext-CL1vxEaL.js} +4 -4
  51. package/dist/{icon-CrG6o7ZE.cjs → icon-B3YGHHa7.cjs} +1 -1
  52. package/dist/{icon-CUU42bZ0.js → icon-C82IxnSO.js} +1 -1
  53. package/dist/if-defined-Ci4ZQsgL.cjs +1 -0
  54. package/dist/{if-defined-D18nY_K_.js → if-defined-DiYi2v_Q.js} +1 -1
  55. package/dist/{input-element-D82laWtR.cjs → input-element-2LHxo0em.cjs} +1 -1
  56. package/dist/{input-element-DczlJQb1.js → input-element-De40zUox.js} +2 -2
  57. package/dist/{input-wrapper-QzdntWJX.cjs → input-wrapper-BNu6kOOn.cjs} +1 -1
  58. package/dist/{input-wrapper-CHwWQgZP.js → input-wrapper-DowJHbGF.js} +6 -6
  59. package/dist/{link-BU6t5Tt9.js → link-D9kjggXZ.js} +4 -4
  60. package/dist/{link-a1ZK4J1j.cjs → link-DqPFlWxz.cjs} +1 -1
  61. package/dist/{linkcard-DM0CQbwD.js → linkcard-BEmG-2lN.js} +4 -4
  62. package/dist/{linkcard-Cu4Rh71U.cjs → linkcard-BMJvjo7R.cjs} +1 -1
  63. package/dist/{listbox-DFd-1faX.js → listbox-DAvIBH4P.js} +4 -4
  64. package/dist/{listbox-BbdUu-IV.cjs → listbox-HrH4JonS.cjs} +1 -1
  65. package/dist/{loader-DwGMavG7.cjs → loader-C4fbS8vr.cjs} +1 -1
  66. package/dist/{loader-Y8V3Q82X.js → loader-lDVe6rUf.js} +4 -4
  67. package/dist/{messagebox-wJcXW5hI.js → messagebox-C8dsqW20.js} +4 -4
  68. package/dist/{messagebox-DR-s6tyr.cjs → messagebox-DFaDuvHQ.cjs} +1 -1
  69. package/dist/{modal-BafCTC4M.js → modal-D389hSbe.js} +6 -6
  70. package/dist/{modal-C5AiVm5g.cjs → modal-EgQREcb8.cjs} +1 -1
  71. package/dist/{option-group-element-ZNyUoLcm.js → option-group-element-CB0Qqev_.js} +3 -3
  72. package/dist/{option-group-element-CWjgrFwS.cjs → option-group-element-DhYJmGgW.cjs} +1 -1
  73. package/dist/pkt-accordion.cjs +1 -1
  74. package/dist/pkt-accordion.js +1 -1
  75. package/dist/pkt-alert.cjs +1 -1
  76. package/dist/pkt-alert.js +1 -1
  77. package/dist/pkt-backlink.cjs +1 -1
  78. package/dist/pkt-backlink.js +1 -1
  79. package/dist/pkt-breadcrumbs.cjs +1 -1
  80. package/dist/pkt-breadcrumbs.js +1 -1
  81. package/dist/pkt-button.cjs +1 -1
  82. package/dist/pkt-button.js +1 -1
  83. package/dist/pkt-calendar.cjs +1 -1
  84. package/dist/pkt-calendar.js +1 -1
  85. package/dist/pkt-card.cjs +1 -1
  86. package/dist/pkt-card.js +1 -1
  87. package/dist/pkt-checkbox-group.cjs +1 -1
  88. package/dist/pkt-checkbox-group.js +1 -1
  89. package/dist/pkt-checkbox.cjs +1 -1
  90. package/dist/pkt-checkbox.js +1 -1
  91. package/dist/pkt-combobox.cjs +1 -1
  92. package/dist/pkt-combobox.js +1 -1
  93. package/dist/pkt-consent.cjs +1 -1
  94. package/dist/pkt-consent.js +1 -1
  95. package/dist/pkt-datepicker.cjs +1 -1
  96. package/dist/pkt-datepicker.js +1 -1
  97. package/dist/pkt-fileupload.cjs +1 -1
  98. package/dist/pkt-fileupload.js +1 -1
  99. package/dist/pkt-footer.cjs +1 -1
  100. package/dist/pkt-footer.js +1 -1
  101. package/dist/pkt-header-menu.cjs +1 -1
  102. package/dist/pkt-header-menu.js +1 -1
  103. package/dist/pkt-header.cjs +1 -1
  104. package/dist/pkt-header.js +1 -1
  105. package/dist/pkt-heading.cjs +1 -1
  106. package/dist/pkt-heading.js +1 -1
  107. package/dist/pkt-helptext.cjs +1 -1
  108. package/dist/pkt-helptext.js +1 -1
  109. package/dist/pkt-icon.cjs +1 -1
  110. package/dist/pkt-icon.js +1 -1
  111. package/dist/pkt-index.cjs +1 -1
  112. package/dist/pkt-index.js +37 -37
  113. package/dist/pkt-input-wrapper.cjs +1 -1
  114. package/dist/pkt-input-wrapper.js +1 -1
  115. package/dist/pkt-link.cjs +1 -1
  116. package/dist/pkt-link.js +1 -1
  117. package/dist/pkt-linkcard.cjs +1 -1
  118. package/dist/pkt-linkcard.js +1 -1
  119. package/dist/pkt-listbox.cjs +1 -1
  120. package/dist/pkt-listbox.js +1 -1
  121. package/dist/pkt-loader.cjs +1 -1
  122. package/dist/pkt-loader.js +1 -1
  123. package/dist/pkt-messagebox.cjs +1 -1
  124. package/dist/pkt-messagebox.js +1 -1
  125. package/dist/pkt-modal.cjs +1 -1
  126. package/dist/pkt-modal.js +1 -1
  127. package/dist/{pkt-options-controller-C193xcN4.cjs → pkt-options-controller-9zoH1OBW.cjs} +1 -1
  128. package/dist/{pkt-options-controller-CH8U6zlw.js → pkt-options-controller-CzvBlEPD.js} +1 -1
  129. package/dist/pkt-progressbar.cjs +1 -1
  130. package/dist/pkt-progressbar.js +1 -1
  131. package/dist/pkt-radio-group.cjs +1 -1
  132. package/dist/pkt-radio-group.js +1 -1
  133. package/dist/pkt-radiobutton.cjs +1 -1
  134. package/dist/pkt-radiobutton.js +1 -1
  135. package/dist/pkt-searchinput.cjs +1 -1
  136. package/dist/pkt-searchinput.js +1 -1
  137. package/dist/pkt-select.cjs +1 -1
  138. package/dist/pkt-select.js +1 -1
  139. package/dist/pkt-tabs.cjs +1 -1
  140. package/dist/pkt-tabs.js +1 -1
  141. package/dist/pkt-tag.cjs +1 -1
  142. package/dist/pkt-tag.js +1 -1
  143. package/dist/pkt-textarea.cjs +1 -1
  144. package/dist/pkt-textarea.js +1 -1
  145. package/dist/pkt-textinput.cjs +1 -1
  146. package/dist/pkt-textinput.js +1 -1
  147. package/dist/pkt-timepicker.cjs +1 -1
  148. package/dist/pkt-timepicker.js +1 -1
  149. package/dist/progressbar-BdqIhC1Z.cjs +30 -0
  150. package/dist/{progressbar-BukfOcRk.js → progressbar-CfCc2zhp.js} +50 -37
  151. package/dist/{radio-group-Bg6ODpT3.js → radio-group-CSs8YnEO.js} +3 -3
  152. package/dist/{radio-group-bpIEEMdL.cjs → radio-group-DRNGFfUh.cjs} +1 -1
  153. package/dist/{radiobutton-DMvVv81Y.js → radiobutton-BN67oAvC.js} +4 -4
  154. package/dist/{radiobutton-IcDc6ze2.cjs → radiobutton-Be66H6On.cjs} +1 -1
  155. package/dist/{ref-CB7e9nMY.cjs → ref-B6p6mQkO.cjs} +1 -1
  156. package/dist/{ref-D4OwQYdf.js → ref-BAegS9BR.js} +2 -2
  157. package/dist/{repeat-CnnigVcj.cjs → repeat-CjvNrcUr.cjs} +1 -1
  158. package/dist/{repeat-BGbBqnfz.js → repeat-Cy1M16Di.js} +2 -2
  159. package/dist/{searchinput-BV2C1VbN.js → searchinput-B26-Xp00.js} +4 -4
  160. package/dist/{searchinput-DqD_iLxV.cjs → searchinput-Trn6uU2J.cjs} +1 -1
  161. package/dist/{select-DKBfPgJB.js → select-DZftfjQt.js} +7 -7
  162. package/dist/{select-CHqM6kI-.cjs → select-o6iuy9hC.cjs} +1 -1
  163. package/dist/shared-strings/nb.d.ts +3 -0
  164. package/dist/shared-types/index.d.ts +4 -1
  165. package/dist/shared-types/progressbar.d.ts +82 -5
  166. package/dist/shared-types/textinput.d.ts +82 -0
  167. package/dist/{tabs-B2RjklQl.js → tabs-Bu9PP33-.js} +5 -5
  168. package/dist/{tabs-BcnYrmjU.cjs → tabs-gRjrFqeG.cjs} +1 -1
  169. package/dist/{tag-DrFK8Wq3.cjs → tag-BgHEzLM3.cjs} +1 -1
  170. package/dist/{tag-BOTH9kMz.js → tag-CtdOrK18.js} +5 -5
  171. package/dist/{textarea-B5OfR-QI.cjs → textarea-Cc2aQLbm.cjs} +1 -1
  172. package/dist/{textarea-Du1Z9JUu.js → textarea-DP7GVL2c.js} +9 -9
  173. package/dist/{textinput-75MKBqas.cjs → textinput-B6FPNOJB.cjs} +2 -2
  174. package/dist/{textinput-D_V3b327.js → textinput-Dhwotaxv.js} +30 -15
  175. package/dist/{timepicker-RxsG0mCF.cjs → timepicker-Ce9hXP0B.cjs} +1 -1
  176. package/dist/{timepicker-DVqTAxt0.js → timepicker-DxwQ7-Bl.js} +8 -8
  177. package/package.json +2 -2
  178. package/src/components/progressbar/progressbar.test.ts +47 -5
  179. package/src/components/progressbar/progressbar.ts +49 -53
  180. package/src/components/textinput/index.ts +1 -0
  181. package/src/components/textinput/textinput.test.ts +1 -1
  182. package/src/components/textinput/textinput.ts +46 -4
  183. package/dist/if-defined-CiML3MTM.cjs +0 -1
  184. package/dist/progressbar-YfHSPmqI.cjs +0 -31
@@ -32,8 +32,11 @@ describe('PktProgressbar', () => {
32
32
  })
33
33
 
34
34
  test('keeps the id on the host element', async () => {
35
- document.body.innerHTML = '<pkt-progressbar id="min-framdrift" title="Framdrift"></pkt-progressbar>'
36
- const progressbar = document.querySelector('pkt-progressbar') as CustomElementFor<'pkt-progressbar'>
35
+ document.body.innerHTML =
36
+ '<pkt-progressbar id="min-framdrift" title="Framdrift"></pkt-progressbar>'
37
+ const progressbar = document.querySelector(
38
+ 'pkt-progressbar',
39
+ ) as CustomElementFor<'pkt-progressbar'>
37
40
  await progressbar.updateComplete
38
41
 
39
42
  expect(document.getElementById('min-framdrift')).toBe(progressbar)
@@ -57,7 +60,9 @@ describe('PktProgressbar', () => {
57
60
  const { progressbar } = await createProgressbarTest({ valueCurrent: 50 })
58
61
 
59
62
  expect(progressbar.valueCurrent).toBe(50)
60
- expect(progressbar.querySelector('.pkt-progressbar')?.getAttribute('role')).toBe('progressbar')
63
+ expect(progressbar.querySelector('.pkt-progressbar')?.getAttribute('role')).toBe(
64
+ 'progressbar',
65
+ )
61
66
  })
62
67
  })
63
68
 
@@ -134,6 +139,39 @@ describe('PktProgressbar', () => {
134
139
  expect(statusElement?.textContent?.trim()).toContain('25 av 50')
135
140
  })
136
141
 
142
+ test('shows fraction relative to valueMin', async () => {
143
+ const { progressbar } = await createProgressbarTest({
144
+ valueCurrent: 25,
145
+ valueMin: 20,
146
+ valueMax: 30,
147
+ statusType: 'fraction',
148
+ })
149
+
150
+ const bar = progressbar.querySelector('.pkt-progressbar')
151
+ const barContainer = progressbar.querySelector<HTMLElement>('.pkt-progressbar__container')
152
+ expect(progressbar.querySelector('.pkt-progressbar__status')?.textContent?.trim()).toBe(
153
+ '5 av 10',
154
+ )
155
+ expect(bar?.getAttribute('aria-valuetext')).toBe('5 av 10')
156
+ expect(barContainer?.style.getPropertyValue('--pkt-progress-width')).toBe('50%')
157
+ })
158
+
159
+ test('uses the same bar width for fraction and percentage', async () => {
160
+ const widths: string[] = []
161
+ for (const statusType of ['fraction', 'percentage'] as const) {
162
+ const { progressbar } = await createProgressbarTest({
163
+ valueCurrent: 10,
164
+ valueMin: 1,
165
+ valueMax: 10,
166
+ statusType,
167
+ })
168
+ const barContainer = progressbar.querySelector<HTMLElement>('.pkt-progressbar__container')
169
+ widths.push(barContainer?.style.getPropertyValue('--pkt-progress-width') ?? '')
170
+ document.body.innerHTML = ''
171
+ }
172
+ expect(widths).toEqual(['100%', '100%'])
173
+ })
174
+
137
175
  test('hides status when statusType is none', async () => {
138
176
  const { progressbar } = await createProgressbarTest({
139
177
  valueCurrent: 50,
@@ -182,7 +220,9 @@ describe('PktProgressbar', () => {
182
220
  progressbar.valueCurrent = 80
183
221
  await progressbar.updateComplete
184
222
 
185
- expect(progressbar.querySelector('.pkt-progressbar')?.getAttribute('aria-valuenow')).toBe('80')
223
+ expect(progressbar.querySelector('.pkt-progressbar')?.getAttribute('aria-valuenow')).toBe(
224
+ '80',
225
+ )
186
226
  })
187
227
  })
188
228
 
@@ -190,7 +230,9 @@ describe('PktProgressbar', () => {
190
230
  test('uses progressbar role by default', async () => {
191
231
  const { progressbar } = await createProgressbarTest()
192
232
 
193
- expect(progressbar.querySelector('.pkt-progressbar')?.getAttribute('role')).toBe('progressbar')
233
+ expect(progressbar.querySelector('.pkt-progressbar')?.getAttribute('role')).toBe(
234
+ 'progressbar',
235
+ )
194
236
  expect(progressbar.hasAttribute('role')).toBe(false)
195
237
  })
196
238
 
@@ -6,64 +6,58 @@ import { PktElement } from '@/base-elements/element'
6
6
  import { Ref, createRef, ref } from 'lit/directives/ref.js'
7
7
  import { styleMap } from 'lit/directives/style-map.js'
8
8
  import { uuidish } from 'shared-utils/utils'
9
+ import { formatString } from 'shared-strings'
10
+ import {
11
+ PROGRESSBAR_DEFAULTS,
12
+ type IPktProgressbarBase,
13
+ type TAriaLive,
14
+ type TProgressbarRole,
15
+ type TProgressbarSkin,
16
+ type TProgressbarStatusPlacement,
17
+ type TProgressbarStatusType,
18
+ type TProgressbarTitlePosition,
19
+ } from 'shared-types'
9
20
 
10
- import '@/components/icon'
11
- import type {
12
- TAriaLive,
21
+ export type {
13
22
  TProgressbarRole,
14
23
  TProgressbarSkin,
15
24
  TProgressbarStatusPlacement,
16
25
  TProgressbarStatusType,
17
26
  TProgressbarTitlePosition,
18
- } from 'shared-types'
19
-
20
- export type { TProgressbarRole, TProgressbarSkin, TProgressbarStatusPlacement, TProgressbarStatusType, TProgressbarTitlePosition }
27
+ }
21
28
 
22
- export interface IPktProgressbar {
23
- ariaLabel?: string | null
24
- ariaLabelledby?: string | null
29
+ export interface IPktProgressbar extends Omit<IPktProgressbarBase, 'ariaLive' | 'id'> {
25
30
  ariaLive?: TAriaLive | null
26
- ariaValueText?: string | null
27
31
  id?: string | null
28
- role?: TProgressbarRole
29
- skin?: TProgressbarSkin
30
- statusPlacement?: TProgressbarStatusPlacement
31
- statusType?: TProgressbarStatusType
32
- title?: string | null
33
- titlePosition?: TProgressbarTitlePosition
34
- valueCurrent: number
35
- valueMax?: number
36
- valueMin?: number
37
32
  }
38
33
 
39
- export class PktProgressbar extends PktElement implements IPktProgressbar {
40
- constructor() {
41
- super()
42
- }
34
+ export class PktProgressbar extends PktElement<IPktProgressbar> implements IPktProgressbar {
43
35
  // Public properties
44
36
  @property({ type: String }) ariaLabel: string | null = null
45
37
  @property({ type: String, reflect: true }) ariaLabelledby: string | null = null
46
38
  @property({ type: String, reflect: true }) ariaValueText: string | null = null
47
- @property({ type: String }) ariaLive: TAriaLive = 'polite'
39
+ @property({ type: String }) ariaLive: TAriaLive = PROGRESSBAR_DEFAULTS.ariaLive
48
40
  @property({ type: String, reflect: true }) id: string = uuidish()
49
- @property({ type: String }) role: TProgressbarRole = 'progressbar'
50
- @property({ type: String }) skin: TProgressbarSkin = 'dark-blue'
51
- @property({ type: String }) statusPlacement: TProgressbarStatusPlacement = 'following'
52
- @property({ type: String }) statusType: TProgressbarStatusType = 'none'
41
+ @property({ type: String }) role: TProgressbarRole = PROGRESSBAR_DEFAULTS.role
42
+ @property({ type: String }) skin: TProgressbarSkin = PROGRESSBAR_DEFAULTS.skin
43
+ @property({ type: String }) statusPlacement: TProgressbarStatusPlacement =
44
+ PROGRESSBAR_DEFAULTS.statusPlacement
45
+ @property({ type: String }) statusType: TProgressbarStatusType = PROGRESSBAR_DEFAULTS.statusType
53
46
  @property({ type: String, reflect: true }) title = ''
54
- @property({ type: String }) titlePosition: TProgressbarTitlePosition = 'left'
55
- @property({ type: Number, reflect: true }) valueCurrent = 0
56
- @property({ type: Number }) valueMax = 100
57
- @property({ type: Number }) valueMin = 0
47
+ @property({ type: String }) titlePosition: TProgressbarTitlePosition =
48
+ PROGRESSBAR_DEFAULTS.titlePosition
49
+ @property({ type: Number, reflect: true }) valueCurrent: number =
50
+ PROGRESSBAR_DEFAULTS.valueCurrent
51
+ @property({ type: Number }) valueMax: number = PROGRESSBAR_DEFAULTS.valueMax
52
+ @property({ type: Number }) valueMin: number = PROGRESSBAR_DEFAULTS.valueMin
58
53
 
59
54
  // State
60
55
  private labelWidth = 0
61
56
  @state() private progressbarId: string = this.id
62
- @state() private resolvedRole: TProgressbarRole = 'progressbar'
57
+ @state() private resolvedRole: TProgressbarRole = PROGRESSBAR_DEFAULTS.role
63
58
 
64
59
  // Private refs
65
60
  private labelRef: Ref<HTMLSpanElement> = createRef()
66
- private progressBarRef: Ref<HTMLDivElement> = createRef()
67
61
  private containerRef: Ref<HTMLDivElement> = createRef()
68
62
 
69
63
  protected willUpdate(changedProperties: Map<string | number | symbol, unknown>) {
@@ -97,17 +91,17 @@ export class PktProgressbar extends PktElement implements IPktProgressbar {
97
91
  render() {
98
92
  const hasStatus = this.statusType !== 'none'
99
93
  const totalSteps = this.valueMax - this.valueMin
100
- const percentageOfSteps = (this.valueCurrent / totalSteps) * 100
101
- const currentPercentage =
102
- this.statusType === 'fraction'
103
- ? Math.round(percentageOfSteps)
104
- : Math.round(((this.valueCurrent - this.valueMin) / (this.valueMax - this.valueMin)) * 100)
94
+ const currentStep = this.valueCurrent - this.valueMin
95
+ const currentPercentage = Math.round((currentStep / totalSteps) * 100)
105
96
 
106
- const formattedTitle = `${this.valueCurrent} av ${totalSteps}`
97
+ const formattedTitle = formatString(this.pktStrings.get('progressbar').fraction, {
98
+ current: currentStep,
99
+ total: totalSteps,
100
+ })
107
101
 
108
102
  const computedAriaValueText =
109
103
  this.statusType === 'fraction' && !this.ariaValueText
110
- ? `${this.valueCurrent} av ${this.valueMax - this.valueMin}`
104
+ ? formattedTitle
111
105
  : this.ariaValueText || ''
112
106
  const computedAriaLabelledby = this.ariaLabel
113
107
  ? undefined
@@ -132,7 +126,6 @@ export class PktProgressbar extends PktElement implements IPktProgressbar {
132
126
  })
133
127
 
134
128
  return html`<div
135
- ${ref(this.progressBarRef)}
136
129
  role=${this.resolvedRole}
137
130
  aria-live=${ifDefined(this.ariaLive || undefined)}
138
131
  aria-atomic="true"
@@ -152,25 +145,28 @@ export class PktProgressbar extends PktElement implements IPktProgressbar {
152
145
  '--pkt-progress-width': `${currentPercentage}%`,
153
146
  })}
154
147
  >
155
- ${this.title
156
- ? html`<p id=${`${this.progressbarId}-title`} class=${titleClasses}>${this.title}</p>`
157
- : nothing}
148
+ ${
149
+ this.title
150
+ ? html`<p id=${`${this.progressbarId}-title`} class=${titleClasses}>${this.title}</p>`
151
+ : nothing
152
+ }
158
153
 
159
154
  <div class="pkt-progressbar__bar-wrapper">
160
155
  <div class=${barClasses}></div>
161
156
  </div>
162
157
 
163
- ${hasStatus
164
- ? html`<div class=${statusClasses}>
165
- <span class=${placementClasses} ${ref(this.labelRef)}>
166
- ${this.statusType === 'percentage' ? `${currentPercentage}%` : formattedTitle}
167
- </span>
168
- </div>`
169
- : nothing}
158
+ ${
159
+ hasStatus
160
+ ? html`<div class=${statusClasses}>
161
+ <span class=${placementClasses} ${ref(this.labelRef)}>
162
+ ${this.statusType === 'percentage' ? `${currentPercentage}%` : formattedTitle}
163
+ </span>
164
+ </div>`
165
+ : nothing
166
+ }
170
167
  </div>
171
168
  </div>`
172
169
  }
173
-
174
170
  }
175
171
 
176
172
  export default PktProgressbar
@@ -1,4 +1,5 @@
1
1
  import { PktTextinput } from './textinput'
2
2
 
3
3
  export { PktTextinput }
4
+ export type { IPktTextinput } from './textinput'
4
5
  export default PktTextinput
@@ -67,7 +67,7 @@ describe('PktTextinput', () => {
67
67
  const { textinput } = await createTextinputTest()
68
68
  expect(textinput.type).toBe('text')
69
69
  expect(textinput.value).toBe('')
70
- expect(textinput.autocomplete).toBe(null) // Property defaults to null, template sets 'off'
70
+ expect(textinput.autocomplete).toBe('off')
71
71
  })
72
72
 
73
73
  test('renders input element', async () => {
@@ -10,6 +10,7 @@ import { forwardSlots } from '@/directives/slot-content'
10
10
  import '@/components/input-wrapper'
11
11
  import '@/components/icon'
12
12
  import { describedByIds } from 'shared-utils/forms/described-by'
13
+ import { TEXTINPUT_DEFAULTS, type Booleanish, type IPktTextinputBase } from 'shared-types'
13
14
 
14
15
  type Props = ElementProps<
15
16
  PktTextinput,
@@ -23,17 +24,58 @@ type Props = ElementProps<
23
24
  | 'omitSearchIcon'
24
25
  >
25
26
 
26
- export class PktTextinput extends PktInputElement<Props> {
27
+ export interface IPktTextinput extends Omit<
28
+ IPktTextinputBase,
29
+ | 'form'
30
+ | 'label'
31
+ | 'placeholder'
32
+ | 'size'
33
+ | 'prefix'
34
+ | 'suffix'
35
+ | 'iconNameRight'
36
+ | 'min'
37
+ | 'max'
38
+ | 'minLength'
39
+ | 'maxLength'
40
+ | 'step'
41
+ | 'readOnly'
42
+ | 'autoComplete'
43
+ | 'ariaDescribedby'
44
+ | 'ariaLabelledby'
45
+ | 'helptextDropdownButton'
46
+ | 'useWrapper'
47
+ > {
48
+ label?: string | null
49
+ placeholder?: string | null
50
+ size?: number | null
51
+ prefix?: string | null
52
+ suffix?: string | null
53
+ iconNameRight?: string | null
54
+ min?: string | number | null
55
+ max?: string | number | null
56
+ minlength?: number | null
57
+ maxlength?: number | null
58
+ step?: number | null
59
+ readonly?: boolean
60
+ autocomplete?: string | null
61
+ ariaDescribedby?: string | null
62
+ ariaLabelledby?: string | null
63
+ /** @deprecated Bruk `strings={{ forms: { readMore: '…' } }}` eller `setPktStrings()`. */
64
+ helptextDropdownButton?: string | null
65
+ useWrapper?: Booleanish
66
+ }
67
+
68
+ export class PktTextinput extends PktInputElement<Props> implements IPktTextinput {
27
69
  inputRef: Ref<HTMLTextAreaElement> = createRef()
28
70
 
29
71
  @property({ type: String, reflect: true }) value: string = ''
30
- @property({ type: String }) type: string = 'text'
72
+ @property({ type: String }) type: string = TEXTINPUT_DEFAULTS.type
31
73
  @property({ type: Number }) size: number | null = null
32
- @property({ type: String }) autocomplete: string | null = null
74
+ @property({ type: String }) autocomplete: string | null = TEXTINPUT_DEFAULTS.autoComplete
33
75
  @property({ type: String }) iconNameRight: string | null = null
34
76
  @property({ type: String }) prefix: string | null = null
35
77
  @property({ type: String }) suffix: string | null = null
36
- @property({ type: Boolean }) omitSearchIcon: boolean = false
78
+ @property({ type: Boolean }) omitSearchIcon: boolean = TEXTINPUT_DEFAULTS.omitSearchIcon
37
79
 
38
80
  @state() counterCurrent = 0
39
81
 
@@ -1 +0,0 @@
1
- const e=require("./element-C6WTyJFE.cjs");var t=t=>t??e.h;Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return t}});
@@ -1,31 +0,0 @@
1
- const e=require("./element-C6WTyJFE.cjs"),t=require("./class-map-Bh6toDeV.cjs");require("./icon-CrG6o7ZE.cjs");const n=require("./if-defined-CiML3MTM.cjs"),r=require("./ref-CB7e9nMY.cjs"),i=require("./utils-63cRpWut.cjs");var a=`important`,o=` !`+a,s=e.f(class extends e.p{constructor(t){if(super(t),t.type!==e.m.ATTRIBUTE||t.name!==`style`||t.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(e){return Object.keys(e).reduce((t,n)=>{let r=e[n];return r==null?t:t+`${n=n.includes(`-`)?n:n.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,`-$&`).toLowerCase()}:${r};`},``)}update(t,[n]){let{style:r}=t.element;if(this.ft===void 0)return this.ft=new Set(Object.keys(n)),this.render(n);for(let e of this.ft)n[e]??(this.ft.delete(e),e.includes(`-`)?r.removeProperty(e):r[e]=null);for(let e in n){let t=n[e];if(t!=null){this.ft.add(e);let n=typeof t==`string`&&t.endsWith(o);e.includes(`-`)||n?r.setProperty(e,n?t.slice(0,-11):t,n?a:``):r[e]=t}}return e.g}}),c=class extends e.t{constructor(){super(),this.ariaLabel=null,this.ariaLabelledby=null,this.ariaValueText=null,this.ariaLive=`polite`,this.id=i.n(),this.role=`progressbar`,this.skin=`dark-blue`,this.statusPlacement=`following`,this.statusType=`none`,this.title=``,this.titlePosition=`left`,this.valueCurrent=0,this.valueMax=100,this.valueMin=0,this.labelWidth=0,this.progressbarId=this.id,this.resolvedRole=`progressbar`,this.labelRef=r.t(),this.progressBarRef=r.t(),this.containerRef=r.t()}willUpdate(e){super.willUpdate(e),this.id&&(this.progressbarId=this.id);let t=this.getAttribute(`role`);t?(this.resolvedRole=t,this.removeAttribute(`role`)):this.role&&(this.resolvedRole=this.role)}updated(e){if(super.updated(e),e.has(`valueCurrent`)&&this.labelRef.value){let e=this.labelRef.value.getBoundingClientRect().width||0;e!==this.labelWidth&&(this.labelWidth=e,this.containerRef.value?.style.setProperty(`--pkt-progress-label-width`,`${e}px`))}}render(){let i=this.statusType!==`none`,a=this.valueMax-this.valueMin,o=this.valueCurrent/a*100,c=this.statusType===`fraction`?Math.round(o):Math.round((this.valueCurrent-this.valueMin)/(this.valueMax-this.valueMin)*100),l=`${this.valueCurrent} av ${a}`,u=this.statusType===`fraction`&&!this.ariaValueText?`${this.valueCurrent} av ${this.valueMax-this.valueMin}`:this.ariaValueText||``,d=this.ariaLabel?void 0:this.ariaLabelledby||`${this.progressbarId}-title`,f=t.t({"pkt-progressbar__bar":!0,[`pkt-progressbar__bar--${this.skin}`]:!!this.skin}),p=t.t({"pkt-progressbar__title":!0,"pkt-progressbar__title-center":this.titlePosition===`center`}),m=t.t({"pkt-progressbar__status":!0,"pkt-progressbar__status--center":this.statusPlacement===`center`}),h=t.t({"pkt-progressbar__status-placement--following":this.statusPlacement===`following`,"pkt-progressbar__status-placement--center":this.statusPlacement===`center`,"pkt-progressbar__status-placement--left":this.statusPlacement===`left`});return e._`<div
2
- ${r.n(this.progressBarRef)}
3
- role=${this.resolvedRole}
4
- aria-live=${n.t(this.ariaLive||void 0)}
5
- aria-atomic="true"
6
- aria-valuenow=${this.valueCurrent}
7
- aria-valuemin=${this.valueMin}
8
- aria-valuemax=${this.valueMax}
9
- aria-valuetext=${n.t(u||void 0)}
10
- aria-label=${n.t(this.ariaLabel||void 0)}
11
- aria-labelledby=${n.t(d)}
12
- class="pkt-progressbar"
13
- >
14
- <div
15
- ${r.n(this.containerRef)}
16
- class="pkt-progressbar__container"
17
- style=${s({"--pkt-progress-label-width":`${this.labelWidth}px`,"--pkt-progress-width":`${c}%`})}
18
- >
19
- ${this.title?e._`<p id=${`${this.progressbarId}-title`} class=${p}>${this.title}</p>`:e.h}
20
-
21
- <div class="pkt-progressbar__bar-wrapper">
22
- <div class=${f}></div>
23
- </div>
24
-
25
- ${i?e._`<div class=${m}>
26
- <span class=${h} ${r.n(this.labelRef)}>
27
- ${this.statusType===`percentage`?`${c}%`:l}
28
- </span>
29
- </div>`:e.h}
30
- </div>
31
- </div>`}};e.n([e.u({type:String})],c.prototype,`ariaLabel`,void 0),e.n([e.u({type:String,reflect:!0})],c.prototype,`ariaLabelledby`,void 0),e.n([e.u({type:String,reflect:!0})],c.prototype,`ariaValueText`,void 0),e.n([e.u({type:String})],c.prototype,`ariaLive`,void 0),e.n([e.u({type:String,reflect:!0})],c.prototype,`id`,void 0),e.n([e.u({type:String})],c.prototype,`role`,void 0),e.n([e.u({type:String})],c.prototype,`skin`,void 0),e.n([e.u({type:String})],c.prototype,`statusPlacement`,void 0),e.n([e.u({type:String})],c.prototype,`statusType`,void 0),e.n([e.u({type:String,reflect:!0})],c.prototype,`title`,void 0),e.n([e.u({type:String})],c.prototype,`titlePosition`,void 0),e.n([e.u({type:Number,reflect:!0})],c.prototype,`valueCurrent`,void 0),e.n([e.u({type:Number})],c.prototype,`valueMax`,void 0),e.n([e.u({type:Number})],c.prototype,`valueMin`,void 0),e.n([e.l()],c.prototype,`progressbarId`,void 0),e.n([e.l()],c.prototype,`resolvedRole`,void 0);try{e.d(`pkt-progressbar`)(c)}catch{console.warn(`Forsøker å definere <pkt-progressbar>, men den er allerede definert`)}var l=c;Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return l}});