@oslokommune/punkt-elements 17.1.2 → 18.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.
- package/CHANGELOG.md +35 -0
- package/dist/{accordion-BeLvLPrB.js → accordion-1_pdxTgJ.js} +27 -27
- package/dist/{accordion-B3GBlvUC.cjs → accordion-DobbH-Sv.cjs} +5 -5
- package/dist/{alert-Cs4Rmq_J.cjs → alert-COeHz6o2.cjs} +6 -6
- package/dist/{alert-DKK_Tb9J.js → alert-xspFetQ8.js} +26 -26
- package/dist/{async-directive-Da7TJpnq.cjs → async-directive-B5pcIMfO.cjs} +1 -1
- package/dist/{async-directive-BPf6K-V2.js → async-directive-D2Sht790.js} +5 -5
- package/dist/{backlink-D1y26pj3.js → backlink-C0jZFnZ2.js} +8 -8
- package/dist/{backlink-CMmrKTe4.cjs → backlink-ZMhqHaVs.cjs} +3 -3
- package/dist/base-elements/element.d.ts +13 -1
- package/dist/base-elements/input-element.d.ts +4 -2
- package/dist/{breadcrumbs-B6JGhJgC.cjs → breadcrumbs-BS64xd1s.cjs} +7 -7
- package/dist/{breadcrumbs-CcTQ3Grm.js → breadcrumbs-BvMownZN.js} +16 -16
- package/dist/{button-2-OSPJkj.js → button-C44vNLFC.js} +28 -28
- package/dist/{button-CE97NQIk.cjs → button-CR4CXtnj.cjs} +7 -7
- package/dist/{calendar-kn4SrtJy.cjs → calendar-DQ4byeom.cjs} +28 -27
- package/dist/{calendar-pOW3R5Pw.js → calendar-DgjCKMMV.js} +82 -68
- package/dist/{card-zQ0eKRMV.js → card-DhHqC265.js} +44 -44
- package/dist/{card-CETDFkxR.cjs → card-Dpqi6HVt.cjs} +26 -26
- package/dist/{checkbox-CH7NpINF.js → checkbox-BQ1K57AB.js} +23 -23
- package/dist/{checkbox-CQNr_sEg.cjs → checkbox-CXQxbiaX.cjs} +11 -11
- package/dist/{class-map-BeimMvPv.cjs → class-map-CzCE5pqG.cjs} +1 -1
- package/dist/{class-map-CnWCnBSX.js → class-map-F1DJHyb7.js} +3 -3
- package/dist/{combobox-Bvg0UO9w.cjs → combobox-BV4oDiII.cjs} +19 -18
- package/dist/{combobox-CRdYYlxu.js → combobox-DPck39I2.js} +55 -54
- package/dist/components/calendar/calendar.d.ts +21 -6
- package/dist/components/checkbox/checkbox.d.ts +4 -2
- package/dist/components/combobox/combobox-base.d.ts +2 -1
- package/dist/components/consent/strings.d.ts +1 -85
- package/dist/components/datepicker/datepicker-base.d.ts +0 -3
- package/dist/components/datepicker/datepicker-multiple.d.ts +0 -2
- package/dist/components/datepicker/datepicker-range.d.ts +0 -2
- package/dist/components/datepicker/datepicker-single.d.ts +0 -2
- package/dist/components/datepicker/datepicker-utils.d.ts +2 -1
- package/dist/components/fileupload/fileupload-base.d.ts +3 -2
- package/dist/components/header/header-service.d.ts +3 -1
- package/dist/components/header/header.d.ts +2 -1
- package/dist/components/helptext/helptext.d.ts +2 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/input-wrapper/input-wrapper.d.ts +4 -2
- package/dist/components/radiobutton/radiobutton.d.ts +4 -2
- package/dist/components/searchinput/searchinput.d.ts +2 -1
- package/dist/{consent-DZEkhgJ1.js → consent-BneInZov.js} +10 -10
- package/dist/{consent-CyY3RyoC.cjs → consent-_N9foluG.cjs} +5 -5
- package/dist/controllers/strings-controller.d.ts +27 -0
- package/dist/{datepicker-VTqSDQk5.cjs → datepicker-9NX5qt2z.cjs} +38 -37
- package/dist/{datepicker-ButIas85.js → datepicker-nSSSr1U7.js} +104 -104
- package/dist/{directive-helpers-CI8YZqku.js → directive-helpers-BARw3nEZ.js} +1 -1
- package/dist/{directive-helpers-BlAV5EQD.cjs → directive-helpers-D6AAMFKs.cjs} +1 -1
- package/dist/docs/components/fileupload.d.ts +1 -0
- package/dist/element-B8OGznK0.cjs +2 -0
- package/dist/{element-ChsFgr_B.js → element-BKSPVgs2.js} +240 -100
- package/dist/{element-with-slot-Bj7nm7fO.cjs → element-with-slot-DTxILHVv.cjs} +1 -1
- package/dist/{element-with-slot-BvG9ctC-.js → element-with-slot-YUAUFRqw.js} +4 -4
- package/dist/fileupload-D05VSbEP.cjs +402 -0
- package/dist/{fileupload-D5IQ9HDe.js → fileupload-E0LGGNgj.js} +370 -380
- package/dist/{footer-DbYQUYNR.cjs → footer-DBApIdGh.cjs} +32 -32
- package/dist/{footer-DrR64HiK.js → footer-DYilVBMC.js} +91 -91
- package/dist/format-B8meU8Tm.cjs +1 -0
- package/dist/format-BTeSVkED.js +18 -0
- package/dist/{header-ClgIac6n.cjs → header-B7tbX-Ok.cjs} +84 -84
- package/dist/{header-menu-BAsUNKSx.cjs → header-menu-1FFWhvNc.cjs} +24 -24
- package/dist/{header-menu-hVPXsb8g.js → header-menu-D522-VTV.js} +75 -75
- package/dist/{header-KvJ1mGwA.js → header-v3GWAzOK.js} +267 -264
- package/dist/{heading-CFmiSuCQ.cjs → heading-CvytvcL7.cjs} +1 -1
- package/dist/{heading-g-_IUB5T.js → heading-rx_oSCqe.js} +16 -16
- package/dist/helptext-DYFdcylX.cjs +27 -0
- package/dist/{helptext-DZng1D5i.js → helptext-LShGPm-b.js} +18 -19
- package/dist/{icon-9iwd2F2l.cjs → icon-BmMC09mi.cjs} +1 -1
- package/dist/{icon-D-LA22xD.js → icon-HYU1f54x.js} +17 -17
- package/dist/{if-defined-CGzIlZ9-.js → if-defined-BF8XcDi5.js} +1 -1
- package/dist/if-defined-CVYApOgK.cjs +1 -0
- package/dist/{input-element-DBMNBplu.js → input-element-D07DmR34.js} +121 -120
- package/dist/input-element-DumGj_oJ.cjs +1 -0
- package/dist/input-wrapper-Cci_wTvD.js +308 -0
- package/dist/input-wrapper-DDfapoRX.cjs +58 -0
- package/dist/{link-DK7gvmnj.cjs → link-11g2ZNin.cjs} +4 -4
- package/dist/{link-D-Eqm5KH.js → link-CQK0SH4H.js} +13 -13
- package/dist/{linkcard-zqbg7Oqm.js → linkcard-B4GlmjJ6.js} +16 -16
- package/dist/linkcard-DNYsVlV6.cjs +13 -0
- package/dist/{listbox-Dc4rGdPi.cjs → listbox-BlFRhyI7.cjs} +15 -15
- package/dist/{listbox-va_E8afs.js → listbox-wd_OofyF.js} +100 -99
- package/dist/{loader-D_RDICnw.js → loader-0C3qVk16.js} +14 -14
- package/dist/{loader-CMUkVJmE.cjs → loader-B9u2qUlR.cjs} +5 -5
- package/dist/{messagebox-Cv8LaSxv.cjs → messagebox-BD5tGmT-.cjs} +5 -5
- package/dist/{messagebox-Cw-OWDya.js → messagebox-C-y1ICmr.js} +15 -15
- package/dist/{modal-BtInv031.cjs → modal-BzPGQYCs.cjs} +8 -8
- package/dist/{modal-D0t_X2dX.js → modal-Cghs3w-d.js} +20 -20
- package/dist/pkt-accordion.cjs +1 -1
- package/dist/pkt-accordion.js +1 -1
- package/dist/pkt-alert.cjs +1 -1
- package/dist/pkt-alert.js +1 -1
- package/dist/pkt-backlink.cjs +1 -1
- package/dist/pkt-backlink.js +1 -1
- package/dist/pkt-breadcrumbs.cjs +1 -1
- package/dist/pkt-breadcrumbs.js +1 -1
- package/dist/pkt-button.cjs +1 -1
- package/dist/pkt-button.js +1 -1
- package/dist/pkt-calendar.cjs +1 -1
- package/dist/pkt-calendar.js +1 -1
- package/dist/pkt-card.cjs +1 -1
- package/dist/pkt-card.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-consent.cjs +1 -1
- package/dist/pkt-consent.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-footer.cjs +1 -1
- package/dist/pkt-footer.js +1 -1
- package/dist/pkt-header-menu.cjs +1 -1
- package/dist/pkt-header-menu.js +1 -1
- package/dist/pkt-header.cjs +1 -1
- package/dist/pkt-header.js +1 -1
- package/dist/pkt-heading.cjs +1 -1
- package/dist/pkt-heading.js +1 -1
- package/dist/pkt-helptext.cjs +1 -1
- package/dist/pkt-helptext.js +1 -1
- package/dist/pkt-icon.cjs +1 -1
- package/dist/pkt-icon.js +1 -1
- package/dist/pkt-index.cjs +1 -1
- package/dist/pkt-index.js +35 -34
- package/dist/pkt-input-wrapper.cjs +1 -1
- package/dist/pkt-input-wrapper.js +1 -1
- package/dist/pkt-link.cjs +1 -1
- package/dist/pkt-link.js +1 -1
- package/dist/pkt-linkcard.cjs +1 -1
- package/dist/pkt-linkcard.js +1 -1
- package/dist/pkt-listbox.cjs +1 -1
- package/dist/pkt-listbox.js +1 -1
- package/dist/pkt-loader.cjs +1 -1
- package/dist/pkt-loader.js +1 -1
- package/dist/pkt-messagebox.cjs +1 -1
- package/dist/pkt-messagebox.js +1 -1
- package/dist/pkt-modal.cjs +1 -1
- package/dist/pkt-modal.js +1 -1
- package/dist/{pkt-options-controller-C5EBX2T0.cjs → pkt-options-controller-CEEAqXaB.cjs} +1 -1
- package/dist/{pkt-options-controller-B77vH3PE.js → pkt-options-controller-PtjhmTGk.js} +1 -1
- package/dist/pkt-progressbar.cjs +1 -1
- package/dist/pkt-progressbar.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-tabs.cjs +1 -1
- package/dist/pkt-tabs.js +1 -1
- package/dist/pkt-tag.cjs +1 -1
- package/dist/pkt-tag.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-CbcfLerF.js → progressbar-BexQQw1o.js} +21 -21
- package/dist/{progressbar-D5MmnQId.cjs → progressbar-X9mSvpjw.cjs} +5 -5
- package/dist/{radiobutton-BUnf3EPi.js → radiobutton-CkhTasn4.js} +24 -24
- package/dist/{radiobutton-DpsO1F-8.cjs → radiobutton-ln29Ad3U.cjs} +8 -8
- package/dist/{ref-CQoEIIp0.cjs → ref-CHbJYtKE.cjs} +1 -1
- package/dist/{ref-CWD6PjVd.js → ref-Chc_DZAb.js} +2 -2
- package/dist/{repeat-sY6B7fAT.cjs → repeat-CHDs__rN.cjs} +1 -1
- package/dist/{repeat-C02g7d5S.js → repeat-P9SMlKd5.js} +4 -4
- package/dist/searchinput-CPgMEAZZ.cjs +60 -0
- package/dist/{searchinput-DwnjsvJ1.js → searchinput-Da7dKHBH.js} +43 -43
- package/dist/{select-BOJi6H6T.cjs → select-DCuvdAuK.cjs} +4 -3
- package/dist/{select-DMre80qs.js → select-jabMSjft.js} +21 -20
- package/dist/shared-strings/consent.d.ts +71 -0
- package/dist/shared-strings/format.d.ts +21 -0
- package/dist/shared-strings/index.d.ts +14 -0
- package/dist/shared-strings/nb.d.ts +118 -0
- package/dist/shared-strings/resolve.d.ts +12 -0
- package/dist/shared-strings/store.d.ts +27 -0
- package/dist/shared-strings/types.d.ts +29 -0
- package/dist/shared-types/fileupload.d.ts +0 -27
- package/dist/shared-types/index.d.ts +1 -2
- package/dist/shared-utils/combobox/index.d.ts +1 -0
- package/dist/shared-utils/combobox/input-utils.d.ts +2 -1
- package/dist/shared-utils/combobox/messages.d.ts +7 -0
- package/dist/shared-utils/combobox/option-utils.d.ts +2 -1
- package/dist/shared-utils/combobox/selection-manager.d.ts +3 -2
- package/dist/{tabs-Cf9ai0FD.cjs → tabs-DV5CQNDL.cjs} +7 -7
- package/dist/{tabs-TvxgbrCF.js → tabs-D_hoi1zu.js} +32 -32
- package/dist/tag-BxYulmZn.cjs +27 -0
- package/dist/{tag-Ds6n1LIs.js → tag-DK5SgKry.js} +33 -32
- package/dist/tests/strings-override.test.d.ts +0 -0
- package/dist/{textarea-vfzIcXhX.js → textarea-BR7Riace.js} +30 -29
- package/dist/{textarea-BydiLM9Z.cjs → textarea-ffBD_VHq.cjs} +3 -2
- package/dist/{textinput-CMP2jPP_.js → textinput-CRNrsRNV.js} +28 -27
- package/dist/{textinput-DGdicNSx.cjs → textinput-CtHFzAux.cjs} +13 -12
- package/dist/timepicker-AfgJipo6.cjs +196 -0
- package/dist/{timepicker-ClwgYywH.js → timepicker-ixs_E5RY.js} +67 -64
- package/package.json +3 -3
- package/src/components/backlink/backlink.ts +1 -1
- package/src/components/breadcrumbs/breadcrumbs.ts +1 -1
- package/src/components/calendar/calendar.ts +56 -26
- package/src/components/checkbox/checkbox.test.ts +0 -2
- package/src/components/checkbox/checkbox.ts +8 -4
- package/src/components/combobox/combobox-base.ts +2 -1
- package/src/components/combobox/combobox-value.ts +10 -9
- package/src/components/combobox/combobox.selection.test.ts +5 -1
- package/src/components/combobox/combobox.ts +4 -1
- package/src/components/consent/strings.ts +1 -125
- package/src/components/datepicker/date-tags.ts +4 -1
- package/src/components/datepicker/datepicker-base.ts +2 -6
- package/src/components/datepicker/datepicker-multiple.ts +0 -3
- package/src/components/datepicker/datepicker-range.ts +4 -7
- package/src/components/datepicker/datepicker-single.ts +0 -3
- package/src/components/datepicker/datepicker-utils.test.ts +5 -5
- package/src/components/datepicker/datepicker-utils.ts +6 -11
- package/src/components/datepicker/datepicker.ts +8 -1
- package/src/components/fileupload/fileupload-base.ts +25 -16
- package/src/components/fileupload/fileupload-renderers.ts +2 -1
- package/src/components/fileupload/fileupload.test.ts +16 -0
- package/src/components/fileupload/fileupload.ts +19 -15
- package/src/components/header/header-global.ts +3 -3
- package/src/components/header/header-service.ts +13 -8
- package/src/components/header/header.ts +2 -1
- package/src/components/helptext/helptext.test.ts +1 -1
- package/src/components/helptext/helptext.ts +3 -3
- package/src/components/index.ts +9 -0
- package/src/components/input-wrapper/input-wrapper.ts +18 -10
- package/src/components/listbox/listbox.ts +3 -3
- package/src/components/radiobutton/radiobutton.ts +8 -4
- package/src/components/searchinput/searchinput.ts +5 -3
- package/src/components/select/select.ts +1 -0
- package/src/components/tag/tag.ts +2 -1
- package/src/components/textarea/textarea.ts +1 -0
- package/src/components/textinput/textinput.ts +1 -0
- package/src/components/timepicker/timepicker.ts +23 -21
- package/dist/element-BA8v6S7z.cjs +0 -2
- package/dist/fileupload-BeWiTAoW.cjs +0 -401
- package/dist/helptext-CTtKJcML.cjs +0 -27
- package/dist/if-defined-B89_ZeCj.cjs +0 -1
- package/dist/input-element-DYmQw-fH.cjs +0 -1
- package/dist/input-wrapper-BmxNvznr.js +0 -128
- package/dist/input-wrapper-D-fPaTbY.js +0 -176
- package/dist/input-wrapper-D5PR0rJn.cjs +0 -1
- package/dist/input-wrapper-Q-B-aBeb.cjs +0 -54
- package/dist/linkcard-B29cmZqh.cjs +0 -13
- package/dist/searchinput-Bh975rjX.cjs +0 -60
- package/dist/tag-CzojNU7z.cjs +0 -27
- package/dist/timepicker-DYrnLHqN.cjs +0 -195
- package/dist/translations/no.json.d.ts +0 -94
|
@@ -3,6 +3,7 @@ import { findOptionByValue, isMaxSelectionReached } from 'shared-utils/combobox/
|
|
|
3
3
|
import { getSingleValueForInput } from 'shared-utils/combobox/input-utils'
|
|
4
4
|
import { selectionMutators } from './combobox-utils'
|
|
5
5
|
import { ComboboxBase } from './combobox-base'
|
|
6
|
+
import type { TComboboxMessageKey } from 'shared-utils/combobox'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Value management layer for PktCombobox.
|
|
@@ -27,7 +28,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
27
28
|
|
|
28
29
|
let shouldOptionsBeOpen: boolean = false
|
|
29
30
|
let shouldResetInput: boolean = true
|
|
30
|
-
let userInfoMessage:
|
|
31
|
+
let userInfoMessage: TComboboxMessageKey = ''
|
|
31
32
|
let searchValue: string | null = ''
|
|
32
33
|
|
|
33
34
|
if (isDisabled) return
|
|
@@ -35,7 +36,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
35
36
|
// Not in option list and allowUserInput is true
|
|
36
37
|
if (!isInOption && this.allowUserInput && !isEmpty) {
|
|
37
38
|
this.addNewUserValue(value)
|
|
38
|
-
userInfoMessage = '
|
|
39
|
+
userInfoMessage = 'valueAdded'
|
|
39
40
|
shouldOptionsBeOpen = isMultiple
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -46,7 +47,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
46
47
|
}
|
|
47
48
|
shouldResetInput = false
|
|
48
49
|
shouldOptionsBeOpen = true
|
|
49
|
-
userInfoMessage = '
|
|
50
|
+
userInfoMessage = 'noResults'
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
// Value is already selected — deselect it
|
|
@@ -85,7 +86,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
85
86
|
|
|
86
87
|
// Multi-select with max selections reached
|
|
87
88
|
else if (isMultiple && isMaxItemsReached) {
|
|
88
|
-
userInfoMessage = '
|
|
89
|
+
userInfoMessage = 'maxSelected'
|
|
89
90
|
shouldResetInput = false
|
|
90
91
|
searchValue = value
|
|
91
92
|
}
|
|
@@ -93,7 +94,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
93
94
|
// No matching condition — fallback
|
|
94
95
|
else {
|
|
95
96
|
isSingle && this.removeAllSelected()
|
|
96
|
-
userInfoMessage = '
|
|
97
|
+
userInfoMessage = 'noValidValue'
|
|
97
98
|
shouldResetInput = false
|
|
98
99
|
shouldOptionsBeOpen = true
|
|
99
100
|
searchValue = value
|
|
@@ -121,7 +122,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
121
122
|
if (this._value.includes(value as string)) return
|
|
122
123
|
|
|
123
124
|
if (this.multiple && isMaxSelectionReached(this._value.length, this.maxlength)) {
|
|
124
|
-
this._userInfoMessage = '
|
|
125
|
+
this._userInfoMessage = 'maxSelected'
|
|
125
126
|
return
|
|
126
127
|
}
|
|
127
128
|
|
|
@@ -152,7 +153,7 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
152
153
|
protected addAllOptions(): void {
|
|
153
154
|
if (!this.multiple) return
|
|
154
155
|
if (this.maxlength && this._options.length > this.maxlength) {
|
|
155
|
-
this._userInfoMessage = '
|
|
156
|
+
this._userInfoMessage = 'tooManySelected'
|
|
156
157
|
return
|
|
157
158
|
}
|
|
158
159
|
|
|
@@ -173,10 +174,10 @@ export class ComboboxValue extends ComboboxBase {
|
|
|
173
174
|
this._search = input
|
|
174
175
|
|
|
175
176
|
// If the typed value is already selected, don't toggle (which would deselect).
|
|
176
|
-
// Just reset the input and keep the "
|
|
177
|
+
// Just reset the input and keep the "alreadySelected" message.
|
|
177
178
|
if (input && this._value.includes(input)) {
|
|
178
179
|
this.resetComboboxInput(true)
|
|
179
|
-
this._userInfoMessage = '
|
|
180
|
+
this._userInfoMessage = 'alreadySelected'
|
|
180
181
|
return
|
|
181
182
|
}
|
|
182
183
|
|
|
@@ -269,7 +269,11 @@ describe('PktCombobox', () => {
|
|
|
269
269
|
;(combobox as any).toggleValue('cherry')
|
|
270
270
|
await combobox.updateComplete
|
|
271
271
|
|
|
272
|
-
expect(combobox['_userInfoMessage']).toBe('
|
|
272
|
+
expect(combobox['_userInfoMessage']).toBe('maxSelected')
|
|
273
|
+
const listbox = container.querySelector('pkt-listbox') as HTMLElement & {
|
|
274
|
+
userMessage: string
|
|
275
|
+
}
|
|
276
|
+
expect(listbox.userMessage).toBe('Maks antall valg nådd')
|
|
273
277
|
})
|
|
274
278
|
|
|
275
279
|
test('allows deselection when at maxlength', async () => {
|
|
@@ -281,6 +281,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
|
|
|
281
281
|
render() {
|
|
282
282
|
return html`
|
|
283
283
|
<pkt-input-wrapper
|
|
284
|
+
.strings=${this.strings}
|
|
284
285
|
.size=${this.inputSize}
|
|
285
286
|
.label=${this.label}
|
|
286
287
|
.helptext=${this.helptext}
|
|
@@ -371,7 +372,9 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
|
|
|
371
372
|
?allow-user-input=${this.allowUserInput && !this._maxIsReached}
|
|
372
373
|
?max-is-reached=${this._maxIsReached}
|
|
373
374
|
.customUserInput=${ifDefined(this._addValueText)}
|
|
374
|
-
.userMessage=${this._userInfoMessage
|
|
375
|
+
.userMessage=${this._userInfoMessage
|
|
376
|
+
? this.pktStrings.get('combobox')[this._userInfoMessage]
|
|
377
|
+
: ''}
|
|
375
378
|
@search=${this.handleSearch}
|
|
376
379
|
@option-toggle=${this.handleOptionToggled}
|
|
377
380
|
@select-all=${this.addAllOptions}
|
|
@@ -1,125 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
i18n: {
|
|
3
|
-
nb: {
|
|
4
|
-
contentPresentation: {
|
|
5
|
-
title: 'Oslo kommune bruker informasjonskapsler',
|
|
6
|
-
description: [
|
|
7
|
-
'For at nettstedet skal fungere og være trygt, bruker Oslo kommune informasjonskapsler. Noen er teknisk nødvendige, mens andre sikrer ulik funksjonalitet.',
|
|
8
|
-
'Godtar du alle informasjonskapsler, tillater du også at vi samler inn data om statistikk og brukeradferd. Da hjelper du oss med å lage et bedre nettsted uten at du trenger å dele noe personlig informasjon med oss.',
|
|
9
|
-
],
|
|
10
|
-
buttons: {
|
|
11
|
-
accept: 'Godta alle',
|
|
12
|
-
reject: 'Kun nødvendige',
|
|
13
|
-
settings: 'Innstillinger for informasjonskapsler',
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
contentSettings: {
|
|
17
|
-
title: 'Innstillinger for informasjonskapsler',
|
|
18
|
-
description: [
|
|
19
|
-
'Her kan du velge hvilke typer informasjonskapsler du vil tillate. Tillatelsen gjelder i 90 dager. Husk at nødvendige informasjonskapsler ikke kan velges bort.',
|
|
20
|
-
'Du kan når som helst endre innstillingene og finne mer informasjon nederst på nettstedet under «Innstillinger for informasjonskapsler» og «Personvern og informasjonskapsler».',
|
|
21
|
-
],
|
|
22
|
-
buttons: {
|
|
23
|
-
back: 'Tilbake',
|
|
24
|
-
save: 'Lagre innstillinger',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
en: {
|
|
29
|
-
contentPresentation: {
|
|
30
|
-
title: 'Before you visit Oslo kommune ...',
|
|
31
|
-
description: [
|
|
32
|
-
'This website uses cookies to make improvements. In this context, we need your consent to measure the traffic on the website in relation to statistics and feedback.',
|
|
33
|
-
'To read more about what we use cookies for, go to our privacy declaration which you will find at the bottom of our websites.',
|
|
34
|
-
],
|
|
35
|
-
buttons: {
|
|
36
|
-
accept: 'Yes, I accept',
|
|
37
|
-
reject: 'Only necessary',
|
|
38
|
-
settings: 'Go to settings',
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
contentSettings: {
|
|
42
|
-
title: 'Her kan du aktivt velge mellom ulike informasjonskapsler',
|
|
43
|
-
description: [
|
|
44
|
-
'For å lese mer om hva vi bruker informasjonskapsler til gå til vår personvernserklering som du finner på våre nettsider',
|
|
45
|
-
],
|
|
46
|
-
buttons: {
|
|
47
|
-
back: 'Back',
|
|
48
|
-
save: 'Save settings',
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
cookies: [
|
|
54
|
-
{
|
|
55
|
-
name: 'statistics',
|
|
56
|
-
defaultValue: null,
|
|
57
|
-
i18n: {
|
|
58
|
-
nb: {
|
|
59
|
-
title: 'Statistikk og analyse',
|
|
60
|
-
description:
|
|
61
|
-
'Jeg godtar at Oslo kommune bruker informasjonskapsler til å innhente data om statistikk og brukeradferd.',
|
|
62
|
-
buttons: {
|
|
63
|
-
yes: 'Ja',
|
|
64
|
-
no: 'Nei',
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
en: {
|
|
68
|
-
title: 'Statistics and analytics',
|
|
69
|
-
description: 'Select your preference for statistics and analytics',
|
|
70
|
-
buttons: {
|
|
71
|
-
yes: 'Yes',
|
|
72
|
-
no: 'No',
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: 'survey',
|
|
79
|
-
defaultValue: null,
|
|
80
|
-
i18n: {
|
|
81
|
-
nb: {
|
|
82
|
-
title: 'Skriftlige tilbakemeldinger',
|
|
83
|
-
description:
|
|
84
|
-
'Jeg godtar at Oslo kommune bruker informasjonskapsler til å vise responsfelt og registrere tilbakemeldinger.',
|
|
85
|
-
buttons: {
|
|
86
|
-
yes: 'Ja',
|
|
87
|
-
no: 'Nei',
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
en: {
|
|
91
|
-
title: 'Survey',
|
|
92
|
-
description: 'Select your preference for survey',
|
|
93
|
-
buttons: {
|
|
94
|
-
yes: 'Yes',
|
|
95
|
-
no: 'No',
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
},
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
name: 'functional',
|
|
102
|
-
defaultValue: true,
|
|
103
|
-
i18n: {
|
|
104
|
-
nb: {
|
|
105
|
-
title: 'Funksjonelle informasjonskapsler',
|
|
106
|
-
description:
|
|
107
|
-
'Jeg godtar at Oslo kommune bruker informasjonskapsler for å gjøre ulike funksjoner på nettstedet mulige (for eksempel skjemaer og barnehagevelger).',
|
|
108
|
-
buttons: {
|
|
109
|
-
yes: 'Ja',
|
|
110
|
-
no: 'Nei',
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
en: {
|
|
114
|
-
title: 'Functional cookies',
|
|
115
|
-
description:
|
|
116
|
-
'For the website to function optimally, we recommend that you accept these cookies',
|
|
117
|
-
buttons: {
|
|
118
|
-
yes: 'Yes',
|
|
119
|
-
no: 'No',
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
}
|
|
1
|
+
export { consentStrings } from 'shared-strings/consent'
|
|
@@ -47,7 +47,10 @@ export class PktDateTags extends PktElement {
|
|
|
47
47
|
@close=${() => {
|
|
48
48
|
this.dispatchEvent(new CustomEvent('date-tag-removed', { detail: date }))
|
|
49
49
|
}}
|
|
50
|
-
.ariaLabel=${`${this.
|
|
50
|
+
.ariaLabel=${`${this.pktStrings.get('datepicker').deleteDate} ${fromISOtoLocal(
|
|
51
|
+
date,
|
|
52
|
+
this.dateformat,
|
|
53
|
+
)}`}
|
|
51
54
|
>
|
|
52
55
|
<time datetime=${date}>${fromISOtoLocal(date, this.dateformat)}</time>
|
|
53
56
|
</pkt-tag>`,
|
|
@@ -4,7 +4,7 @@ import { Ref, createRef } from 'lit/directives/ref.js'
|
|
|
4
4
|
import { classMap } from 'lit/directives/class-map.js'
|
|
5
5
|
import { PktElement } from '@/base-elements/element'
|
|
6
6
|
import { cssUtils } from './datepicker-utils'
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
import type { TPktInputSize } from 'shared-types/size'
|
|
9
9
|
import '@/components/icon'
|
|
10
10
|
|
|
@@ -15,7 +15,6 @@ import '@/components/icon'
|
|
|
15
15
|
* used by all three datepicker input types (single, multiple, range).
|
|
16
16
|
*
|
|
17
17
|
* Subclasses must implement:
|
|
18
|
-
* - `strings` property with component-specific defaults
|
|
19
18
|
* - `render()` method with component-specific template
|
|
20
19
|
*/
|
|
21
20
|
export abstract class PktDatepickerBase extends PktElement {
|
|
@@ -50,9 +49,6 @@ export abstract class PktDatepickerBase extends PktElement {
|
|
|
50
49
|
@property({ type: Object })
|
|
51
50
|
internals?: ElementInternals
|
|
52
51
|
|
|
53
|
-
// Abstract property - must be implemented by subclasses
|
|
54
|
-
abstract strings: IDatepickerStrings
|
|
55
|
-
|
|
56
52
|
// Shared refs
|
|
57
53
|
inputRef: Ref<HTMLInputElement> = createRef()
|
|
58
54
|
btnRef: Ref<HTMLButtonElement> = createRef()
|
|
@@ -140,7 +136,7 @@ export abstract class PktDatepickerBase extends PktElement {
|
|
|
140
136
|
${this.btnRef}
|
|
141
137
|
>
|
|
142
138
|
<pkt-icon name="calendar"></pkt-icon>
|
|
143
|
-
<span class="pkt-btn__text">${this.
|
|
139
|
+
<span class="pkt-btn__text">${this.pktStrings.get('datepicker').openPicker}</span>
|
|
144
140
|
</button>
|
|
145
141
|
`
|
|
146
142
|
}
|
|
@@ -5,7 +5,6 @@ import { ifDefined } from 'lit/directives/if-defined.js'
|
|
|
5
5
|
import { ref } from 'lit/directives/ref.js'
|
|
6
6
|
import { PktDatepickerBase } from './datepicker-base'
|
|
7
7
|
import { keyboardUtils, formUtils } from './datepicker-utils'
|
|
8
|
-
import { IDatepickerStrings, defaultSingleStrings } from './datepicker-types'
|
|
9
8
|
import { isIOS } from 'shared-utils/device-utils'
|
|
10
9
|
import '@/components/icon'
|
|
11
10
|
|
|
@@ -16,8 +15,6 @@ export class PktDatepickerMultiple extends PktDatepickerBase {
|
|
|
16
15
|
@property({ type: Number })
|
|
17
16
|
maxlength?: number
|
|
18
17
|
|
|
19
|
-
@property({ type: Object })
|
|
20
|
-
strings: IDatepickerStrings = defaultSingleStrings
|
|
21
18
|
|
|
22
19
|
get isInputDisabled(): boolean {
|
|
23
20
|
return (
|
|
@@ -5,7 +5,6 @@ import { ifDefined } from 'lit/directives/if-defined.js'
|
|
|
5
5
|
import { Ref, createRef, ref } from 'lit/directives/ref.js'
|
|
6
6
|
import { PktDatepickerBase } from './datepicker-base'
|
|
7
7
|
import { keyboardUtils, formUtils, cssUtils } from './datepicker-utils'
|
|
8
|
-
import { IDatepickerStrings, defaultRangeStrings } from './datepicker-types'
|
|
9
8
|
import { isIOS } from 'shared-utils/device-utils'
|
|
10
9
|
import '@/components/icon'
|
|
11
10
|
|
|
@@ -19,8 +18,6 @@ export class PktDatepickerRange extends PktDatepickerBase {
|
|
|
19
18
|
@property({ type: Boolean })
|
|
20
19
|
showRangeLabels: boolean = false
|
|
21
20
|
|
|
22
|
-
@property({ type: Object })
|
|
23
|
-
strings: IDatepickerStrings = defaultRangeStrings
|
|
24
21
|
|
|
25
22
|
inputRefTo: Ref<HTMLInputElement> = createRef()
|
|
26
23
|
|
|
@@ -34,13 +31,13 @@ export class PktDatepickerRange extends PktDatepickerBase {
|
|
|
34
31
|
return html`
|
|
35
32
|
<div class="pkt-input__container">
|
|
36
33
|
${this.showRangeLabels
|
|
37
|
-
? html` <div class="pkt-input-prefix">${this.
|
|
34
|
+
? html` <div class="pkt-input-prefix">${this.pktStrings.get('generic').from}</div> `
|
|
38
35
|
: nothing}
|
|
39
36
|
<input
|
|
40
37
|
class=${classMap(this.inputClasses)}
|
|
41
38
|
.type=${this.inputType}
|
|
42
39
|
id="${this.id}-input"
|
|
43
|
-
aria-label="${this.label} ${this.
|
|
40
|
+
aria-label="${this.label} ${this.pktStrings.get('generic').from}"
|
|
44
41
|
.value=${this.value[0] ?? ''}
|
|
45
42
|
min=${ifDefined(this.min)}
|
|
46
43
|
max=${ifDefined(this.max)}
|
|
@@ -97,14 +94,14 @@ export class PktDatepickerRange extends PktDatepickerBase {
|
|
|
97
94
|
${ref(this.inputRef)}
|
|
98
95
|
/>
|
|
99
96
|
<div class="${classMap(rangeLabelClasses)}" id="${this.id}-to-label">
|
|
100
|
-
${this.
|
|
97
|
+
${this.pktStrings.get('generic').to}
|
|
101
98
|
</div>
|
|
102
99
|
${!this.showRangeLabels ? html` <div class="pkt-input-separator">–</div> ` : nothing}
|
|
103
100
|
<input
|
|
104
101
|
class=${classMap(this.inputClasses)}
|
|
105
102
|
.type=${this.inputType}
|
|
106
103
|
id="${this.id}-to"
|
|
107
|
-
aria-label="${this.label} ${this.
|
|
104
|
+
aria-label="${this.label} ${this.pktStrings.get('generic').to}"
|
|
108
105
|
.value=${this.value[1] ?? ''}
|
|
109
106
|
min=${ifDefined(this.min)}
|
|
110
107
|
max=${ifDefined(this.max)}
|
|
@@ -5,15 +5,12 @@ import { ifDefined } from 'lit/directives/if-defined.js'
|
|
|
5
5
|
import { ref } from 'lit/directives/ref.js'
|
|
6
6
|
import { PktDatepickerBase } from './datepicker-base'
|
|
7
7
|
import { keyboardUtils, formUtils } from './datepicker-utils'
|
|
8
|
-
import { IDatepickerStrings, defaultSingleStrings } from './datepicker-types'
|
|
9
8
|
import { isIOS } from 'shared-utils/device-utils'
|
|
10
9
|
|
|
11
10
|
export class PktDatepickerSingle extends PktDatepickerBase {
|
|
12
11
|
@property({ type: String })
|
|
13
12
|
value: string = ''
|
|
14
13
|
|
|
15
|
-
@property({ type: Object })
|
|
16
|
-
strings: IDatepickerStrings = defaultSingleStrings
|
|
17
14
|
|
|
18
15
|
private dispatchManageValidity(input: HTMLInputElement) {
|
|
19
16
|
this.dispatchEvent(
|
|
@@ -144,9 +144,9 @@ describe('datepicker-utils', () => {
|
|
|
144
144
|
it('should set rangeUnderflow validity when value is below minimum', () => {
|
|
145
145
|
const input = { value: '2024-01-01' } as HTMLInputElement
|
|
146
146
|
const internals = { setValidity: vi.fn() }
|
|
147
|
-
const
|
|
147
|
+
const messages = { dateUnderflow: 'Too early' }
|
|
148
148
|
|
|
149
|
-
formUtils.validateDateInput(input, internals, '2024-01-10', null,
|
|
149
|
+
formUtils.validateDateInput(input, internals, '2024-01-10', null, messages)
|
|
150
150
|
expect(internals.setValidity).toHaveBeenCalledWith(
|
|
151
151
|
{ rangeUnderflow: true },
|
|
152
152
|
'Too early',
|
|
@@ -157,9 +157,9 @@ describe('datepicker-utils', () => {
|
|
|
157
157
|
it('should set rangeOverflow validity when value is above maximum', () => {
|
|
158
158
|
const input = { value: '2024-01-31' } as HTMLInputElement
|
|
159
159
|
const internals = { setValidity: vi.fn() }
|
|
160
|
-
const
|
|
160
|
+
const messages = { dateOverflow: 'Too late' }
|
|
161
161
|
|
|
162
|
-
formUtils.validateDateInput(input, internals, null, '2024-01-20',
|
|
162
|
+
formUtils.validateDateInput(input, internals, null, '2024-01-20', messages)
|
|
163
163
|
expect(internals.setValidity).toHaveBeenCalledWith(
|
|
164
164
|
{ rangeOverflow: true },
|
|
165
165
|
'Too late',
|
|
@@ -174,7 +174,7 @@ describe('datepicker-utils', () => {
|
|
|
174
174
|
formUtils.validateDateInput(input, internals, '2024-01-10', null)
|
|
175
175
|
expect(internals.setValidity).toHaveBeenCalledWith(
|
|
176
176
|
{ rangeUnderflow: true },
|
|
177
|
-
'
|
|
177
|
+
'For tidlig dato',
|
|
178
178
|
input,
|
|
179
179
|
)
|
|
180
180
|
})
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { fromISOToDate, newDate } from 'shared-utils/date-utils'
|
|
2
2
|
import { Ref } from 'lit/directives/ref.js'
|
|
3
3
|
import { PktCalendar } from '@/components/calendar/calendar'
|
|
4
|
+
import { nb, type TPktStrings } from 'shared-strings'
|
|
4
5
|
import {
|
|
5
6
|
validateRangeOrder,
|
|
6
7
|
sortDates,
|
|
@@ -66,23 +67,17 @@ export const formUtils = {
|
|
|
66
67
|
internals: any,
|
|
67
68
|
min?: string | null,
|
|
68
69
|
max?: string | null,
|
|
69
|
-
|
|
70
|
+
messages?: Partial<TPktStrings['validation']>,
|
|
70
71
|
): void {
|
|
71
72
|
const value = input.value
|
|
72
73
|
if (!value) return
|
|
73
74
|
|
|
75
|
+
const validation = { ...nb.validation, ...messages }
|
|
76
|
+
|
|
74
77
|
if (min && min > value) {
|
|
75
|
-
internals.setValidity(
|
|
76
|
-
{ rangeUnderflow: true },
|
|
77
|
-
strings?.forms?.messages?.rangeUnderflow || 'Value is below minimum',
|
|
78
|
-
input,
|
|
79
|
-
)
|
|
78
|
+
internals.setValidity({ rangeUnderflow: true }, validation.dateUnderflow, input)
|
|
80
79
|
} else if (max && max < value) {
|
|
81
|
-
internals.setValidity(
|
|
82
|
-
{ rangeOverflow: true },
|
|
83
|
-
strings?.forms?.messages?.rangeOverflow || 'Value is above maximum',
|
|
84
|
-
input,
|
|
85
|
-
)
|
|
80
|
+
internals.setValidity({ rangeOverflow: true }, validation.dateOverflow, input)
|
|
86
81
|
}
|
|
87
82
|
},
|
|
88
83
|
}
|
|
@@ -391,7 +391,13 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
391
391
|
}}
|
|
392
392
|
@manage-validity=${(e: CustomEvent) => this.manageValidity(e.detail)}
|
|
393
393
|
@validate-date-input=${(e: CustomEvent) => {
|
|
394
|
-
formUtils.validateDateInput(
|
|
394
|
+
formUtils.validateDateInput(
|
|
395
|
+
e.detail,
|
|
396
|
+
this.internals,
|
|
397
|
+
this.min,
|
|
398
|
+
this.max,
|
|
399
|
+
this.pktStrings.get('validation'),
|
|
400
|
+
)
|
|
395
401
|
}}
|
|
396
402
|
@handle-date-select=${(e: CustomEvent) => {
|
|
397
403
|
const date = fromISOToDate(e.detail)
|
|
@@ -497,6 +503,7 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
497
503
|
|
|
498
504
|
return html`
|
|
499
505
|
<pkt-input-wrapper
|
|
506
|
+
.strings=${this.strings}
|
|
500
507
|
label="${this.label}"
|
|
501
508
|
forId="${this.id}-input"
|
|
502
509
|
?counter=${this.multiple && !!this.maxlength}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { PropertyValues } from 'lit'
|
|
2
2
|
import { property, state } from 'lit/decorators.js'
|
|
3
3
|
|
|
4
|
-
import { defaultFileUploadStrings } from 'shared-types'
|
|
5
4
|
import {
|
|
6
5
|
countFileTransferStates,
|
|
7
6
|
formatFileSize,
|
|
@@ -29,6 +28,7 @@ import type {
|
|
|
29
28
|
TUploadStrategy,
|
|
30
29
|
} from './fileupload-types'
|
|
31
30
|
import { uuidish } from 'shared-utils/utils'
|
|
31
|
+
import { formatString, plural } from 'shared-strings'
|
|
32
32
|
|
|
33
33
|
export abstract class PktFileUploadBase
|
|
34
34
|
extends PktElement<IPktFileUpload>
|
|
@@ -92,8 +92,9 @@ export abstract class PktFileUploadBase
|
|
|
92
92
|
/** Show "Valgfritt" tag in the input wrapper. */
|
|
93
93
|
@property({ type: Boolean, attribute: 'optional-tag' }) optionalTag = false
|
|
94
94
|
/** Label text for the optional tag. */
|
|
95
|
+
/** @deprecated Bruk `strings={{ forms: { optional: '…' } }}` eller `setPktStrings()`. */
|
|
95
96
|
@property({ type: String, attribute: 'optional-text' })
|
|
96
|
-
optionalText
|
|
97
|
+
optionalText?: string
|
|
97
98
|
/** Show "Må fylles ut" tag in the input wrapper. */
|
|
98
99
|
@property({ type: Boolean, attribute: 'required-tag' }) requiredTag = false
|
|
99
100
|
/** Label text for the required tag. */
|
|
@@ -119,7 +120,9 @@ export abstract class PktFileUploadBase
|
|
|
119
120
|
private thumbnailFileById = new Map<string, File>()
|
|
120
121
|
private connectedForm: HTMLFormElement | null = null
|
|
121
122
|
private addedAnnouncementTimer: ReturnType<typeof setTimeout> | null = null
|
|
122
|
-
private
|
|
123
|
+
private get requiredSelectionMessage() {
|
|
124
|
+
return this.pktStrings.get('fileupload').requiredMissing
|
|
125
|
+
}
|
|
123
126
|
|
|
124
127
|
protected get isControlled() {
|
|
125
128
|
return this.value !== undefined
|
|
@@ -297,10 +300,13 @@ export abstract class PktFileUploadBase
|
|
|
297
300
|
},
|
|
298
301
|
}))
|
|
299
302
|
|
|
303
|
+
const fileuploadStrings = this.pktStrings.get('fileupload')
|
|
300
304
|
this.setAddedAnnouncement(
|
|
301
305
|
newItems.length === 1
|
|
302
|
-
?
|
|
303
|
-
|
|
306
|
+
? formatString(fileuploadStrings.srFileAdded, {
|
|
307
|
+
filename: newItems[0].attributes.targetFilename,
|
|
308
|
+
})
|
|
309
|
+
: formatString(fileuploadStrings.srFilesAdded, { count: newItems.length }),
|
|
304
310
|
)
|
|
305
311
|
|
|
306
312
|
const currentFiles = this.getCurrentFiles()
|
|
@@ -448,7 +454,8 @@ export abstract class PktFileUploadBase
|
|
|
448
454
|
this.dispatchEvent(validationEvent)
|
|
449
455
|
|
|
450
456
|
if (eventDetail.errorMessage) return eventDetail.errorMessage
|
|
451
|
-
if (validationEvent.defaultPrevented)
|
|
457
|
+
if (validationEvent.defaultPrevented)
|
|
458
|
+
return this.pktStrings.get('fileupload').genericValidationRejection
|
|
452
459
|
return null
|
|
453
460
|
}
|
|
454
461
|
|
|
@@ -523,11 +530,12 @@ export abstract class PktFileUploadBase
|
|
|
523
530
|
this.transfers,
|
|
524
531
|
)
|
|
525
532
|
if (totalCount === 0 || uploadedCount === 0) return ''
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
533
|
+
const fileuploadStrings = this.pktStrings.get('fileupload')
|
|
534
|
+
return formatString(fileuploadStrings.srFilesUploadedOfTotal, {
|
|
535
|
+
uploaded: uploadedCount,
|
|
536
|
+
total: totalCount,
|
|
537
|
+
label: plural(totalCount, fileuploadStrings.fileLabelOne, fileuploadStrings.fileLabelOther),
|
|
538
|
+
})
|
|
531
539
|
}
|
|
532
540
|
|
|
533
541
|
/** Assertive summary for transfer errors (parity with React `FileUpload`). */
|
|
@@ -537,11 +545,12 @@ export abstract class PktFileUploadBase
|
|
|
537
545
|
this.transfers,
|
|
538
546
|
)
|
|
539
547
|
if (totalCount === 0 || failedCount === 0) return ''
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
548
|
+
const fileuploadStrings = this.pktStrings.get('fileupload')
|
|
549
|
+
return formatString(fileuploadStrings.srFilesFailedOfTotal, {
|
|
550
|
+
failed: failedCount,
|
|
551
|
+
total: totalCount,
|
|
552
|
+
label: plural(totalCount, fileuploadStrings.fileLabelOne, fileuploadStrings.fileLabelOther),
|
|
553
|
+
})
|
|
545
554
|
}
|
|
546
555
|
|
|
547
556
|
private syncFormSubmitListener() {
|
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
TQueueOperationContext,
|
|
11
11
|
TTransferProgress,
|
|
12
12
|
} from './fileupload-types'
|
|
13
|
+
import { formatString, nb } from 'shared-strings'
|
|
13
14
|
|
|
14
15
|
type TRenderQueueItemProps = {
|
|
15
16
|
file: FileItem
|
|
@@ -449,7 +450,7 @@ const renderThumbnailIdleMain = ({
|
|
|
449
450
|
<button
|
|
450
451
|
type="button"
|
|
451
452
|
class="pkt-fileupload__queue-display__item__thumbnail__image-wrapper pkt-btn pkt-btn--medium pkt-btn--secondary pkt-btn--label-only"
|
|
452
|
-
aria-label=${
|
|
453
|
+
aria-label=${formatString(nb.fileupload.previewImage, { filename })}
|
|
453
454
|
?disabled=${!isInteractive}
|
|
454
455
|
@click=${() => {
|
|
455
456
|
if (!isInteractive || !onOpenPreview) return
|
|
@@ -368,6 +368,22 @@ describe('PktFileUpload', () => {
|
|
|
368
368
|
expect(withAcceptText).toContain('Format: PNG, application/pdf')
|
|
369
369
|
})
|
|
370
370
|
|
|
371
|
+
test('uses drop zone text from the strings property', async () => {
|
|
372
|
+
const { fileupload } = await createFileUploadTest({ multiple: true })
|
|
373
|
+
fileupload.strings = {
|
|
374
|
+
fileupload: {
|
|
375
|
+
dropZoneDragMultiple: 'Dra dokumentene hit eller',
|
|
376
|
+
dropZoneOpenFileDialogMultiple: 'bla i filene',
|
|
377
|
+
},
|
|
378
|
+
}
|
|
379
|
+
await fileupload.updateComplete
|
|
380
|
+
|
|
381
|
+
const title = fileupload.querySelector('.pkt-fileupload__drop-zone__placeholder__title')
|
|
382
|
+
expect(title?.textContent).toContain('Dra dokumentene hit eller')
|
|
383
|
+
expect(title?.textContent).toContain('bla i filene')
|
|
384
|
+
expect(title?.textContent).not.toContain('velg filer')
|
|
385
|
+
})
|
|
386
|
+
|
|
371
387
|
test('sets required only on native file input in form strategy', async () => {
|
|
372
388
|
const { fileupload: formUpload } = await createFileUploadTest({
|
|
373
389
|
required: true,
|