@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.
- package/CHANGELOG.md +18 -0
- package/dist/components/combobox/types.d.ts +4 -0
- package/dist/components/datepicker/types.d.ts +2 -0
- package/dist/components/select/Select.d.ts +2 -0
- package/dist/components/textarea/Textarea.d.ts +1 -0
- package/dist/components/textinput/Textinput.d.ts +1 -0
- package/dist/components/timepicker/types.d.ts +2 -0
- package/dist/punkt-react.cjs +1 -1
- package/dist/punkt-react.js +1765 -1715
- package/dist/shared-types/booleanish.d.ts +11 -0
- package/dist/shared-types/index.d.ts +1 -1
- package/dist/shared-utils/forms/described-by.d.ts +24 -0
- package/package.json +3 -3
- package/src/components/combobox/Combobox.tsx +2 -1
- package/src/components/combobox/types.ts +4 -0
- package/src/components/combobox/useComboboxState.ts +5 -1
- package/src/components/datepicker/Datepicker.tsx +7 -1
- package/src/components/datepicker/types.ts +2 -0
- package/src/components/datepicker/useDatepickerState.ts +3 -1
- package/src/components/fileupload/FileUpload.tsx +20 -18
- package/src/components/helptext/Helptext.tsx +3 -0
- package/src/components/inputwrapper/InputWrapper.tsx +20 -8
- package/src/components/select/Select.tsx +46 -32
- package/src/components/textarea/Textarea.tsx +59 -47
- package/src/components/textinput/Textinput.tsx +79 -67
- package/src/components/timepicker/Timepicker.tsx +3 -0
- package/src/components/timepicker/types.ts +2 -0
|
@@ -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
|
|
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 (
|
|
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
|
-
<
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
{
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
{
|
|
195
|
-
|
|
196
|
-
{
|
|
197
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
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
|