@oslokommune/punkt-react 12.43.2 → 13.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oslokommune/punkt-react",
3
- "version": "12.43.2",
3
+ "version": "13.0.0",
4
4
  "description": "React komponentbibliotek til Punkt, et designsystem laget av Oslo Origo",
5
5
  "homepage": "https://punkt.oslo.kommune.no",
6
6
  "author": "Team Designsystem, Oslo Origo",
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "@lit-labs/ssr-dom-shim": "^1.2.1",
40
40
  "@lit/react": "^1.0.7",
41
- "@oslokommune/punkt-elements": "^12.43.2",
41
+ "@oslokommune/punkt-elements": "^13.0.0",
42
42
  "angular-html-parser": "^6.0.2",
43
43
  "html-format": "^1.1.7",
44
44
  "prettier": "^3.3.3",
@@ -48,8 +48,8 @@
48
48
  },
49
49
  "devDependencies": {
50
50
  "@babel/plugin-proposal-private-property-in-object": "^7.18.6",
51
- "@oslokommune/punkt-assets": "^12.43.2",
52
- "@oslokommune/punkt-css": "^12.43.2",
51
+ "@oslokommune/punkt-assets": "^13.0.0",
52
+ "@oslokommune/punkt-css": "^13.0.0",
53
53
  "@testing-library/jest-dom": "^6.5.0",
54
54
  "@testing-library/react": "^16.0.1",
55
55
  "@testing-library/user-event": "^14.5.2",
@@ -112,5 +112,5 @@
112
112
  "url": "https://github.com/oslokommune/punkt/issues"
113
113
  },
114
114
  "license": "MIT",
115
- "gitHead": "e6129504ff4bd5c109780783832e2a02d763f9dc"
115
+ "gitHead": "8012adb5b795a7ab26d844a3311435fef05121c4"
116
116
  }
@@ -12,8 +12,6 @@ describe('PktCheckbox', () => {
12
12
  it('renders a basic checkbox with label', async () => {
13
13
  const { getByLabelText } = render(<PktCheckbox id="myCheckbox" label="My Checkbox" />)
14
14
 
15
- await window.customElements.whenDefined('pkt-checkbox')
16
-
17
15
  // Check if the label is present in the document
18
16
  const checkboxLabel = getByLabelText('My Checkbox')
19
17
  expect(checkboxLabel).toBeInTheDocument()
@@ -22,8 +20,6 @@ describe('PktCheckbox', () => {
22
20
  it('renders an error state checkbox', async () => {
23
21
  render(<PktCheckbox id="myCheckbox" label="My Checkbox" hasError />)
24
22
 
25
- await window.customElements.whenDefined('pkt-checkbox')
26
-
27
23
  const checkbox = screen.getByRole('checkbox', { name: 'My Checkbox' })
28
24
 
29
25
  // Verify that the error class is applied to the checkbox
@@ -33,8 +29,6 @@ describe('PktCheckbox', () => {
33
29
  it('renders as Switch', async () => {
34
30
  render(<PktCheckbox id="myCheckbox" label="My Checkbox" isSwitch />)
35
31
 
36
- await window.customElements.whenDefined('pkt-checkbox')
37
-
38
32
  const checkbox = screen.getByRole('switch', { name: 'My Checkbox' })
39
33
 
40
34
  // Verify that the error class is applied to the checkbox
@@ -44,7 +38,6 @@ describe('PktCheckbox', () => {
44
38
  test('renders a default checked checkbox', async () => {
45
39
  const { getByRole } = render(<PktCheckbox id="myCheckbox" label="My Checkbox" defaultChecked={true} />)
46
40
 
47
- await window.customElements.whenDefined('pkt-checkbox')
48
41
  // Find the checkbox element by its "checkbox" role
49
42
  const checkbox = getByRole('checkbox') as HTMLInputElement
50
43
  // Verify that the checkbox is initially checked
@@ -55,8 +48,6 @@ describe('PktCheckbox', () => {
55
48
  const onClickMock = jest.fn()
56
49
  const { getByLabelText } = render(<PktCheckbox id="myCheckbox" label="My Checkbox" onClick={onClickMock} />)
57
50
 
58
- await window.customElements.whenDefined('pkt-checkbox')
59
-
60
51
  // Get the checkbox label element
61
52
  const checkboxLabel = getByLabelText('My Checkbox')
62
53
 
@@ -70,7 +61,7 @@ describe('PktCheckbox', () => {
70
61
  describe('accessibility', () => {
71
62
  it('renders with no wcag errors with axe', async () => {
72
63
  const { container } = render(<PktCheckbox id="accessibilityTest" label="My checkkbox"></PktCheckbox>)
73
- await window.customElements.whenDefined('pkt-checkbox')
64
+
74
65
  const results = await axe(container)
75
66
 
76
67
  expect(results).toHaveNoViolations()
@@ -1,49 +1,60 @@
1
- 'use client'
1
+ import React, { ForwardedRef, forwardRef } from 'react'
2
2
 
3
- import React, {
4
- ChangeEventHandler,
5
- FocusEventHandler,
6
- ForwardedRef,
7
- ForwardRefExoticComponent,
8
- InputHTMLAttributes,
9
- ReactNode,
10
- } from 'react'
11
- import { createComponent, EventName } from '@lit/react'
12
- import { PktCheckbox as PktElCheckbox } from '@oslokommune/punkt-elements'
13
- import { PktEventWithTarget } from '@/interfaces/IPktElements'
14
-
15
- export interface IPktCheckbox extends InputHTMLAttributes<HTMLInputElement> {
3
+ export interface IPktCheckbox extends React.InputHTMLAttributes<HTMLInputElement> {
16
4
  id: string
17
- name?: string
18
- label: string
19
5
  hasTile?: boolean
6
+ disabled?: boolean
7
+ label?: string
8
+ checkHelptext?: string
20
9
  hasError?: boolean
21
10
  defaultChecked?: boolean
22
- disabled?: boolean
23
11
  value?: string
24
- checkHelptext?: string | ReactNode | ReactNode[]
25
12
  isSwitch?: boolean
26
13
  hideLabel?: boolean
27
14
  labelPosition?: 'right' | 'left'
28
15
  checked?: boolean
29
- ref?: ForwardedRef<HTMLInputElement>
30
- onChange?: ChangeEventHandler<HTMLInputElement>
31
- onInput?: ChangeEventHandler<HTMLInputElement>
32
- onBlur?: FocusEventHandler<HTMLInputElement>
33
- onFocus?: FocusEventHandler<HTMLInputElement>
34
- onValueChange?: (e: CustomEvent) => void
35
16
  }
36
17
 
37
- export const PktCheckbox = createComponent({
38
- tagName: 'pkt-checkbox',
39
- elementClass: PktElCheckbox,
40
- react: React,
41
- displayName: 'PktCheckbox',
42
- events: {
43
- onChange: 'change' as EventName<PktEventWithTarget>,
44
- onInput: 'input' as EventName<PktEventWithTarget>,
45
- onBlur: 'blur' as EventName<FocusEvent>,
46
- onFocus: 'focus' as EventName<FocusEvent>,
47
- onValueChange: 'valueChange' as EventName<CustomEvent>,
18
+ export const PktCheckbox = forwardRef(
19
+ (
20
+ {
21
+ id,
22
+ hasTile = false,
23
+ disabled = false,
24
+ label,
25
+ checkHelptext,
26
+ hasError = false,
27
+ className,
28
+ isSwitch = false,
29
+ hideLabel = false,
30
+ labelPosition,
31
+ checked,
32
+ ...props
33
+ }: IPktCheckbox,
34
+ ref: ForwardedRef<HTMLInputElement>,
35
+ ): React.ReactElement => {
36
+ const classes = [className, 'pkt-input-check'].filter(Boolean).join(' ')
37
+
38
+ return (
39
+ <div className={classes}>
40
+ <div className={`pkt-input-check__input ${hasTile ? 'pkt-input-check__input--tile' : ''}`}>
41
+ <input
42
+ role={isSwitch ? 'switch' : 'checkbox'}
43
+ ref={ref}
44
+ className={`pkt-input-check__input-checkbox ${hasError ? 'pkt-input-check__input-checkbox--error' : ''}`}
45
+ type="checkbox"
46
+ id={id}
47
+ disabled={disabled}
48
+ {...props}
49
+ />
50
+ <label className="pkt-input-check__input-label" htmlFor={id}>
51
+ {label}
52
+ {checkHelptext && <div className="pkt-input-check__input-helptext">{checkHelptext}</div>}
53
+ </label>
54
+ </div>
55
+ </div>
56
+ )
48
57
  },
49
- }) as ForwardRefExoticComponent<IPktCheckbox>
58
+ )
59
+
60
+ PktCheckbox.displayName = 'PktCheckbox'
@@ -1,15 +1,14 @@
1
1
  'use client'
2
2
 
3
- import React, { FC, forwardRef, ForwardRefExoticComponent, LegacyRef, ReactElement, ReactNode } from 'react'
4
- import { createComponent, EventName } from '@lit/react'
5
- import { PktInputWrapper as PktEl } from '@oslokommune/punkt-elements'
6
- import type { PktElType } from '@/interfaces/IPktElements'
3
+ import { ForwardedRef, forwardRef, ReactNode, RefAttributes, useState, MouseEvent } from 'react'
4
+ import { PktAlert } from '../alert/Alert'
5
+ import { PktButton } from '../button/Button'
7
6
 
8
- export interface IPktInputWrapper extends Omit<PktElType, 'ref'> {
7
+ export interface IPktInputWrapper extends RefAttributes<HTMLElement> {
9
8
  forId: string
10
9
  label: string
11
- helptext?: string | ReactNode | ReactNode[]
12
- helptextDropdown?: string | ReactNode | ReactNode[]
10
+ helptext?: string | ReactNode
11
+ helptextDropdown?: string | ReactNode
13
12
  helptextDropdownButton?: string
14
13
  counter?: boolean
15
14
  counterCurrent?: number
@@ -19,35 +18,186 @@ export interface IPktInputWrapper extends Omit<PktElType, 'ref'> {
19
18
  requiredTag?: boolean
20
19
  requiredText?: string
21
20
  hasError?: boolean
22
- errorMessage?: string | ReactNode | ReactNode[]
21
+ errorMessage?: string | ReactNode
23
22
  disabled?: boolean
24
23
  inline?: boolean
25
24
  ariaDescribedby?: string
26
25
  useWrapper?: boolean
26
+ children?: ReactNode
27
+ className?: string
27
28
  hasFieldset?: boolean
28
- ref?: LegacyRef<PktEl>
29
- onToggleHelpText?: (e: CustomEvent) => void
29
+ role?: string
30
+ counterPosition?: 'top' | 'bottom'
30
31
  }
31
32
 
32
- const LitComponent: ForwardRefExoticComponent<IPktInputWrapper> = createComponent({
33
- tagName: 'pkt-input-wrapper',
34
- elementClass: PktEl,
35
- react: React,
36
- displayName: 'PktInputWrapper',
37
- events: {
38
- onToggleHelpText: 'toggleHelpText' as EventName<CustomEvent>,
39
- },
40
- })
33
+ export const PktInputWrapper = forwardRef(
34
+ (
35
+ {
36
+ forId,
37
+ label,
38
+ helptext,
39
+ helptextDropdown,
40
+ helptextDropdownButton,
41
+ counter,
42
+ counterCurrent = 0,
43
+ counterMaxLength,
44
+ optionalTag = false,
45
+ optionalText = 'Valgfritt',
46
+ requiredTag = false,
47
+ requiredText = 'Må fylles ut',
48
+ hasError = false,
49
+ errorMessage,
50
+ disabled = false,
51
+ inline = false,
52
+ ariaDescribedby,
53
+ useWrapper = true,
54
+ children,
55
+ className = '',
56
+ hasFieldset = false,
57
+ role = 'group',
58
+ counterPosition = 'bottom',
59
+ }: IPktInputWrapper,
60
+ ref: ForwardedRef<HTMLDivElement>,
61
+ ) => {
62
+ const [isHelpTextOpen, setIsHelpTextOpen] = useState(false)
41
63
 
42
- export const PktInputWrapper: FC<IPktInputWrapper> = forwardRef(
43
- ({ children, helptext, ...props }: IPktInputWrapper, ref: LegacyRef<PktEl>): ReactElement => {
44
- return (
45
- <LitComponent ref={ref} {...props}>
46
- <div className="pkt-contents" slot="helptext">
47
- {helptext}
64
+ const tagText = optionalTag ? optionalText : requiredTag ? requiredText : null
65
+
66
+ const describedBy = ariaDescribedby || (helptext ? `${forId}-helptext` : undefined)
67
+ const showCounter = !!counter
68
+ const counterTop = showCounter && counterPosition === 'top'
69
+ const counterBottom = showCounter && counterPosition === 'bottom'
70
+
71
+ const toggleHelpText = () => setIsHelpTextOpen((prev) => !prev)
72
+
73
+ const wrapperClasses = [
74
+ 'pkt-inputwrapper',
75
+ className,
76
+ hasError ? 'pkt-inputwrapper--error' : '',
77
+ disabled ? 'pkt-inputwrapper--disabled' : '',
78
+ inline ? 'pkt-inputwrapper--inline' : '',
79
+ ]
80
+ .filter(Boolean)
81
+ .join(' ')
82
+
83
+ const tagClasses = [
84
+ 'pkt-tag',
85
+ 'pkt-tag--small',
86
+ 'pkt-tag--thin-text',
87
+ optionalTag && 'pkt-tag--blue-light',
88
+ !optionalTag && requiredTag && 'pkt-tag--beige',
89
+ ]
90
+ .filter(Boolean)
91
+ .join(' ')
92
+
93
+ const Counter = () =>
94
+ showCounter ? (
95
+ <div className="pkt-input__counter" aria-live="polite" aria-atomic="true">
96
+ {counterCurrent}
97
+ {counterMaxLength ? `/${counterMaxLength}` : ''}
48
98
  </div>
49
- <div className="pkt-contents">{children}</div>
50
- </LitComponent>
99
+ ) : null
100
+
101
+ const renderLabel = () => {
102
+ const labelContent = (
103
+ <>
104
+ {label} {tagText && <span className={tagClasses}>{tagText}</span>}
105
+ </>
106
+ )
107
+
108
+ if (!useWrapper) {
109
+ return (
110
+ <label htmlFor={forId} className="pkt-sr-only" aria-describedby={describedBy} id={`${forId}-label`}>
111
+ {label}
112
+ </label>
113
+ )
114
+ }
115
+
116
+ if (hasFieldset) {
117
+ return (
118
+ <legend className="pkt-inputwrapper__legend" id={`${forId}-label`}>
119
+ {labelContent}
120
+ </legend>
121
+ )
122
+ }
123
+
124
+ return (
125
+ <label className="pkt-inputwrapper__label" htmlFor={forId} aria-describedby={describedBy} id={`${forId}-label`}>
126
+ {labelContent}
127
+ </label>
128
+ )
129
+ }
130
+
131
+ const renderHelptext = () => {
132
+ if (!helptext && !helptextDropdown) return null
133
+
134
+ return (
135
+ <>
136
+ {helptext && (
137
+ <div className="pkt-inputwrapper__helptext" id={`${forId}-helptext`}>
138
+ {helptext}
139
+ </div>
140
+ )}
141
+ {helptextDropdown && (
142
+ <div className="pkt-inputwrapper__helptext-expandable">
143
+ <PktButton
144
+ skin="tertiary"
145
+ size="small"
146
+ variant="icon-right"
147
+ iconName={isHelpTextOpen ? 'chevron-thin-up' : 'chevron-thin-down'}
148
+ className="pkt-link pkt-link--icon-right"
149
+ onClick={toggleHelpText}
150
+ >
151
+ <span
152
+ dangerouslySetInnerHTML={{
153
+ __html: helptextDropdownButton ?? 'Les mer <span class="pkt-sr-only">om inputfeltet</span>',
154
+ }}
155
+ />
156
+ </PktButton>
157
+ <div
158
+ className={`pkt-inputwrapper__helptext ${
159
+ isHelpTextOpen
160
+ ? 'pkt-inputwrapper__helptext-expandable-open'
161
+ : 'pkt-inputwrapper__helptext-expandable-closed'
162
+ }`}
163
+ >
164
+ {helptextDropdown}
165
+ </div>
166
+ </div>
167
+ )}
168
+ </>
169
+ )
170
+ }
171
+
172
+ const content = (
173
+ <>
174
+ {renderLabel()}
175
+ {renderHelptext()}
176
+ {counterTop && <Counter />}
177
+ {children}
178
+ {counterBottom && <Counter />}
179
+ {hasError && errorMessage && (
180
+ <div className="pkt-inputwrapper__alert-wrapper">
181
+ <PktAlert skin="error" aria-live="assertive" role="alert" id={`${forId}-error`} compact>
182
+ {errorMessage}
183
+ </PktAlert>
184
+ </div>
185
+ )}
186
+ </>
187
+ )
188
+
189
+ return (
190
+ <div className={wrapperClasses} ref={ref} role={role}>
191
+ {hasFieldset ? (
192
+ <fieldset className="pkt-inputwrapper__fieldset" aria-describedby={describedBy}>
193
+ {content}
194
+ </fieldset>
195
+ ) : (
196
+ <div className="pkt-inputwrapper__fieldset">{content}</div>
197
+ )}
198
+ </div>
51
199
  )
52
200
  },
53
201
  )
202
+
203
+ PktInputWrapper.displayName = 'PktInputWrapper'
@@ -12,9 +12,8 @@ describe('PktRadiobutton', () => {
12
12
  // Test case for rendering a basic radiogroup
13
13
  it('renders without errors', async () => {
14
14
  const { container } = render(<PktRadioButton id="radio1" name="radioGroup" label="Option 1" value="option1" />)
15
- await window.customElements.whenDefined('pkt-radiobutton')
16
15
 
17
- const inputElement = container.querySelector('pkt-radiobutton')
16
+ const inputElement = container.querySelector('input[type="radio"]')
18
17
  expect(inputElement).toBeInTheDocument()
19
18
  expect(inputElement).toHaveAttribute('id', 'radio1')
20
19
  expect(inputElement).toHaveAttribute('name', 'radioGroup')
@@ -37,11 +36,8 @@ describe('PktRadiobutton', () => {
37
36
  </PktInputWrapper>,
38
37
  )
39
38
 
40
- await window.customElements.whenDefined('pkt-radiobutton')
41
- await window.customElements.whenDefined('pkt-input-wrapper')
42
-
43
- const option1 = container.querySelector('pkt-radiobutton[id="radio1"]')
44
- const option2 = container.querySelector('pkt-radiobutton[id="radio2"]')
39
+ const option1 = container.querySelector('input[type="radio"][id="radio1"]')
40
+ const option2 = container.querySelector('input[type="radio"][id="radio2"]')
45
41
 
46
42
  expect(option1).toBeInTheDocument()
47
43
  expect(option2).toBeInTheDocument()
@@ -62,7 +58,7 @@ describe('PktRadiobutton', () => {
62
58
  const { container } = render(
63
59
  <PktRadioButton name="accessibilitytest" id="accessibilityTest" label="My checkkbox" />,
64
60
  )
65
- await window.customElements.whenDefined('pkt-radiobutton')
61
+
66
62
  const results = await axe(container)
67
63
 
68
64
  expect(results).toHaveNoViolations()
@@ -1,46 +1,57 @@
1
- 'use client'
1
+ import React, { ForwardedRef, forwardRef } from 'react'
2
2
 
3
- import React, {
4
- ChangeEventHandler,
5
- FocusEventHandler,
6
- ForwardedRef,
7
- ForwardRefExoticComponent,
8
- InputHTMLAttributes,
9
- ReactNode,
10
- } from 'react'
11
- import { createComponent, EventName } from '@lit/react'
12
- import { PktRadioButton as PktElRadioButton } from '@oslokommune/punkt-elements'
13
- import { PktEventWithTarget } from '@/interfaces/IPktElements'
14
-
15
- export interface IPktRadioButton extends InputHTMLAttributes<HTMLInputElement> {
3
+ export interface IPktRadioButton extends React.InputHTMLAttributes<HTMLInputElement> {
16
4
  id: string
17
5
  name: string
18
6
  label: string
19
7
  hasTile?: boolean
20
- hasError?: boolean
21
- defaultChecked?: boolean
22
8
  disabled?: boolean
9
+ checkHelptext?: string | React.ReactNode | React.ReactNode[]
10
+ hasError?: boolean
23
11
  value?: string
24
- checkHelptext?: string | ReactNode | ReactNode[]
25
-
26
- ref?: ForwardedRef<HTMLInputElement>
27
- onChange?: ChangeEventHandler<HTMLInputElement>
28
- onInput?: ChangeEventHandler<HTMLInputElement>
29
- onBlur?: FocusEventHandler<HTMLInputElement>
30
- onFocus?: FocusEventHandler<HTMLInputElement>
31
- onValueChange?: (e: CustomEvent) => void
32
12
  }
33
13
 
34
- export const PktRadioButton = createComponent({
35
- tagName: 'pkt-radiobutton',
36
- elementClass: PktElRadioButton,
37
- react: React,
38
- displayName: 'PktRadioButton',
39
- events: {
40
- onChange: 'change' as EventName<PktEventWithTarget>,
41
- onInput: 'input' as EventName<PktEventWithTarget>,
42
- onBlur: 'blur' as EventName<FocusEvent>,
43
- onFocus: 'focus' as EventName<FocusEvent>,
44
- onValueChange: 'valueChange' as EventName<CustomEvent>,
14
+ export const PktRadioButton = forwardRef(
15
+ (
16
+ {
17
+ id,
18
+ name,
19
+ label,
20
+ className,
21
+ hasTile = false,
22
+ disabled = false,
23
+ checkHelptext,
24
+ hasError = false,
25
+ ...props
26
+ }: IPktRadioButton,
27
+ ref: ForwardedRef<HTMLInputElement>,
28
+ ): React.ReactElement => {
29
+ const classes = [className, 'pkt-input-check'].filter(Boolean).join(' ')
30
+
31
+ return (
32
+ <div className={classes}>
33
+ <div
34
+ className={`pkt-input-check__input ${hasTile ? 'pkt-input-check__input--tile' : ''} ${
35
+ disabled && hasTile ? 'pkt-input-check__input--tile-disabled' : ''
36
+ }`}
37
+ >
38
+ <input
39
+ ref={ref}
40
+ id={id}
41
+ type="radio"
42
+ name={name}
43
+ disabled={disabled}
44
+ className={`pkt-input-check__input-checkbox ${hasError ? 'pkt-input-check__input-checkbox--error' : ''}`}
45
+ {...props}
46
+ />
47
+ <label className="pkt-input-check__input-label" htmlFor={id}>
48
+ {label}
49
+ {checkHelptext && <div className="pkt-input-check__input-helptext">{checkHelptext}</div>}
50
+ </label>
51
+ </div>
52
+ </div>
53
+ )
45
54
  },
46
- }) as ForwardRefExoticComponent<IPktRadioButton>
55
+ )
56
+
57
+ PktRadioButton.displayName = 'PktRadioButton'
@@ -11,55 +11,49 @@ expect.extend(toHaveNoViolations)
11
11
  describe('PktSelect', () => {
12
12
  test('renders select field with correct props', async () => {
13
13
  const { container } = render(
14
- <PktSelect
15
- label="Input Label"
16
- id="inputId"
17
- ariaLabelledby="inputId"
18
- options={[{ value: 'verdi', label: 'Verdi' }]}
19
- />,
14
+ <PktSelect label="Input Label" id="inputIdeas" ariaLabelledby="inputId">
15
+ <option>Oslosommer</option>
16
+ </PktSelect>,
20
17
  )
21
- await window.customElements.whenDefined('pkt-select')
22
18
 
23
- const select = container.querySelector('pkt-select')
19
+ const select = container.querySelector('#inputIdeas-input') as HTMLSelectElement | null
24
20
  expect(select).toBeInTheDocument()
25
- expect(select).toHaveAttribute('id', 'inputId')
26
- expect(select?.tagName).toBe('PKT-SELECT')
27
- expect(select?.id).toBe('inputId')
21
+ expect(select).toHaveAttribute('id', 'inputIdeas-input')
22
+ expect(select?.tagName).toBe('SELECT')
23
+ expect(select?.id).toBe('inputIdeas-input')
28
24
 
29
- const inputWrapper = container.querySelector('pkt-input-wrapper')
25
+ const inputWrapper = container.querySelector('.pkt-inputwrapper') as HTMLDivElement | null
30
26
  expect(inputWrapper).toBeInTheDocument()
31
- expect(inputWrapper).toHaveAttribute('label', 'Input Label')
27
+ expect(inputWrapper).toHaveTextContent('Input Label')
28
+
29
+ const label = container.querySelector('label') as HTMLLabelElement | null
30
+ expect(label).toBeInTheDocument()
31
+ expect(label).toHaveAttribute('for', 'inputIdeas-input')
32
32
  })
33
33
 
34
34
  test('renders error message when hasError prop is true', async () => {
35
- const { getByText } = render(
36
- <PktSelect
37
- label="Input Label"
38
- id="inputId"
39
- hasError
40
- errorMessage="Input error"
41
- options={[{ value: 'verdi', label: 'Verdi' }]}
42
- />,
35
+ const { getByText, getByRole } = render(
36
+ <PktSelect label="Input Label" id="inputId" hasError errorMessage="Input error" />,
43
37
  )
44
- await window.customElements.whenDefined('pkt-select')
45
38
 
39
+ await window.customElements.whenDefined('pkt-alert')
46
40
  const errorMessage = getByText('Input error')
47
41
  expect(errorMessage).toBeInTheDocument()
48
- expect(errorMessage.closest('.pkt-alert')).toHaveAttribute('id', 'inputId-input-error')
42
+
43
+ const alertContainer = errorMessage.closest('pkt-alert')
44
+ expect(alertContainer).toHaveAttribute('id', 'inputId-input-error')
45
+ expect(alertContainer).toHaveTextContent('Input error')
46
+
47
+ const alert = getByRole('alert')
48
+ expect(alert).toBeInTheDocument()
49
+ expect(alert).toHaveAttribute('role', 'alert')
49
50
  })
50
51
 
51
52
  describe('PktSelect', () => {
52
53
  test('toggles helptext class', async () => {
53
54
  const { getByText, container } = render(
54
- <PktSelect
55
- label="Input Label"
56
- id="inputId"
57
- helptext="Help Text"
58
- helptextDropdown="Help Text"
59
- options={[{ value: 'verdi', label: 'Verdi' }]}
60
- />,
55
+ <PktSelect label="Input Label" id="inputId" helptext="Help Text" helptextDropdown="Help Text" />,
61
56
  )
62
- await window.customElements.whenDefined('pkt-select')
63
57
 
64
58
  const expandButton = getByText('Les mer').closest('button') as HTMLButtonElement
65
59
  const helptextElement = container.querySelector('.pkt-inputwrapper__helptext-expandable-closed')
@@ -74,10 +68,8 @@ describe('PktSelect', () => {
74
68
 
75
69
  describe('accessibility', () => {
76
70
  it('renders with no wcag errors with axe', async () => {
77
- const { container } = render(
78
- <PktSelect label="Input Label" id="inputId" options={[{ value: 'verdi', label: 'Verdi' }]} />,
79
- )
80
- await window.customElements.whenDefined('pkt-select')
71
+ const { container } = render(<PktSelect label="Input Label" id="inputId" />)
72
+
81
73
  const results = await axe(container)
82
74
  expect(results).toHaveNoViolations()
83
75
  })