@oslokommune/punkt-react 17.0.9 → 17.1.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.
@@ -13,6 +13,7 @@ import {
13
13
 
14
14
  import { PktIcon } from '../icon/Icon'
15
15
  import { PktInputWrapper } from '../inputwrapper/InputWrapper'
16
+ import { describedByIds } from 'shared-utils/forms/described-by'
16
17
 
17
18
  export interface IPktTextinput extends InputHTMLAttributes<HTMLInputElement> {
18
19
  id: string
@@ -20,6 +21,7 @@ export interface IPktTextinput extends InputHTMLAttributes<HTMLInputElement> {
20
21
  ariaLabelledby?: string
21
22
  autocomplete?: string
22
23
  counter?: boolean
24
+ hasFieldset?: boolean
23
25
  counterMaxLength?: number
24
26
  disabled?: boolean
25
27
  errorMessage?: string | ReactNode | ReactNode[]
@@ -66,6 +68,7 @@ export const PktTextinput = forwardRef(
66
68
  ariaLabelledby,
67
69
  autocomplete = 'off',
68
70
  counter,
71
+ hasFieldset,
69
72
  counterMaxLength,
70
73
  className,
71
74
  disabled = false,
@@ -107,7 +110,8 @@ export const PktTextinput = forwardRef(
107
110
  }: IPktTextinput,
108
111
  ref: ForwardedRef<HTMLInputElement>,
109
112
  ) => {
110
- const classNames = [className, 'pkt-textinput'].join(' ')
113
+ const showCounter = counter ?? (counterMaxLength ?? 0) > 0
114
+ const outerClasses = [className, 'pkt-textinput'].filter(Boolean).join(' ')
111
115
 
112
116
  const shouldShowSearchIcon = type === 'search' && !iconNameRight && !omitSearchIcon
113
117
  const isoValue = type === 'date' && value ? value.slice(0, 10) : value
@@ -119,7 +123,7 @@ export const PktTextinput = forwardRef(
119
123
  const labelledBy = ariaLabelledby || labelId
120
124
 
121
125
  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
122
- if (counter) {
126
+ if (showCounter) {
123
127
  setCounterCurrent(event.currentTarget?.value?.length || 0)
124
128
  }
125
129
  if (onChange) {
@@ -134,73 +138,81 @@ export const PktTextinput = forwardRef(
134
138
  }, [value])
135
139
 
136
140
  return (
137
- <PktInputWrapper
138
- ariaDescribedby={ariaDescribedby}
139
- className={classNames}
140
- disabled={disabled}
141
- errorMessage={errorMessage}
142
- forId={inputId}
143
- hasError={hasError}
144
- helptext={helptext}
145
- helptextDropdown={helptextDropdown}
146
- helptextDropdownButton={helptextDropdownButton}
147
- inline={inline}
148
- label={label}
149
- optionalTag={optionalTag}
150
- optionalText={optionalText}
151
- requiredTag={requiredTag}
152
- requiredText={requiredText}
153
- tagText={tagText}
154
- useWrapper={useWrapper}
155
- counter={counter}
156
- counterCurrent={counterCurrent}
157
- counterMaxLength={counterMaxLength}
158
- size={inputSize}
159
- >
160
- <div
161
- className={`pkt-input__container pkt-input__container--${inputSize}`}
162
- data-testid={dataTestid}
163
- data-skip-forward-testid={skipForwardTestid ? 'true' : undefined}
141
+ <div className={outerClasses}>
142
+ <PktInputWrapper
143
+ ariaDescribedby={ariaDescribedby}
144
+ disabled={disabled}
145
+ errorMessage={errorMessage}
146
+ forId={inputId}
147
+ hasError={hasError}
148
+ helptext={helptext}
149
+ helptextDropdown={helptextDropdown}
150
+ helptextDropdownButton={helptextDropdownButton}
151
+ inline={inline}
152
+ label={label}
153
+ optionalTag={optionalTag}
154
+ optionalText={optionalText}
155
+ requiredTag={requiredTag}
156
+ requiredText={requiredText}
157
+ tagText={tagText}
158
+ useWrapper={useWrapper}
159
+ counter={showCounter}
160
+ counterCurrent={counterCurrent}
161
+ counterMaxLength={counterMaxLength}
162
+ hasFieldset={hasFieldset ?? false}
163
+ size={inputSize}
164
164
  >
165
- {prefix && <div className="pkt-input-prefix">{prefix}</div>}
166
- <input
167
- {...props}
168
- ref={ref}
169
- className={`pkt-input pkt-input--${inputSize} ${fullwidth ? 'pkt-input--fullwidth' : ''} ${
170
- counterMaxLength && counterCurrent > counterMaxLength ? 'pkt-input--counter-error' : ''
171
- }`}
172
- type={type}
173
- name={`${name || id}`}
174
- value={isoValue}
175
- id={inputId}
176
- placeholder={placeholder}
177
- autoComplete={autocomplete}
178
- disabled={disabled}
179
- aria-invalid={hasError}
180
- aria-errormessage={`${id}-error`}
181
- aria-labelledby={labelledBy}
182
- min={min}
183
- max={max}
184
- onChange={handleChange}
185
- step={step}
186
- minLength={minLength}
187
- maxLength={maxLength}
188
- size={size}
189
- readOnly={readOnly}
190
- required={required}
191
- />
192
- {suffix && (
193
- <p className="pkt-input-suffix">
194
- {suffix}
195
- {iconNameRight && <PktIcon className="pkt-input-suffix-icon" name={iconNameRight} />}
196
- {shouldShowSearchIcon && <PktIcon className="pkt-input-suffix-icon" name="magnifying-glass-big" />}
197
- </p>
198
- )}
165
+ <div
166
+ className={`pkt-input__container pkt-input__container--${inputSize}`}
167
+ data-testid={dataTestid}
168
+ data-skip-forward-testid={skipForwardTestid ? 'true' : undefined}
169
+ >
170
+ {prefix && <div className="pkt-input-prefix">{prefix}</div>}
171
+ <input
172
+ {...props}
173
+ ref={ref}
174
+ className={`pkt-input pkt-input--${inputSize} ${fullwidth ? 'pkt-input--fullwidth' : ''} ${
175
+ counterMaxLength && counterCurrent > counterMaxLength ? 'pkt-input--counter-error' : ''
176
+ }`}
177
+ type={type}
178
+ name={`${name || id}`}
179
+ value={isoValue}
180
+ id={inputId}
181
+ placeholder={placeholder}
182
+ autoComplete={autocomplete}
183
+ disabled={disabled}
184
+ aria-invalid={hasError}
185
+ aria-errormessage={hasError ? `${id}-error` : undefined}
186
+ aria-describedby={describedByIds({
187
+ id: inputId,
188
+ hasHelptext: !!helptext,
189
+ hasCounter: showCounter,
190
+ ariaDescribedby,
191
+ })}
192
+ aria-labelledby={labelledBy}
193
+ min={min}
194
+ max={max}
195
+ onChange={handleChange}
196
+ step={step}
197
+ minLength={minLength}
198
+ maxLength={maxLength}
199
+ size={size}
200
+ readOnly={readOnly}
201
+ required={required}
202
+ />
203
+ {suffix && (
204
+ <p className="pkt-input-suffix">
205
+ {suffix}
206
+ {iconNameRight && <PktIcon className="pkt-input-suffix-icon" name={iconNameRight} />}
207
+ {shouldShowSearchIcon && <PktIcon className="pkt-input-suffix-icon" name="magnifying-glass-big" />}
208
+ </p>
209
+ )}
199
210
 
200
- {!suffix && iconNameRight && <PktIcon className="pkt-input-icon" name={iconNameRight} />}
201
- {!suffix && shouldShowSearchIcon && <PktIcon className="pkt-input-icon" name="magnifying-glass-big" />}
202
- </div>
203
- </PktInputWrapper>
211
+ {!suffix && iconNameRight && <PktIcon className="pkt-input-icon" name={iconNameRight} />}
212
+ {!suffix && shouldShowSearchIcon && <PktIcon className="pkt-input-icon" name="magnifying-glass-big" />}
213
+ </div>
214
+ </PktInputWrapper>
215
+ </div>
204
216
  )
205
217
  },
206
218
  )
@@ -114,6 +114,7 @@ export const PktTimepicker = forwardRef<HTMLDivElement, IPktTimepicker>((props,
114
114
  aria-label={hoursAriaLabel}
115
115
  role="spinbutton"
116
116
  aria-invalid={state.hasError || state.isInvalid || undefined}
117
+ aria-errormessage={state.hasError ? `${state.hoursId}-error` : undefined}
117
118
  aria-valuemin={0}
118
119
  aria-valuemax={23}
119
120
  aria-valuenow={state.hours !== '' ? parseInt(state.hours, 10) : undefined}
@@ -146,6 +147,7 @@ export const PktTimepicker = forwardRef<HTMLDivElement, IPktTimepicker>((props,
146
147
  aria-label={minutesAriaLabel}
147
148
  role="spinbutton"
148
149
  aria-invalid={state.hasError || state.isInvalid || undefined}
150
+ aria-errormessage={state.hasError ? `${state.hoursId}-error` : undefined}
149
151
  aria-valuemin={0}
150
152
  aria-valuemax={59}
151
153
  aria-valuenow={state.minutes !== '' ? parseInt(state.minutes, 10) : undefined}
@@ -222,6 +224,7 @@ export const PktTimepicker = forwardRef<HTMLDivElement, IPktTimepicker>((props,
222
224
  label={state.label}
223
225
  disabled={state.disabled}
224
226
  hasError={state.hasError}
227
+ hasFieldset={props.hasFieldset ?? false}
225
228
  inline={state.inline}
226
229
  optionalTag={state.optionalTag}
227
230
  optionalText={state.optionalText}
@@ -88,6 +88,8 @@ export interface IPktTimepicker extends Omit<
88
88
 
89
89
  /** Show visible label and help text (`false` = screen-reader-only label). */
90
90
  useWrapper?: boolean
91
+ /** Bruk fieldset og legend i stedet for label. */
92
+ hasFieldset?: boolean
91
93
 
92
94
  /** Passed through to InputWrapper as `aria-describedby`. */
93
95
  ariaDescribedby?: string