@oslokommune/punkt-elements 19.7.0 → 19.9.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-CMCCpxtz.cjs +47 -0
- package/dist/{accordion-BJh6X1Ek.js → accordion-Cp2o6wTY.js} +10 -9
- package/dist/{alert-C0PiYnot.js → alert-CAPiwi4F.js} +10 -5
- package/dist/alert-QfloIr-o.cjs +39 -0
- package/dist/{async-directive-BGoo_npW.cjs → async-directive-DpyKp6qv.cjs} +1 -1
- package/dist/{async-directive-DsdqP_X7.js → async-directive-yh8hG41Q.js} +2 -2
- package/dist/{backlink-BRqhwUr2.cjs → backlink-CsFeerTH.cjs} +1 -1
- package/dist/{backlink-BslFewn-.js → backlink-ogvv493Y.js} +3 -3
- package/dist/base-elements/input-element.d.ts +17 -0
- package/dist/base-elements/option-group-element.d.ts +61 -0
- package/dist/base-elements/polyfill-form-value.test.d.ts +0 -0
- package/dist/{breadcrumbs-Cr3GugPv.js → breadcrumbs-53QVnTFP.js} +2 -2
- package/dist/{breadcrumbs-DG4i5UCh.cjs → breadcrumbs-D03id_ha.cjs} +1 -1
- package/dist/{button-B78im4wB.js → button-CeRr7oIn.js} +5 -5
- package/dist/{button-BNVTj7nB.cjs → button-Dh97H-58.cjs} +1 -1
- package/dist/{calendar-TcxvS-1_.cjs → calendar-C5QwPrbk.cjs} +1 -1
- package/dist/{calendar-BLaRXUBl.js → calendar-D9w8M99G.js} +3 -3
- package/dist/{card-CaLEuumN.cjs → card--NuWdTbG.cjs} +1 -1
- package/dist/{card-CYKhPUNI.js → card-_PlgXmgZ.js} +6 -6
- package/dist/{checkbox-Tq8ESzwH.js → checkbox-G8k3vg85.js} +39 -35
- package/dist/checkbox-QIcdn09A.cjs +40 -0
- package/dist/checkbox-group-DoueGGi5.js +50 -0
- package/dist/checkbox-group-nLazAkcg.cjs +1 -0
- package/dist/checkbox-group.d.ts +1 -0
- package/dist/{class-map-C4hdfSfY.js → class-map-Bf-QzUpN.js} +1 -1
- package/dist/{class-map-Drv0_anQ.cjs → class-map-Bh6toDeV.cjs} +1 -1
- package/dist/{combobox-BfdvXLBz.cjs → combobox-ClXhKwR9.cjs} +1 -1
- package/dist/{combobox-CMpYhgln.js → combobox-Cz_rq7Mm.js} +13 -13
- package/dist/components/checkbox/checkbox.d.ts +1 -0
- package/dist/components/checkbox-group/checkbox-group-context.d.ts +5 -0
- package/dist/components/checkbox-group/checkbox-group.d.ts +15 -0
- package/dist/components/checkbox-group/checkbox-group.test.d.ts +0 -0
- package/dist/components/checkbox-group/index.d.ts +3 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/messagebox/messagebox.d.ts +2 -6
- package/dist/components/radio-group/index.d.ts +3 -0
- package/dist/components/radio-group/radio-group-context.d.ts +7 -0
- package/dist/components/radio-group/radio-group.d.ts +14 -0
- package/dist/components/radio-group/radio-group.test.d.ts +0 -0
- package/dist/components/radiobutton/radiobutton.d.ts +1 -0
- package/dist/{consent-CleJMbVH.js → consent-CZMxUavj.js} +2 -2
- package/dist/{consent-Dl-R0iC3.cjs → consent-DimzcQxt.cjs} +1 -1
- package/dist/consume-Bp12si68.js +61 -0
- package/dist/consume-kEjgTrAp.cjs +1 -0
- package/dist/{datepicker-Bs7Z3EFn.js → datepicker-C7ABsx7H.js} +12 -12
- package/dist/{datepicker-CWHYYj-H.cjs → datepicker-usIF9WY7.cjs} +2 -2
- package/dist/{directive-helpers-BRrz3Bcj.cjs → directive-helpers-Bv70GjQh.cjs} +1 -1
- package/dist/{directive-helpers-D96YEsht.js → directive-helpers-CwxFepWh.js} +1 -1
- package/dist/directives/slot-content.d.ts +4 -3
- package/dist/docs/components/checkbox-group.d.ts +13 -0
- package/dist/docs/components/radio-group.d.ts +13 -0
- package/dist/{element-BOmr9YLv.cjs → element-C6WTyJFE.cjs} +1 -1
- package/dist/{element-mwwC2Rra.js → element-DBugHPKM.js} +1 -0
- package/dist/{element-with-slot-DQv0cbbD.js → element-with-slot-DDLS-aLw.js} +6 -3
- package/dist/element-with-slot-DhiAuSjM.cjs +1 -0
- package/dist/{fileupload-CMIFZWJ5.cjs → fileupload-2uTFjd81.cjs} +1 -1
- package/dist/{fileupload-BQFJx1ok.js → fileupload-BR9H6fET.js} +8 -8
- package/dist/{footer-DdLls3F-.js → footer-B3DMvo8-.js} +4 -4
- package/dist/{footer-vy9NqT65.cjs → footer-CyxRYvT-.cjs} +1 -1
- package/dist/{header-Cc1Cy0U3.js → header-BKeSkfB7.js} +11 -11
- package/dist/{header-C4Uojzoy.cjs → header-Drj3lTrv.cjs} +1 -1
- package/dist/{header-menu-BfkCp8jw.cjs → header-menu-B_5hCNUl.cjs} +1 -1
- package/dist/{header-menu-ANj5nL2M.js → header-menu-buYE90FU.js} +4 -4
- package/dist/{heading-zoz-QZJ9.cjs → heading-DUYOvlxs.cjs} +1 -1
- package/dist/{heading-CUrZvkrM.js → heading-WBB5MO9i.js} +2 -2
- package/dist/{helptext-BCkwSz1m.cjs → helptext-C7cyihnu.cjs} +1 -1
- package/dist/{helptext-DCT_9dw1.js → helptext-DadLkcoO.js} +4 -4
- package/dist/{icon-JigbxxF7.js → icon-Bao96Zb8.js} +1 -1
- package/dist/{icon-Dnv6LtPC.cjs → icon-jPhyZD1z.cjs} +1 -1
- package/dist/if-defined-CiML3MTM.cjs +1 -0
- package/dist/{if-defined-Bebu3LXY.js → if-defined-O59_I-e-.js} +1 -1
- package/dist/{input-element-lLzfwdim.js → input-element-BBygBEei.js} +54 -17
- package/dist/input-element-C4SelHLD.cjs +1 -0
- package/dist/{input-wrapper-J3mEKhvR.cjs → input-wrapper-BT6B3Kco.cjs} +6 -2
- package/dist/{input-wrapper-BoTugCvh.js → input-wrapper-DrSCuw6U.js} +12 -8
- package/dist/{link-LO_5_La8.cjs → link-CEP7w1et.cjs} +1 -1
- package/dist/{link-CmZwAw5u.js → link-CVnIn74-.js} +4 -4
- package/dist/{linkcard-UKsxADrP.cjs → linkcard-D8vitdrQ.cjs} +1 -1
- package/dist/{linkcard-CQluSyJJ.js → linkcard-IWiVvRKy.js} +4 -4
- package/dist/{listbox-Ct9jIV_5.js → listbox-BDesthOp.js} +4 -4
- package/dist/{listbox-g-vHHLkD.cjs → listbox-CvduK_YU.cjs} +1 -1
- package/dist/{loader-C_PH05aw.cjs → loader-B0hFoBtF.cjs} +1 -1
- package/dist/{loader-DzctJ9jW.js → loader-CAsUPHjl.js} +4 -4
- package/dist/{messagebox-DPFBuisE.js → messagebox-6_iNN5F3.js} +9 -49
- package/dist/messagebox-C19L2Duq.cjs +13 -0
- package/dist/{modal-BymjMIJi.cjs → modal-CoEPzt4p.cjs} +1 -1
- package/dist/{modal-CELmA0-8.js → modal-D7MolBXb.js} +5 -5
- package/dist/option-group-element-BIuotbRu.js +135 -0
- package/dist/option-group-element-BYS7s-is.cjs +23 -0
- 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-group.cjs +1 -0
- package/dist/pkt-checkbox-group.js +2 -0
- 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 +37 -35
- 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-CpEZcomb.cjs → pkt-options-controller-B3vVKnAG.cjs} +1 -1
- package/dist/{pkt-options-controller-D7l18Iw0.js → pkt-options-controller-ClFrUWZK.js} +1 -1
- package/dist/pkt-progressbar.cjs +1 -1
- package/dist/pkt-progressbar.js +1 -1
- package/dist/pkt-radio-group.cjs +1 -0
- package/dist/pkt-radio-group.js +2 -0
- 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-CIXNSwTy.cjs → progressbar-CnX4fFfR.cjs} +1 -1
- package/dist/{progressbar-DH5lIBpx.js → progressbar-DZHiq7B0.js} +5 -5
- package/dist/provide-Cz18sYug.cjs +1 -0
- package/dist/provide-_MnlMGnw.js +111 -0
- package/dist/radio-group-kOzlGn8T.cjs +1 -0
- package/dist/radio-group-lhymYEZX.js +52 -0
- package/dist/radio-group.d.ts +1 -0
- package/dist/radiobutton-BgHCcDJv.cjs +38 -0
- package/dist/{radiobutton-l_3oGDbb.js → radiobutton-CFd8TgV9.js} +39 -35
- package/dist/{ref-Emu5PNxk.cjs → ref-CB7e9nMY.cjs} +1 -1
- package/dist/{ref-CCSGk4MP.js → ref-y_5qv9vU.js} +2 -2
- package/dist/{repeat-CdxGS-_3.js → repeat-CV9S4zya.js} +2 -2
- package/dist/{repeat-Dh9YKoeV.cjs → repeat-CnnigVcj.cjs} +1 -1
- package/dist/{searchinput-Co8tcq-l.js → searchinput-Bkcr3Fby.js} +4 -4
- package/dist/{searchinput-CbClDE-d.cjs → searchinput-Mdc9Ihld.cjs} +1 -1
- package/dist/{select-DYjKMmHa.js → select-B6CN2Ymq.js} +7 -7
- package/dist/{select-CZYQ5Dmx.cjs → select-BowvpCNa.cjs} +1 -1
- package/dist/shared-strings/nb.d.ts +1 -0
- package/dist/shared-types/index.d.ts +7 -3
- package/dist/shared-types/messagebox.d.ts +32 -0
- package/dist/shared-types/option-group.d.ts +50 -0
- package/dist/shared-types/skin.d.ts +1 -4
- package/dist/{tabs-B8blHQrL.js → tabs-DZvtVA0y.js} +9 -8
- package/dist/tabs-Dm8xcPRs.cjs +40 -0
- package/dist/{tag-Bns7Xj1O.js → tag-C33BPIOm.js} +5 -5
- package/dist/{tag-B5dUg7AD.cjs → tag-DyVZrqOQ.cjs} +1 -1
- package/dist/tests/component-registry.d.ts +4 -0
- package/dist/tests/option-contexts.d.ts +7 -0
- package/dist/{textarea-H1Lt2o6K.cjs → textarea-DoH3Il8v.cjs} +1 -1
- package/dist/{textarea-C2oaRlfb.js → textarea-hW0kV5gj.js} +9 -9
- package/dist/{textinput-C0eu70sH.js → textinput-B6G4dVuL.js} +8 -8
- package/dist/{textinput-C2Tx-OrN.cjs → textinput-CQknclmV.cjs} +1 -1
- package/dist/{timepicker-B8TwchA2.js → timepicker-Cd2QI6ua.js} +8 -8
- package/dist/{timepicker-DZG_gHIa.cjs → timepicker-DB3gor6g.cjs} +1 -1
- package/package.json +2 -2
- package/src/components/alert/alert.ts +1 -1
- package/src/components/checkbox/checkbox.test.ts +99 -0
- package/src/components/checkbox/checkbox.ts +14 -5
- package/src/components/checkbox-group/checkbox-group-context.ts +8 -0
- package/src/components/checkbox-group/checkbox-group.test.ts +406 -0
- package/src/components/checkbox-group/checkbox-group.ts +69 -0
- package/src/components/checkbox-group/index.ts +4 -0
- package/src/components/combobox/combobox.ts +1 -1
- package/src/components/datepicker/datepicker.ts +1 -1
- package/src/components/index.ts +2 -0
- package/src/components/input-wrapper/input-wrapper.ts +5 -1
- package/src/components/input-wrapper/wrapper-parity.test.ts +27 -2
- package/src/components/messagebox/messagebox.test.ts +1 -1
- package/src/components/messagebox/messagebox.ts +6 -12
- package/src/components/radio-group/index.ts +4 -0
- package/src/components/radio-group/radio-group-context.ts +8 -0
- package/src/components/radio-group/radio-group.test.ts +530 -0
- package/src/components/radio-group/radio-group.ts +65 -0
- package/src/components/radiobutton/radiobutton.test.ts +95 -0
- package/src/components/radiobutton/radiobutton.ts +11 -5
- package/dist/accordion-5lSFQToJ.cjs +0 -47
- package/dist/alert-IaZzEgyI.cjs +0 -39
- package/dist/checkbox-D69leWDh.cjs +0 -40
- package/dist/consume-BDnMAp2g.js +0 -167
- package/dist/consume-Le4HztPo.cjs +0 -1
- package/dist/element-with-slot-D7sTqOr3.cjs +0 -1
- package/dist/if-defined-2mkIDgOm.cjs +0 -1
- package/dist/input-element-CSfDGslx.cjs +0 -1
- package/dist/messagebox-JWKMJEFc.cjs +0 -13
- package/dist/radiobutton-BPr22VmL.cjs +0 -38
- package/dist/tabs-CjX-GWvM.cjs +0 -40
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { consume } from '@lit/context'
|
|
2
|
+
import { customElement, property, state } from 'lit/decorators.js'
|
|
2
3
|
|
|
3
4
|
import { PktInputElement } from '@/base-elements/input-element'
|
|
5
|
+
import {
|
|
6
|
+
checkboxGroupContext,
|
|
7
|
+
type CheckboxGroupContext,
|
|
8
|
+
} from '@/components/checkbox-group/checkbox-group-context'
|
|
4
9
|
import { Ref, createRef, ref } from 'lit/directives/ref.js'
|
|
5
10
|
import { html, nothing, PropertyValues } from 'lit'
|
|
6
11
|
import { classMap } from 'lit/directives/class-map.js'
|
|
@@ -46,6 +51,10 @@ export class PktCheckbox extends PktInputElement<Props> {
|
|
|
46
51
|
/** @deprecated Bruk `strings={{ forms: { required: '…' } }}` eller `setPktStrings()`. */
|
|
47
52
|
@property({ type: String }) requiredText?: string
|
|
48
53
|
|
|
54
|
+
@consume({ context: checkboxGroupContext, subscribe: true })
|
|
55
|
+
@state()
|
|
56
|
+
private groupContext?: CheckboxGroupContext
|
|
57
|
+
|
|
49
58
|
connectedCallback() {
|
|
50
59
|
super.connectedCallback()
|
|
51
60
|
}
|
|
@@ -91,15 +100,16 @@ export class PktCheckbox extends PktInputElement<Props> {
|
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
render() {
|
|
103
|
+
const hasTile = this.hasTile || !!this.groupContext?.hasTile
|
|
94
104
|
const inputTileClasses = classMap({
|
|
95
105
|
'pkt-input-check__input': true,
|
|
96
|
-
'pkt-input-check__input--tile':
|
|
97
|
-
'pkt-input-check__input--tile-disabled': this.isDisabled &&
|
|
106
|
+
'pkt-input-check__input--tile': hasTile,
|
|
107
|
+
'pkt-input-check__input--tile-disabled': this.isDisabled && hasTile,
|
|
98
108
|
})
|
|
99
109
|
|
|
100
110
|
const inputCheckBoxClasses = classMap({
|
|
101
111
|
'pkt-input-check__input-checkbox': true,
|
|
102
|
-
'pkt-input-check__input-checkbox--error': this.hasError,
|
|
112
|
+
'pkt-input-check__input-checkbox--error': this.hasError || !!this.groupContext?.hasError,
|
|
103
113
|
})
|
|
104
114
|
|
|
105
115
|
const labelClasses = classMap({
|
|
@@ -185,7 +195,6 @@ export class PktCheckbox extends PktInputElement<Props> {
|
|
|
185
195
|
|
|
186
196
|
private handleInput(e: Event) {
|
|
187
197
|
e.stopImmediatePropagation()
|
|
188
|
-
this.onInput()
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
private handleClick(e: Event) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createContext } from '@lit/context'
|
|
2
|
+
import type { IPktOptionGroupContext } from '@/base-elements/input-element'
|
|
3
|
+
|
|
4
|
+
export type CheckboxGroupContext = IPktOptionGroupContext
|
|
5
|
+
|
|
6
|
+
export const checkboxGroupContext = createContext<CheckboxGroupContext>(
|
|
7
|
+
Symbol('pkt-checkbox-group-context'),
|
|
8
|
+
)
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import '@testing-library/jest-dom'
|
|
2
|
+
import { axe, toHaveNoViolations } from 'jest-axe'
|
|
3
|
+
import { fireEvent } from '@testing-library/dom'
|
|
4
|
+
import { vi } from 'vitest'
|
|
5
|
+
import type { LitElement } from 'lit'
|
|
6
|
+
import { CustomElementFor } from '../../tests/component-registry'
|
|
7
|
+
import '@/components/textinput'
|
|
8
|
+
import './checkbox-group'
|
|
9
|
+
|
|
10
|
+
expect.extend(toHaveNoViolations)
|
|
11
|
+
|
|
12
|
+
type TCheckboxGroup = CustomElementFor<'pkt-checkbox-group'>
|
|
13
|
+
type TCheckbox = CustomElementFor<'pkt-checkbox'> & {
|
|
14
|
+
internals: { validity: ValidityState; validationMessage: string }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const settle = async () => {
|
|
18
|
+
for (let i = 0; i < 2; i++) {
|
|
19
|
+
const elements = Array.from(
|
|
20
|
+
document.querySelectorAll<LitElement>('pkt-checkbox-group, pkt-input-wrapper, pkt-checkbox'),
|
|
21
|
+
)
|
|
22
|
+
await Promise.all(elements.map((el) => el.updateComplete))
|
|
23
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const mount = async (markup: string) => {
|
|
28
|
+
document.body.innerHTML = markup
|
|
29
|
+
await settle()
|
|
30
|
+
return document.querySelector('pkt-checkbox-group') as TCheckboxGroup
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const checkbox = (id: string) => document.getElementById(id) as TCheckbox
|
|
34
|
+
const inner = (id: string) => checkbox(id).querySelector('input') as HTMLInputElement
|
|
35
|
+
|
|
36
|
+
const toggle = async (id: string) => {
|
|
37
|
+
fireEvent.click(inner(id))
|
|
38
|
+
await settle()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const options = `
|
|
42
|
+
<pkt-checkbox id="enkelt" value="enkelt" label="Enkeltrom"></pkt-checkbox>
|
|
43
|
+
<pkt-checkbox id="dobbelt" value="dobbelt" label="Dobbeltrom"></pkt-checkbox>
|
|
44
|
+
<pkt-checkbox id="varsler" value="varsler" label="Send meg varsler" isSwitch></pkt-checkbox>
|
|
45
|
+
`
|
|
46
|
+
|
|
47
|
+
describe('pkt-checkbox-group', () => {
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
document.body.innerHTML = ''
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
describe('rendering', () => {
|
|
53
|
+
test('renders the checkboxes inside the fieldset options of an input wrapper', async () => {
|
|
54
|
+
const group = await mount(
|
|
55
|
+
`<pkt-checkbox-group id="rom" label="Romtype">${options}</pkt-checkbox-group>`,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
const container = group.querySelector('fieldset .pkt-inputwrapper__options')
|
|
59
|
+
expect(group.querySelector('legend')).toHaveTextContent('Romtype')
|
|
60
|
+
expect(checkbox('enkelt').parentElement).toBe(container)
|
|
61
|
+
expect(checkbox('varsler').parentElement).toBe(container)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
test('allows switches in the group', async () => {
|
|
65
|
+
await mount(`<pkt-checkbox-group label="Romtype">${options}</pkt-checkbox-group>`)
|
|
66
|
+
|
|
67
|
+
expect(inner('varsler')).toHaveAttribute('role', 'switch')
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('name and defaults', () => {
|
|
72
|
+
test('gives checkboxes without a name the group name', async () => {
|
|
73
|
+
await mount(`<pkt-checkbox-group name="rom" label="Romtype">${options}</pkt-checkbox-group>`)
|
|
74
|
+
|
|
75
|
+
expect(checkbox('enkelt')).toHaveAttribute('name', 'rom')
|
|
76
|
+
expect(checkbox('dobbelt')).toHaveAttribute('name', 'rom')
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('keeps a name set on the checkbox', async () => {
|
|
80
|
+
await mount(
|
|
81
|
+
`<pkt-checkbox-group name="rom" label="Romtype">
|
|
82
|
+
<pkt-checkbox id="enkelt" name="eget" value="enkelt" label="Enkeltrom"></pkt-checkbox>
|
|
83
|
+
</pkt-checkbox-group>`,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
expect(checkbox('enkelt')).toHaveAttribute('name', 'eget')
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
test('turns on tile and error state for every checkbox', async () => {
|
|
90
|
+
await mount(
|
|
91
|
+
`<pkt-checkbox-group label="Romtype" hasTile hasError>${options}</pkt-checkbox-group>`,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
expect(checkbox('dobbelt').querySelector('.pkt-input-check__input')).toHaveClass(
|
|
95
|
+
'pkt-input-check__input--tile',
|
|
96
|
+
)
|
|
97
|
+
expect(inner('dobbelt')).toHaveClass('pkt-input-check__input-checkbox--error')
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('does not pass required on to the checkboxes', async () => {
|
|
101
|
+
await mount(`<pkt-checkbox-group label="Romtype" required>${options}</pkt-checkbox-group>`)
|
|
102
|
+
|
|
103
|
+
expect(checkbox('enkelt').required).toBe(false)
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
describe('value', () => {
|
|
108
|
+
test('is the values of the checked checkboxes in DOM order', async () => {
|
|
109
|
+
const group = await mount(
|
|
110
|
+
`<pkt-checkbox-group label="Romtype">
|
|
111
|
+
<pkt-checkbox id="enkelt" value="enkelt" label="Enkeltrom" checked></pkt-checkbox>
|
|
112
|
+
<pkt-checkbox id="dobbelt" value="dobbelt" label="Dobbeltrom"></pkt-checkbox>
|
|
113
|
+
<pkt-checkbox id="suite" value="suite" label="Suite" checked></pkt-checkbox>
|
|
114
|
+
</pkt-checkbox-group>`,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
expect(group.value).toEqual(['enkelt', 'suite'])
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
test('keeps DOM order regardless of the order they were checked in', async () => {
|
|
121
|
+
const group = await mount(
|
|
122
|
+
`<pkt-checkbox-group label="Romtype">${options}</pkt-checkbox-group>`,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
await toggle('varsler')
|
|
126
|
+
await toggle('enkelt')
|
|
127
|
+
|
|
128
|
+
expect(group.value).toEqual(['enkelt', 'varsler'])
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
test('leaves out disabled checkboxes', async () => {
|
|
132
|
+
const group = await mount(
|
|
133
|
+
`<pkt-checkbox-group label="Romtype">
|
|
134
|
+
<pkt-checkbox id="enkelt" value="enkelt" label="Enkeltrom" checked></pkt-checkbox>
|
|
135
|
+
<pkt-checkbox id="dobbelt" value="dobbelt" label="Dobbeltrom" checked disabled></pkt-checkbox>
|
|
136
|
+
</pkt-checkbox-group>`,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
expect(group.value).toEqual(['enkelt'])
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
test('uses on for a checked checkbox without a value', async () => {
|
|
143
|
+
const group = await mount(
|
|
144
|
+
`<pkt-checkbox-group label="Vilkår">
|
|
145
|
+
<pkt-checkbox id="godta" label="Jeg godtar" checked></pkt-checkbox>
|
|
146
|
+
</pkt-checkbox-group>`,
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
expect(group.value).toEqual(['on'])
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
test('checks the checkboxes listed in the value attribute', async () => {
|
|
153
|
+
const group = await mount(
|
|
154
|
+
`<pkt-checkbox-group label="Romtype" value="enkelt,varsler">${options}</pkt-checkbox-group>`,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
expect(checkbox('enkelt').checked).toBe(true)
|
|
158
|
+
expect(checkbox('dobbelt').checked).toBeFalsy()
|
|
159
|
+
expect(checkbox('varsler').checked).toBe(true)
|
|
160
|
+
expect(group.value).toEqual(['enkelt', 'varsler'])
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
test('checks the matching checkboxes when set from code, without firing events', async () => {
|
|
164
|
+
const group = await mount(
|
|
165
|
+
`<pkt-checkbox-group label="Romtype">${options}</pkt-checkbox-group>`,
|
|
166
|
+
)
|
|
167
|
+
const changed = vi.fn()
|
|
168
|
+
group.addEventListener('change', changed)
|
|
169
|
+
group.addEventListener('value-change', changed)
|
|
170
|
+
|
|
171
|
+
group.value = ['dobbelt']
|
|
172
|
+
await settle()
|
|
173
|
+
|
|
174
|
+
expect(checkbox('dobbelt').checked).toBe(true)
|
|
175
|
+
expect(inner('dobbelt').checked).toBe(true)
|
|
176
|
+
expect(checkbox('enkelt').checked).toBeFalsy()
|
|
177
|
+
expect(changed).not.toHaveBeenCalled()
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
describe('events', () => {
|
|
182
|
+
test('fires value-change on the group with all checked values', async () => {
|
|
183
|
+
const group = await mount(
|
|
184
|
+
`<pkt-checkbox-group label="Romtype">${options}</pkt-checkbox-group>`,
|
|
185
|
+
)
|
|
186
|
+
const fromGroup: unknown[] = []
|
|
187
|
+
group.addEventListener('value-change', (event) => {
|
|
188
|
+
if (event.target === group) fromGroup.push((event as CustomEvent).detail)
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
await toggle('dobbelt')
|
|
192
|
+
await toggle('enkelt')
|
|
193
|
+
await toggle('dobbelt')
|
|
194
|
+
|
|
195
|
+
expect(fromGroup).toEqual([['dobbelt'], ['enkelt', 'dobbelt'], ['enkelt']])
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
test('fires change from the group with all checked values as its value', async () => {
|
|
199
|
+
const group = await mount(
|
|
200
|
+
`<form><pkt-checkbox-group name="rom" label="Romtype">${options}</pkt-checkbox-group></form>`,
|
|
201
|
+
)
|
|
202
|
+
const values: unknown[] = []
|
|
203
|
+
group.addEventListener('change', (event) => {
|
|
204
|
+
expect(event.target).toBe(group)
|
|
205
|
+
values.push((event.target as TCheckboxGroup).value)
|
|
206
|
+
})
|
|
207
|
+
const formChanges = vi.fn()
|
|
208
|
+
group.closest('form')!.addEventListener('change', formChanges)
|
|
209
|
+
|
|
210
|
+
await toggle('dobbelt')
|
|
211
|
+
await toggle('enkelt')
|
|
212
|
+
|
|
213
|
+
expect(values).toEqual([['dobbelt'], ['enkelt', 'dobbelt']])
|
|
214
|
+
expect(formChanges).toHaveBeenCalledTimes(2)
|
|
215
|
+
expect(formChanges.mock.calls.every(([event]) => event.target === group)).toBe(true)
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
test('still fires the events on the checkbox itself', async () => {
|
|
219
|
+
await mount(`<pkt-checkbox-group label="Romtype">${options}</pkt-checkbox-group>`)
|
|
220
|
+
const changed = vi.fn()
|
|
221
|
+
checkbox('enkelt').addEventListener('change', changed)
|
|
222
|
+
|
|
223
|
+
await toggle('enkelt')
|
|
224
|
+
|
|
225
|
+
expect(changed).toHaveBeenCalledTimes(1)
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
test('focus() moves focus to the first checked checkbox, or the first one', async () => {
|
|
229
|
+
const group = await mount(
|
|
230
|
+
`<pkt-checkbox-group label="Romtype">${options}</pkt-checkbox-group>`,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
group.focus()
|
|
234
|
+
expect(document.activeElement).toBe(inner('enkelt'))
|
|
235
|
+
|
|
236
|
+
group.value = ['dobbelt']
|
|
237
|
+
await settle()
|
|
238
|
+
group.focus()
|
|
239
|
+
expect(document.activeElement).toBe(inner('dobbelt'))
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
describe('validation', () => {
|
|
244
|
+
test('makes every checkbox invalid with a custom error until one is checked', async () => {
|
|
245
|
+
await mount(`<pkt-checkbox-group label="Romtype" required>${options}</pkt-checkbox-group>`)
|
|
246
|
+
|
|
247
|
+
for (const id of ['enkelt', 'dobbelt', 'varsler']) {
|
|
248
|
+
expect(checkbox(id).internals.validity.customError).toBe(true)
|
|
249
|
+
expect(checkbox(id).internals.validity.valueMissing).toBe(false)
|
|
250
|
+
expect(checkbox(id).internals.validationMessage).toBe('Velg minst ett alternativ')
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
await toggle('dobbelt')
|
|
254
|
+
|
|
255
|
+
for (const id of ['enkelt', 'dobbelt', 'varsler']) {
|
|
256
|
+
expect(checkbox(id).internals.validity.valid).toBe(true)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
await toggle('dobbelt')
|
|
260
|
+
|
|
261
|
+
expect(checkbox('enkelt').internals.validity.customError).toBe(true)
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
test('counts a checked value set from code', async () => {
|
|
265
|
+
const group = await mount(
|
|
266
|
+
`<pkt-checkbox-group label="Romtype" required>${options}</pkt-checkbox-group>`,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
group.value = ['enkelt']
|
|
270
|
+
await settle()
|
|
271
|
+
|
|
272
|
+
expect(checkbox('dobbelt').internals.validity.valid).toBe(true)
|
|
273
|
+
})
|
|
274
|
+
|
|
275
|
+
test('clears the custom error when the group is no longer required', async () => {
|
|
276
|
+
const group = await mount(
|
|
277
|
+
`<pkt-checkbox-group label="Romtype" required>${options}</pkt-checkbox-group>`,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
group.required = false
|
|
281
|
+
await settle()
|
|
282
|
+
|
|
283
|
+
expect(checkbox('enkelt').internals.validity.valid).toBe(true)
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
test('keeps the rule of a required checkbox in a required group', async () => {
|
|
287
|
+
await mount(
|
|
288
|
+
`<pkt-checkbox-group label="Vilkår" required>
|
|
289
|
+
<pkt-checkbox id="vilkar" value="vilkar" label="Vilkår" required></pkt-checkbox>
|
|
290
|
+
<pkt-checkbox id="nyhetsbrev" value="nyhetsbrev" label="Nyhetsbrev"></pkt-checkbox>
|
|
291
|
+
</pkt-checkbox-group>`,
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
await toggle('nyhetsbrev')
|
|
295
|
+
|
|
296
|
+
expect(checkbox('nyhetsbrev').internals.validity.valid).toBe(true)
|
|
297
|
+
expect(checkbox('vilkar').internals.validity.valueMissing).toBe(true)
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
test('leaves the checkboxes valid when the group is not required', async () => {
|
|
301
|
+
await mount(`<pkt-checkbox-group label="Romtype">${options}</pkt-checkbox-group>`)
|
|
302
|
+
|
|
303
|
+
expect(checkbox('enkelt').internals.validity.valid).toBe(true)
|
|
304
|
+
})
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
describe('disabled', () => {
|
|
308
|
+
test('disables the fieldset', async () => {
|
|
309
|
+
const group = await mount(
|
|
310
|
+
`<pkt-checkbox-group label="Romtype" disabled>${options}</pkt-checkbox-group>`,
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
expect(group.querySelector('fieldset')).toHaveAttribute('disabled', '')
|
|
314
|
+
})
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
describe('a text field for an other option', () => {
|
|
318
|
+
const settleAll = async () => {
|
|
319
|
+
for (let i = 0; i < 3; i++) {
|
|
320
|
+
const elements = Array.from(document.querySelectorAll<LitElement>('*')).filter(
|
|
321
|
+
(el) => 'updateComplete' in el,
|
|
322
|
+
)
|
|
323
|
+
await Promise.all(elements.map((el) => el.updateComplete))
|
|
324
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const mountOther = async () => {
|
|
329
|
+
document.body.innerHTML = `
|
|
330
|
+
<form id="skjema">
|
|
331
|
+
<pkt-checkbox-group id="gruppe" name="varsling" label="Spørsmål">
|
|
332
|
+
<pkt-checkbox id="epost" value="epost" label="E-post"></pkt-checkbox>
|
|
333
|
+
<pkt-checkbox id="annet" value="annet" label="Annet"></pkt-checkbox>
|
|
334
|
+
<pkt-textinput id="annet-tekst" name="varsling-annet" label="Hva annet?" hidden></pkt-textinput>
|
|
335
|
+
</pkt-checkbox-group>
|
|
336
|
+
<button>Utenfor</button>
|
|
337
|
+
</form>`
|
|
338
|
+
await settleAll()
|
|
339
|
+
const group = document.getElementById('gruppe') as HTMLElement & { value: unknown }
|
|
340
|
+
const field = document.getElementById('annet-tekst') as HTMLElement
|
|
341
|
+
group.addEventListener('change', (event) => {
|
|
342
|
+
if (event.target === group) field.hidden = !String(group.value).includes('annet')
|
|
343
|
+
})
|
|
344
|
+
return { group, field, input: () => field.querySelector('input') as HTMLInputElement }
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
test('shows the text field inside the group when the other option is chosen', async () => {
|
|
348
|
+
const { field } = await mountOther()
|
|
349
|
+
|
|
350
|
+
fireEvent.click(document.getElementById('annet')!.querySelector('input')!)
|
|
351
|
+
await settleAll()
|
|
352
|
+
|
|
353
|
+
expect(field.hidden).toBe(false)
|
|
354
|
+
expect(field.closest('.pkt-inputwrapper__options')).toBeInTheDocument()
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
test('keeps the text field out of the group value, and lets its events through', async () => {
|
|
358
|
+
const { group, input } = await mountOther()
|
|
359
|
+
fireEvent.click(document.getElementById('annet')!.querySelector('input')!)
|
|
360
|
+
await settleAll()
|
|
361
|
+
const targets: string[] = []
|
|
362
|
+
group.addEventListener('change', (event) => targets.push((event.target as Element).id))
|
|
363
|
+
|
|
364
|
+
input().value = 'Brevdue'
|
|
365
|
+
fireEvent.input(input())
|
|
366
|
+
fireEvent.change(input())
|
|
367
|
+
await settleAll()
|
|
368
|
+
|
|
369
|
+
expect(group.value).toEqual(['annet'])
|
|
370
|
+
expect(targets).toEqual(['annet-tekst'])
|
|
371
|
+
expect(
|
|
372
|
+
Array.from(new FormData(document.getElementById('skjema') as HTMLFormElement).entries()),
|
|
373
|
+
).toEqual([
|
|
374
|
+
['varsling', 'annet'],
|
|
375
|
+
['varsling-annet', 'Brevdue'],
|
|
376
|
+
])
|
|
377
|
+
})
|
|
378
|
+
|
|
379
|
+
test('fires blur only when focus leaves the group, also from the text field', async () => {
|
|
380
|
+
const { group, input } = await mountOther()
|
|
381
|
+
fireEvent.click(document.getElementById('annet')!.querySelector('input')!)
|
|
382
|
+
await settleAll()
|
|
383
|
+
const blurs: Element[] = []
|
|
384
|
+
group.addEventListener('blur', (event) => {
|
|
385
|
+
if (event.target === group) blurs.push(event.target as Element)
|
|
386
|
+
})
|
|
387
|
+
|
|
388
|
+
document.getElementById('annet')!.querySelector('input')!.focus()
|
|
389
|
+
input().focus()
|
|
390
|
+
expect(blurs).toEqual([])
|
|
391
|
+
|
|
392
|
+
document.querySelector('button')!.focus()
|
|
393
|
+
expect(blurs).toEqual([group])
|
|
394
|
+
})
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
describe('accessibility', () => {
|
|
398
|
+
test('has no axe violations', async () => {
|
|
399
|
+
const group = await mount(
|
|
400
|
+
`<pkt-checkbox-group id="rom" label="Romtype" helptext="Velg alle som passer">${options}</pkt-checkbox-group>`,
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
expect(await axe(group)).toHaveNoViolations()
|
|
404
|
+
})
|
|
405
|
+
})
|
|
406
|
+
})
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { provide } from '@lit/context'
|
|
2
|
+
import { customElement, property, state } from 'lit/decorators.js'
|
|
3
|
+
import {
|
|
4
|
+
optionChecked,
|
|
5
|
+
optionDisabled,
|
|
6
|
+
optionValue,
|
|
7
|
+
PktOptionGroupElement,
|
|
8
|
+
type TOption,
|
|
9
|
+
} from '@/base-elements/option-group-element'
|
|
10
|
+
import { checkboxGroupContext, type CheckboxGroupContext } from './checkbox-group-context'
|
|
11
|
+
import '@/components/checkbox'
|
|
12
|
+
|
|
13
|
+
export class PktCheckboxGroup extends PktOptionGroupElement {
|
|
14
|
+
protected readonly optionSelector = 'pkt-checkbox'
|
|
15
|
+
|
|
16
|
+
@provide({ context: checkboxGroupContext })
|
|
17
|
+
@state()
|
|
18
|
+
protected groupContext: CheckboxGroupContext = { name: '', hasTile: false, hasError: false }
|
|
19
|
+
|
|
20
|
+
private storedValue: string[] | null = null
|
|
21
|
+
private validityApplied = false
|
|
22
|
+
|
|
23
|
+
@property({ type: String })
|
|
24
|
+
get value(): string[] {
|
|
25
|
+
return this.options()
|
|
26
|
+
.filter((option) => optionChecked(option) && !optionDisabled(option))
|
|
27
|
+
.map(optionValue)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
set value(newValue: string | string[] | null | undefined) {
|
|
31
|
+
const oldValue = this.value
|
|
32
|
+
this.storedValue = Array.isArray(newValue) ? newValue : newValue ? newValue.split(',') : []
|
|
33
|
+
this.applyStoredValue(this.options())
|
|
34
|
+
this.requestUpdate('value', oldValue)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected get hasStoredValue(): boolean {
|
|
38
|
+
return this.storedValue !== null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected storeCurrentValue(): void {
|
|
42
|
+
this.storedValue = this.value
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
protected applyStoredValue(options: TOption[]): void {
|
|
46
|
+
options.forEach((option) => {
|
|
47
|
+
const checked = !!this.storedValue?.includes(optionValue(option))
|
|
48
|
+
if (optionChecked(option) !== checked) option.checked = checked
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
protected syncValidity(): void {
|
|
53
|
+
if (!this.required && !this.validityApplied) return
|
|
54
|
+
this.validityApplied = this.required
|
|
55
|
+
const options = this.options()
|
|
56
|
+
const missing =
|
|
57
|
+
this.required && !options.some((option) => optionChecked(option) && !optionDisabled(option))
|
|
58
|
+
const message = missing ? this.pktStrings.get('validation').checkboxGroupValueMissing : ''
|
|
59
|
+
options.forEach((option) => option.setGroupValidity?.(message))
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
customElement('pkt-checkbox-group')(PktCheckboxGroup)
|
|
65
|
+
} catch (e) {
|
|
66
|
+
console.warn('Forsøker å definere <pkt-checkbox-group>, men den er allerede definert')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default PktCheckboxGroup
|
|
@@ -313,7 +313,7 @@ export class PktCombobox extends ComboboxHandlers implements IPktCombobox {
|
|
|
313
313
|
this.inputRef.value.value = ''
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
-
this.
|
|
316
|
+
this.setFormValue('')
|
|
317
317
|
this.internals.ariaInvalid = 'false'
|
|
318
318
|
this.requestUpdate()
|
|
319
319
|
}
|
|
@@ -612,7 +612,7 @@ export class PktDatepicker extends PktInputElement<Props> {
|
|
|
612
612
|
public clearInputValue() {
|
|
613
613
|
this._value = []
|
|
614
614
|
this.value = ''
|
|
615
|
-
this.
|
|
615
|
+
this.setFormValue(this.value)
|
|
616
616
|
this.dispatchEvent(new Event('change', { bubbles: true, composed: true }))
|
|
617
617
|
this.dispatchEvent(
|
|
618
618
|
new CustomEvent('value-change', {
|
package/src/components/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { PktCard } from '@/components/card'
|
|
|
9
9
|
export { PktCombobox } from './combobox'
|
|
10
10
|
export { PktConsent } from './consent'
|
|
11
11
|
export { PktCheckbox } from '@/components/checkbox'
|
|
12
|
+
export { PktCheckboxGroup } from '@/components/checkbox-group'
|
|
12
13
|
export { PktFileUpload } from '@/components/fileupload'
|
|
13
14
|
export { PktDateTags } from '@/components/datepicker/date-tags.js'
|
|
14
15
|
export { PktDatepicker } from '@/components/datepicker/datepicker.js'
|
|
@@ -31,6 +32,7 @@ export { PktMessagebox } from '@/components/messagebox'
|
|
|
31
32
|
export { PktModal } from '@/components/modal'
|
|
32
33
|
export { PktProgressbar } from '@/components/progressbar'
|
|
33
34
|
export { PktRadioButton } from '@/components/radiobutton'
|
|
35
|
+
export { PktRadioGroup } from '@/components/radio-group'
|
|
34
36
|
// TODO: Avklar om RadioButton kan eksporteres som *kun* PktRadiobutton
|
|
35
37
|
export { PktRadioButton as PktRadiobutton } from '@/components/radiobutton'
|
|
36
38
|
export { PktTag } from '@/components/tag'
|
|
@@ -232,7 +232,11 @@ export class PktInputWrapper extends PktElementWithSlot<Props> {
|
|
|
232
232
|
|
|
233
233
|
const wrapperElement = () => {
|
|
234
234
|
return this.hasFieldset
|
|
235
|
-
? html`<fieldset
|
|
235
|
+
? html`<fieldset
|
|
236
|
+
class="pkt-inputwrapper__fieldset"
|
|
237
|
+
aria-describedby="${describedBy}"
|
|
238
|
+
?disabled=${this.disabled}
|
|
239
|
+
>
|
|
236
240
|
${inputContent()}
|
|
237
241
|
</fieldset>`
|
|
238
242
|
: html`<div class="pkt-inputwrapper__fieldset">${inputContent()}</div>`
|
|
@@ -36,6 +36,14 @@ const COMPONENTS = {
|
|
|
36
36
|
elements: 'packages/elements/src/components/fileupload/fileupload.ts',
|
|
37
37
|
react: 'packages/react/src/components/fileupload/FileUpload.tsx',
|
|
38
38
|
},
|
|
39
|
+
radioGroup: {
|
|
40
|
+
elements: 'packages/elements/src/base-elements/option-group-element.ts',
|
|
41
|
+
react: 'packages/react/src/components/radiogroup/RadioGroup.tsx',
|
|
42
|
+
},
|
|
43
|
+
checkboxGroup: {
|
|
44
|
+
elements: 'packages/elements/src/base-elements/option-group-element.ts',
|
|
45
|
+
react: 'packages/react/src/components/checkboxgroup/CheckboxGroup.tsx',
|
|
46
|
+
},
|
|
39
47
|
} as const
|
|
40
48
|
|
|
41
49
|
// Props som med vilje ikke videresendes, med begrunnelse.
|
|
@@ -44,16 +52,22 @@ const OMITTED: Record<string, Partial<Record<keyof typeof COMPONENTS, string>>>
|
|
|
44
52
|
select: 'ingenting å telle i en select',
|
|
45
53
|
timepicker: 'ingenting å telle',
|
|
46
54
|
fileupload: 'ingenting å telle',
|
|
55
|
+
radioGroup: 'ingenting å telle',
|
|
56
|
+
checkboxGroup: 'ingenting å telle',
|
|
47
57
|
},
|
|
48
58
|
counterCurrent: {
|
|
49
59
|
select: 'se counter',
|
|
50
60
|
timepicker: 'se counter',
|
|
51
61
|
fileupload: 'se counter',
|
|
62
|
+
radioGroup: 'se counter',
|
|
63
|
+
checkboxGroup: 'se counter',
|
|
52
64
|
},
|
|
53
65
|
counterMaxLength: {
|
|
54
66
|
select: 'se counter',
|
|
55
67
|
timepicker: 'se counter',
|
|
56
68
|
fileupload: 'se counter',
|
|
69
|
+
radioGroup: 'se counter',
|
|
70
|
+
checkboxGroup: 'se counter',
|
|
57
71
|
},
|
|
58
72
|
counterPosition: {
|
|
59
73
|
textinput: 'teller over feltet er aldri støttet',
|
|
@@ -63,6 +77,8 @@ const OMITTED: Record<string, Partial<Record<keyof typeof COMPONENTS, string>>>
|
|
|
63
77
|
datepicker: 'teller over feltet er aldri støttet',
|
|
64
78
|
timepicker: 'teller over feltet er aldri støttet',
|
|
65
79
|
fileupload: 'teller over feltet er aldri støttet',
|
|
80
|
+
radioGroup: 'ingenting å telle',
|
|
81
|
+
checkboxGroup: 'ingenting å telle',
|
|
66
82
|
},
|
|
67
83
|
layout: {
|
|
68
84
|
textinput: 'layout gjelder alternativer i en gruppe, ikke ett felt',
|
|
@@ -76,9 +92,18 @@ const OMITTED: Record<string, Partial<Record<keyof typeof COMPONENTS, string>>>
|
|
|
76
92
|
hasFieldset: {
|
|
77
93
|
fileupload: 'ikke støttet',
|
|
78
94
|
},
|
|
79
|
-
inline: {
|
|
95
|
+
inline: {
|
|
96
|
+
fileupload: 'ikke et enkelt felt på en linje',
|
|
97
|
+
radioGroup: 'ikke et enkelt felt på en linje, retningen styres av layout',
|
|
98
|
+
checkboxGroup: 'ikke et enkelt felt på en linje, retningen styres av layout',
|
|
99
|
+
},
|
|
80
100
|
useWrapper: { fileupload: 'wrapperen rendres bare når label er satt' },
|
|
81
|
-
ariaDescribedby: {
|
|
101
|
+
ariaDescribedby: {
|
|
102
|
+
combobox: 'ikke implementert ennå',
|
|
103
|
+
fileupload: 'ikke implementert ennå',
|
|
104
|
+
radioGroup: 'fieldset beskrives av hjelpeteksten og feilmeldingen',
|
|
105
|
+
checkboxGroup: 'fieldset beskrives av hjelpeteksten og feilmeldingen',
|
|
106
|
+
},
|
|
82
107
|
errorMessage: { fileupload: 'egen feilvisning' },
|
|
83
108
|
size: { fileupload: 'har ikke størrelsesvarianter' },
|
|
84
109
|
role: {},
|
|
@@ -72,7 +72,7 @@ describe('PktMessagebox', () => {
|
|
|
72
72
|
expect(messagebox.closable).toBe(false)
|
|
73
73
|
expect(messagebox.compact).toBe(false)
|
|
74
74
|
expect(messagebox.title).toBe('')
|
|
75
|
-
expect(messagebox.skin).
|
|
75
|
+
expect(messagebox.skin).toBe('beige')
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
test('sets properties correctly', async () => {
|