@jobber/components 8.2.0 → 8.4.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/ActivityIndicator.d.ts +1 -0
- package/ActivityIndicator.js +17 -0
- package/dist/ActivityIndicator/ActivityIndicator.d.ts +38 -0
- package/dist/ActivityIndicator/index.cjs +9 -0
- package/dist/ActivityIndicator/index.d.ts +2 -0
- package/dist/ActivityIndicator/index.mjs +3 -0
- package/dist/ActivityIndicator-cjs.js +27 -0
- package/dist/ActivityIndicator-es.js +25 -0
- package/dist/Autocomplete/Autocomplete.d.ts +2 -3
- package/dist/Autocomplete/Autocomplete.types.d.ts +4 -9
- package/dist/Autocomplete/index.cjs +7 -8
- package/dist/Autocomplete/index.d.ts +3 -4
- package/dist/Autocomplete/index.mjs +6 -7
- package/dist/DataList/components/DataListSearch/index.cjs +1 -2
- package/dist/DataList/components/DataListSearch/index.mjs +1 -2
- package/dist/DataList/index.cjs +1 -2
- package/dist/DataList/index.mjs +1 -2
- package/dist/DataListSearch-cjs.js +12 -6
- package/dist/DataListSearch-es.js +11 -5
- package/dist/InputDate/index.cjs +1 -2
- package/dist/InputDate/index.mjs +1 -2
- package/dist/InputDate-cjs.js +2 -2
- package/dist/InputDate-es.js +2 -2
- package/dist/InputText/InputText.d.ts +2 -70
- package/dist/InputText/InputText.types.d.ts +2 -30
- package/dist/InputText/index.cjs +12 -268
- package/dist/InputText/index.d.ts +2 -5
- package/dist/InputText/index.mjs +11 -271
- package/dist/InputText/useInputTextActions.d.ts +2 -2
- package/dist/InputText-cjs.js +199 -0
- package/dist/InputText-es.js +197 -0
- package/dist/Spinner/Spinner.d.ts +6 -0
- package/dist/Spinner-cjs.js +3 -0
- package/dist/Spinner-es.js +3 -0
- package/dist/docs/ActivityIndicator/ActivityIndicator.md +67 -0
- package/dist/docs/Autocomplete/AutocompleteV1.md +1 -2
- package/dist/docs/Autocomplete/AutocompleteV2.md +1 -1
- package/dist/docs/Banner/Banner.md +2 -2
- package/dist/docs/Box/Box.md +2 -2
- package/dist/docs/Glimmer/Glimmer.md +1 -1
- package/dist/docs/Icon/Icon.md +1 -1
- package/dist/docs/InputText/InputText.md +152 -106
- package/dist/docs/Menu/Menu.md +1 -1
- package/dist/docs/Modal/Modal.md +1 -1
- package/dist/docs/Spinner/Spinner.md +9 -1
- package/dist/docs/Stack/Stack.md +1 -1
- package/dist/docs/index.md +1 -0
- package/dist/docs/usage-guidelines/usage-guidelines.md +0 -2
- package/dist/index.cjs +5 -3
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +3 -2
- package/dist/styles.css +279 -0
- package/dist/utils/meta/meta.json +1 -0
- package/package.json +8 -3
- package/dist/InputText/InputText.rebuilt.d.ts +0 -3
package/dist/InputText/index.mjs
CHANGED
|
@@ -1,281 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import '
|
|
5
|
-
import '../tslib.es6-es.js';
|
|
6
|
-
import 'react-hook-form';
|
|
1
|
+
export { I as InputText } from '../InputText-es.js';
|
|
2
|
+
import 'react';
|
|
3
|
+
import '@jobber/hooks';
|
|
4
|
+
import '../FormFieldWrapper-es.js';
|
|
7
5
|
import 'framer-motion';
|
|
8
6
|
import '@jobber/design';
|
|
7
|
+
import 'classnames';
|
|
9
8
|
import '../Button-es.js';
|
|
10
|
-
import
|
|
11
|
-
import { F as FormFieldPostFix } from '../FormFieldPostFix-es.js';
|
|
12
|
-
import { u as useAtlantisFormFieldName } from '../useAtlantisFormFieldName-es.js';
|
|
13
|
-
import { m as mergeRefs } from '../mergeRefs-es.js';
|
|
14
|
-
import { f as filterDataAttributes } from '../filterDataAttributes-es.js';
|
|
9
|
+
import '../tslib.es6-es.js';
|
|
15
10
|
import 'react-router-dom';
|
|
16
11
|
import '../Icon-es.js';
|
|
17
12
|
import '../Typography-es.js';
|
|
18
13
|
import '../Text-es.js';
|
|
19
14
|
import '../useFormFieldFocus-es.js';
|
|
20
15
|
import '../InputValidation-es.js';
|
|
16
|
+
import '../FormFieldPostFix-es.js';
|
|
21
17
|
import '../Spinner-es.js';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
function useTextAreaResize({ rows, value, inputRef, wrapperRef, }) {
|
|
27
|
-
const rowRange = getRowRange(rows);
|
|
28
|
-
useSafeLayoutEffect(() => {
|
|
29
|
-
if (inputRef &&
|
|
30
|
-
inputRef.current instanceof HTMLTextAreaElement &&
|
|
31
|
-
wrapperRef &&
|
|
32
|
-
wrapperRef.current instanceof HTMLDivElement) {
|
|
33
|
-
resize();
|
|
34
|
-
}
|
|
35
|
-
}, [inputRef.current, wrapperRef.current]);
|
|
36
|
-
// When the consumer passes a new controlled value, we need to recheck the size.
|
|
37
|
-
// The timeout ensures the DOM has a enough time to render the new text before
|
|
38
|
-
// we access the height.
|
|
39
|
-
useSafeLayoutEffect(() => {
|
|
40
|
-
setTimeout(() => {
|
|
41
|
-
if (inputRef &&
|
|
42
|
-
inputRef.current instanceof HTMLTextAreaElement &&
|
|
43
|
-
wrapperRef &&
|
|
44
|
-
wrapperRef.current instanceof HTMLDivElement) {
|
|
45
|
-
resize();
|
|
46
|
-
}
|
|
47
|
-
}, 0);
|
|
48
|
-
}, [value]);
|
|
49
|
-
function resize() {
|
|
50
|
-
if (inputRef &&
|
|
51
|
-
inputRef.current instanceof HTMLTextAreaElement &&
|
|
52
|
-
wrapperRef &&
|
|
53
|
-
(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current) instanceof HTMLDivElement) {
|
|
54
|
-
if (rowRange.min === rowRange.max)
|
|
55
|
-
return;
|
|
56
|
-
inputRef.current.style.flexBasis = "auto";
|
|
57
|
-
wrapperRef.current.style.height = "auto";
|
|
58
|
-
inputRef.current.style.flexBasis =
|
|
59
|
-
textAreaHeight(inputRef.current) + "px";
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function textAreaHeight(textArea) {
|
|
63
|
-
const { lineHeight, borderBottomWidth, borderTopWidth, paddingBottom, paddingTop, } = window.getComputedStyle(textArea);
|
|
64
|
-
const maxHeight = rowRange.max * parseFloat(lineHeight) +
|
|
65
|
-
parseFloat(borderTopWidth) +
|
|
66
|
-
parseFloat(borderBottomWidth) +
|
|
67
|
-
parseFloat(paddingTop) +
|
|
68
|
-
parseFloat(paddingBottom);
|
|
69
|
-
const scrollHeight = textArea.scrollHeight +
|
|
70
|
-
parseFloat(borderTopWidth) +
|
|
71
|
-
parseFloat(borderBottomWidth);
|
|
72
|
-
return Math.min(scrollHeight, maxHeight);
|
|
73
|
-
}
|
|
74
|
-
return { resize, rowRange };
|
|
75
|
-
}
|
|
76
|
-
function getRowRange(rows) {
|
|
77
|
-
if (rows === undefined) {
|
|
78
|
-
return { min: 3, max: 3 };
|
|
79
|
-
}
|
|
80
|
-
else if (typeof rows === "object") {
|
|
81
|
-
return { min: rows.min, max: rows.max };
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return { min: rows, max: rows };
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function InputTextInternal(
|
|
89
|
-
// eslint-disable-next-line import/no-deprecated
|
|
90
|
-
props, ref) {
|
|
91
|
-
const inputRef = useRef(null);
|
|
92
|
-
const actionsRef = useRef(null);
|
|
93
|
-
const wrapperRef = useRef(null);
|
|
94
|
-
const { resize, rowRange } = useTextAreaResize({
|
|
95
|
-
rows: props.rows,
|
|
96
|
-
value: props.value,
|
|
97
|
-
inputRef,
|
|
98
|
-
wrapperRef,
|
|
99
|
-
});
|
|
100
|
-
useImperativeHandle(ref, () => ({
|
|
101
|
-
insert: (text) => {
|
|
102
|
-
insertText(text);
|
|
103
|
-
},
|
|
104
|
-
blur: () => {
|
|
105
|
-
const input = inputRef.current;
|
|
106
|
-
if (input) {
|
|
107
|
-
input.blur();
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
focus: () => {
|
|
111
|
-
const input = inputRef.current;
|
|
112
|
-
if (input) {
|
|
113
|
-
input.focus();
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
scrollIntoView: arg => {
|
|
117
|
-
const input = inputRef.current;
|
|
118
|
-
if (input) {
|
|
119
|
-
input.scrollIntoView(arg);
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
}));
|
|
123
|
-
return (React__default.createElement(FormField, Object.assign({}, props, { type: props.multiline ? "textarea" : "text", inputRef: inputRef, actionsRef: actionsRef, wrapperRef: wrapperRef, onChange: handleChange, rows: rowRange.min })));
|
|
124
|
-
function handleChange(newValue) {
|
|
125
|
-
props.onChange && props.onChange(newValue);
|
|
126
|
-
resize();
|
|
127
|
-
}
|
|
128
|
-
function insertText(text) {
|
|
129
|
-
var _a;
|
|
130
|
-
const input = inputRef.current;
|
|
131
|
-
if (input) {
|
|
132
|
-
insertAtCursor(input, text);
|
|
133
|
-
const newValue = input.value;
|
|
134
|
-
(_a = actionsRef.current) === null || _a === void 0 ? void 0 : _a.setValue(newValue);
|
|
135
|
-
props.onChange && props.onChange(newValue);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
const InputText$1 = forwardRef(InputTextInternal);
|
|
140
|
-
function insertAtCursor(input, newText) {
|
|
141
|
-
const start = input.selectionStart || 0;
|
|
142
|
-
const end = input.selectionEnd || 0;
|
|
143
|
-
const text = input.value;
|
|
144
|
-
const before = text.substring(0, start);
|
|
145
|
-
const after = text.substring(end, text.length);
|
|
146
|
-
input.value = before + newText + after;
|
|
147
|
-
input.selectionStart = input.selectionEnd = start + newText.length;
|
|
148
|
-
input.focus();
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Combines the actions on the InputText such as onChange, onEnter, onFocus, onBlur, and onClear to forward information to the consumers of the InputText.
|
|
153
|
-
* DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
|
|
154
|
-
*/
|
|
155
|
-
function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, onKeyUp, onMouseDown, onMouseUp, onPointerDown, onPointerUp, onClick, }) {
|
|
156
|
-
function handleClear() {
|
|
157
|
-
var _a;
|
|
158
|
-
onChange && onChange("");
|
|
159
|
-
(_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
160
|
-
}
|
|
161
|
-
function handleChange(event) {
|
|
162
|
-
const newValue = event.currentTarget.value;
|
|
163
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(newValue, event);
|
|
164
|
-
}
|
|
165
|
-
function handleKeyDown(event) {
|
|
166
|
-
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
|
|
167
|
-
if (!onEnter)
|
|
168
|
-
return;
|
|
169
|
-
if (event.key !== "Enter")
|
|
170
|
-
return;
|
|
171
|
-
if (event.shiftKey || event.ctrlKey)
|
|
172
|
-
return;
|
|
173
|
-
event.preventDefault();
|
|
174
|
-
onEnter && onEnter(event);
|
|
175
|
-
}
|
|
176
|
-
function handleKeyUp(event) {
|
|
177
|
-
onKeyUp === null || onKeyUp === void 0 ? void 0 : onKeyUp(event);
|
|
178
|
-
}
|
|
179
|
-
function handleFocus(event) {
|
|
180
|
-
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
181
|
-
}
|
|
182
|
-
function handleBlur(event) {
|
|
183
|
-
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
184
|
-
}
|
|
185
|
-
function handleMouseDown(event) {
|
|
186
|
-
onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(event);
|
|
187
|
-
}
|
|
188
|
-
function handleMouseUp(event) {
|
|
189
|
-
onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(event);
|
|
190
|
-
}
|
|
191
|
-
function handlePointerDown(event) {
|
|
192
|
-
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
193
|
-
}
|
|
194
|
-
function handlePointerUp(event) {
|
|
195
|
-
onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp(event);
|
|
196
|
-
}
|
|
197
|
-
function handleClick(event) {
|
|
198
|
-
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
199
|
-
}
|
|
200
|
-
return {
|
|
201
|
-
handleClear,
|
|
202
|
-
handleChange,
|
|
203
|
-
handleKeyDown,
|
|
204
|
-
handleKeyUp,
|
|
205
|
-
handleFocus,
|
|
206
|
-
handleBlur,
|
|
207
|
-
handleMouseDown,
|
|
208
|
-
handleMouseUp,
|
|
209
|
-
handlePointerDown,
|
|
210
|
-
handlePointerUp,
|
|
211
|
-
handleClick,
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const InputTextSPAR = forwardRef(function InputTextInternal(props, inputRef) {
|
|
216
|
-
var _a, _b, _c;
|
|
217
|
-
const inputTextRef = React__default.useRef(null), wrapperRef = React__default.useRef(null);
|
|
218
|
-
const id = useInputTextId(props);
|
|
219
|
-
const { rowRange } = useTextAreaResize({
|
|
220
|
-
rows: props.rows,
|
|
221
|
-
value: props.value,
|
|
222
|
-
inputRef: inputTextRef,
|
|
223
|
-
wrapperRef: wrapperRef,
|
|
224
|
-
});
|
|
225
|
-
const { name } = useAtlantisFormFieldName({
|
|
226
|
-
nameProp: props.name,
|
|
227
|
-
id: id,
|
|
228
|
-
});
|
|
229
|
-
const { handleChange, handleBlur, handleFocus, handleKeyDown, handleKeyUp, handleClear, handleMouseDown, handleMouseUp, handlePointerDown, handlePointerUp, handleClick, } = useInputTextActions({
|
|
230
|
-
onChange: props.onChange,
|
|
231
|
-
onBlur: props.onBlur,
|
|
232
|
-
onFocus: props.onFocus,
|
|
233
|
-
onMouseDown: props.onMouseDown,
|
|
234
|
-
onMouseUp: props.onMouseUp,
|
|
235
|
-
onPointerDown: props.onPointerDown,
|
|
236
|
-
onPointerUp: props.onPointerUp,
|
|
237
|
-
onClick: props.onClick,
|
|
238
|
-
onKeyDown: props.onKeyDown,
|
|
239
|
-
onKeyUp: props.onKeyUp,
|
|
240
|
-
onEnter: props.onEnter,
|
|
241
|
-
inputRef: inputTextRef,
|
|
242
|
-
});
|
|
243
|
-
const descriptionIdentifier = `descriptionUUID--${id}`;
|
|
244
|
-
const descriptionVisible = props.description && !props.inline;
|
|
245
|
-
const isInvalid = Boolean(props.error || props.invalid);
|
|
246
|
-
const dataAttrs = filterDataAttributes(props);
|
|
247
|
-
const mergedRef = useMemo(() => mergeRefs([inputRef, inputTextRef]), []);
|
|
248
|
-
// Shared props for both TextArea and TextInput
|
|
249
|
-
const commonInputProps = Object.assign({ id,
|
|
250
|
-
name, className: formFieldStyles.input, value: props.value, disabled: props.disabled, readOnly: props.readOnly, autoFocus: props.autoFocus, autoComplete: props.autoComplete, inputMode: props.inputMode, tabIndex: props.tabIndex, maxLength: props.maxLength, required: props.required, role: props.role, "aria-label": props["aria-label"], "aria-describedby": descriptionVisible
|
|
251
|
-
? descriptionIdentifier
|
|
252
|
-
: props["aria-describedby"], "aria-invalid": isInvalid ? true : undefined, "aria-controls": props["aria-controls"], "aria-expanded": props["aria-expanded"], "aria-activedescendant": props["aria-activedescendant"], "aria-autocomplete": props["aria-autocomplete"], "aria-required": props["aria-required"], onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onClick: handleClick, ref: mergedRef }, dataAttrs);
|
|
253
|
-
return (React__default.createElement(FormFieldWrapper, { disabled: props.disabled, size: props.size, align: props.align, inline: props.inline, name: name, wrapperRef: wrapperRef, error: (_a = props.error) !== null && _a !== void 0 ? _a : "", invalid: Boolean(props.error || props.invalid), identifier: id, descriptionIdentifier: descriptionIdentifier, description: props.description, clearable: (_b = props.clearable) !== null && _b !== void 0 ? _b : "never", onClear: handleClear, type: props.multiline ? "textarea" : "text", placeholder: props.placeholder, value: props.value, prefix: props.prefix, suffix: props.suffix, readonly: props.readOnly, rows: rowRange.min, toolbar: props.toolbar, toolbarVisibility: props.toolbarVisibility, showMiniLabel: props.showMiniLabel },
|
|
254
|
-
React__default.createElement(React__default.Fragment, null,
|
|
255
|
-
props.multiline ? (React__default.createElement(TextArea, Object.assign({}, commonInputProps, { rows: rowRange.min }))) : (React__default.createElement(TextInput, Object.assign({}, commonInputProps, { pattern: props.pattern }))),
|
|
256
|
-
React__default.createElement(FormFieldPostFix, { variation: "spinner", visible: (_c = props.loading) !== null && _c !== void 0 ? _c : false }))));
|
|
257
|
-
});
|
|
258
|
-
function useInputTextId(props) {
|
|
259
|
-
const generatedId = useId();
|
|
260
|
-
return props.id || generatedId;
|
|
261
|
-
}
|
|
262
|
-
const TextArea = forwardRef(function TextArea(props, ref) {
|
|
263
|
-
return React__default.createElement("textarea", Object.assign({}, props, { ref: ref }));
|
|
264
|
-
});
|
|
265
|
-
const TextInput = forwardRef(function TextInput(props, ref) {
|
|
266
|
-
return React__default.createElement("input", Object.assign({}, props, { ref: ref }));
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
function isNewInputTextProps(props) {
|
|
270
|
-
return props.version === 2;
|
|
271
|
-
}
|
|
272
|
-
const InputText = forwardRef(function InputTextShim(props, ref) {
|
|
273
|
-
if (isNewInputTextProps(props)) {
|
|
274
|
-
return (React__default.createElement(InputTextSPAR, Object.assign({}, props, { ref: ref })));
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
return (React__default.createElement(InputText$1, Object.assign({}, props, { ref: ref })));
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
export { InputText };
|
|
18
|
+
import '../useAtlantisFormFieldName-es.js';
|
|
19
|
+
import 'react-hook-form';
|
|
20
|
+
import '../mergeRefs-es.js';
|
|
21
|
+
import '../filterDataAttributes-es.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ChangeEvent, FocusEvent, KeyboardEvent, MouseEvent, PointerEvent } from "react";
|
|
2
|
-
import type {
|
|
3
|
-
export interface useInputTextActionsProps extends Pick<
|
|
2
|
+
import type { InputTextProps } from "./InputText.types";
|
|
3
|
+
export interface useInputTextActionsProps extends Pick<InputTextProps, "onChange" | "onEnter" | "onFocus" | "onBlur" | "onKeyDown" | "onKeyUp" | "onMouseDown" | "onMouseUp" | "onPointerDown" | "onPointerUp" | "onClick"> {
|
|
4
4
|
inputRef?: React.RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var jobberHooks = require('@jobber/hooks');
|
|
5
|
+
var FormFieldWrapper = require('./FormFieldWrapper-cjs.js');
|
|
6
|
+
var FormFieldPostFix = require('./FormFieldPostFix-cjs.js');
|
|
7
|
+
require('classnames');
|
|
8
|
+
var useAtlantisFormFieldName = require('./useAtlantisFormFieldName-cjs.js');
|
|
9
|
+
require('./tslib.es6-cjs.js');
|
|
10
|
+
require('react-hook-form');
|
|
11
|
+
var mergeRefs = require('./mergeRefs-cjs.js');
|
|
12
|
+
require('./Button-cjs.js');
|
|
13
|
+
require('@jobber/design');
|
|
14
|
+
var filterDataAttributes = require('./filterDataAttributes-cjs.js');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Hook for resizing a textarea based on its content. The textarea will grow up to the max number of rows specified.
|
|
18
|
+
*/
|
|
19
|
+
function useTextAreaResize({ rows, value, inputRef, wrapperRef, }) {
|
|
20
|
+
const rowRange = getRowRange(rows);
|
|
21
|
+
jobberHooks.useSafeLayoutEffect(() => {
|
|
22
|
+
if (inputRef &&
|
|
23
|
+
inputRef.current instanceof HTMLTextAreaElement &&
|
|
24
|
+
wrapperRef &&
|
|
25
|
+
wrapperRef.current instanceof HTMLDivElement) {
|
|
26
|
+
resize();
|
|
27
|
+
}
|
|
28
|
+
}, [inputRef.current, wrapperRef.current]);
|
|
29
|
+
// When the consumer passes a new controlled value, we need to recheck the size.
|
|
30
|
+
// The timeout ensures the DOM has a enough time to render the new text before
|
|
31
|
+
// we access the height.
|
|
32
|
+
jobberHooks.useSafeLayoutEffect(() => {
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
if (inputRef &&
|
|
35
|
+
inputRef.current instanceof HTMLTextAreaElement &&
|
|
36
|
+
wrapperRef &&
|
|
37
|
+
wrapperRef.current instanceof HTMLDivElement) {
|
|
38
|
+
resize();
|
|
39
|
+
}
|
|
40
|
+
}, 0);
|
|
41
|
+
}, [value]);
|
|
42
|
+
function resize() {
|
|
43
|
+
if (inputRef &&
|
|
44
|
+
inputRef.current instanceof HTMLTextAreaElement &&
|
|
45
|
+
wrapperRef &&
|
|
46
|
+
(wrapperRef === null || wrapperRef === void 0 ? void 0 : wrapperRef.current) instanceof HTMLDivElement) {
|
|
47
|
+
if (rowRange.min === rowRange.max)
|
|
48
|
+
return;
|
|
49
|
+
inputRef.current.style.flexBasis = "auto";
|
|
50
|
+
wrapperRef.current.style.height = "auto";
|
|
51
|
+
inputRef.current.style.flexBasis =
|
|
52
|
+
textAreaHeight(inputRef.current) + "px";
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function textAreaHeight(textArea) {
|
|
56
|
+
const { lineHeight, borderBottomWidth, borderTopWidth, paddingBottom, paddingTop, } = window.getComputedStyle(textArea);
|
|
57
|
+
const maxHeight = rowRange.max * parseFloat(lineHeight) +
|
|
58
|
+
parseFloat(borderTopWidth) +
|
|
59
|
+
parseFloat(borderBottomWidth) +
|
|
60
|
+
parseFloat(paddingTop) +
|
|
61
|
+
parseFloat(paddingBottom);
|
|
62
|
+
const scrollHeight = textArea.scrollHeight +
|
|
63
|
+
parseFloat(borderTopWidth) +
|
|
64
|
+
parseFloat(borderBottomWidth);
|
|
65
|
+
return Math.min(scrollHeight, maxHeight);
|
|
66
|
+
}
|
|
67
|
+
return { resize, rowRange };
|
|
68
|
+
}
|
|
69
|
+
function getRowRange(rows) {
|
|
70
|
+
if (rows === undefined) {
|
|
71
|
+
return { min: 3, max: 3 };
|
|
72
|
+
}
|
|
73
|
+
else if (typeof rows === "object") {
|
|
74
|
+
return { min: rows.min, max: rows.max };
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return { min: rows, max: rows };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Combines the actions on the InputText such as onChange, onEnter, onFocus, onBlur, and onClear to forward information to the consumers of the InputText.
|
|
83
|
+
* DO not repeat this pattern. We are doing this as a proof of concept relating to the refactoring of Form inputs to see what can be removed.
|
|
84
|
+
*/
|
|
85
|
+
function useInputTextActions({ onChange, inputRef, onEnter, onFocus, onBlur, onKeyDown, onKeyUp, onMouseDown, onMouseUp, onPointerDown, onPointerUp, onClick, }) {
|
|
86
|
+
function handleClear() {
|
|
87
|
+
var _a;
|
|
88
|
+
onChange && onChange("");
|
|
89
|
+
(_a = inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
90
|
+
}
|
|
91
|
+
function handleChange(event) {
|
|
92
|
+
const newValue = event.currentTarget.value;
|
|
93
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(newValue, event);
|
|
94
|
+
}
|
|
95
|
+
function handleKeyDown(event) {
|
|
96
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
|
|
97
|
+
if (!onEnter)
|
|
98
|
+
return;
|
|
99
|
+
if (event.key !== "Enter")
|
|
100
|
+
return;
|
|
101
|
+
if (event.shiftKey || event.ctrlKey)
|
|
102
|
+
return;
|
|
103
|
+
event.preventDefault();
|
|
104
|
+
onEnter && onEnter(event);
|
|
105
|
+
}
|
|
106
|
+
function handleKeyUp(event) {
|
|
107
|
+
onKeyUp === null || onKeyUp === void 0 ? void 0 : onKeyUp(event);
|
|
108
|
+
}
|
|
109
|
+
function handleFocus(event) {
|
|
110
|
+
onFocus === null || onFocus === void 0 ? void 0 : onFocus(event);
|
|
111
|
+
}
|
|
112
|
+
function handleBlur(event) {
|
|
113
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(event);
|
|
114
|
+
}
|
|
115
|
+
function handleMouseDown(event) {
|
|
116
|
+
onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(event);
|
|
117
|
+
}
|
|
118
|
+
function handleMouseUp(event) {
|
|
119
|
+
onMouseUp === null || onMouseUp === void 0 ? void 0 : onMouseUp(event);
|
|
120
|
+
}
|
|
121
|
+
function handlePointerDown(event) {
|
|
122
|
+
onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
|
|
123
|
+
}
|
|
124
|
+
function handlePointerUp(event) {
|
|
125
|
+
onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp(event);
|
|
126
|
+
}
|
|
127
|
+
function handleClick(event) {
|
|
128
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
handleClear,
|
|
132
|
+
handleChange,
|
|
133
|
+
handleKeyDown,
|
|
134
|
+
handleKeyUp,
|
|
135
|
+
handleFocus,
|
|
136
|
+
handleBlur,
|
|
137
|
+
handleMouseDown,
|
|
138
|
+
handleMouseUp,
|
|
139
|
+
handlePointerDown,
|
|
140
|
+
handlePointerUp,
|
|
141
|
+
handleClick,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const InputText = React.forwardRef(function InputTextInternal(props, inputRef) {
|
|
146
|
+
var _a, _b, _c;
|
|
147
|
+
const inputTextRef = React.useRef(null), wrapperRef = React.useRef(null);
|
|
148
|
+
const id = useInputTextId(props);
|
|
149
|
+
const { rowRange } = useTextAreaResize({
|
|
150
|
+
rows: props.rows,
|
|
151
|
+
value: props.value,
|
|
152
|
+
inputRef: inputTextRef,
|
|
153
|
+
wrapperRef: wrapperRef,
|
|
154
|
+
});
|
|
155
|
+
const { name } = useAtlantisFormFieldName.useAtlantisFormFieldName({
|
|
156
|
+
nameProp: props.name,
|
|
157
|
+
id: id,
|
|
158
|
+
});
|
|
159
|
+
const { handleChange, handleBlur, handleFocus, handleKeyDown, handleKeyUp, handleClear, handleMouseDown, handleMouseUp, handlePointerDown, handlePointerUp, handleClick, } = useInputTextActions({
|
|
160
|
+
onChange: props.onChange,
|
|
161
|
+
onBlur: props.onBlur,
|
|
162
|
+
onFocus: props.onFocus,
|
|
163
|
+
onMouseDown: props.onMouseDown,
|
|
164
|
+
onMouseUp: props.onMouseUp,
|
|
165
|
+
onPointerDown: props.onPointerDown,
|
|
166
|
+
onPointerUp: props.onPointerUp,
|
|
167
|
+
onClick: props.onClick,
|
|
168
|
+
onKeyDown: props.onKeyDown,
|
|
169
|
+
onKeyUp: props.onKeyUp,
|
|
170
|
+
onEnter: props.onEnter,
|
|
171
|
+
inputRef: inputTextRef,
|
|
172
|
+
});
|
|
173
|
+
const descriptionIdentifier = `descriptionUUID--${id}`;
|
|
174
|
+
const descriptionVisible = props.description && !props.inline;
|
|
175
|
+
const isInvalid = Boolean(props.error || props.invalid);
|
|
176
|
+
const dataAttrs = filterDataAttributes.filterDataAttributes(props);
|
|
177
|
+
const mergedRef = React.useMemo(() => mergeRefs.mergeRefs([inputRef, inputTextRef]), []);
|
|
178
|
+
// Shared props for both TextArea and TextInput
|
|
179
|
+
const commonInputProps = Object.assign({ id,
|
|
180
|
+
name, className: FormFieldWrapper.formFieldStyles.input, value: props.value, disabled: props.disabled, readOnly: props.readOnly, autoFocus: props.autoFocus, autoComplete: props.autoComplete, inputMode: props.inputMode, tabIndex: props.tabIndex, maxLength: props.maxLength, required: props.required, role: props.role, "aria-label": props["aria-label"], "aria-describedby": descriptionVisible
|
|
181
|
+
? descriptionIdentifier
|
|
182
|
+
: props["aria-describedby"], "aria-invalid": isInvalid ? true : undefined, "aria-controls": props["aria-controls"], "aria-expanded": props["aria-expanded"], "aria-activedescendant": props["aria-activedescendant"], "aria-autocomplete": props["aria-autocomplete"], "aria-required": props["aria-required"], onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, onKeyDown: handleKeyDown, onKeyUp: handleKeyUp, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, onPointerDown: handlePointerDown, onPointerUp: handlePointerUp, onClick: handleClick, ref: mergedRef }, dataAttrs);
|
|
183
|
+
return (React.createElement(FormFieldWrapper.FormFieldWrapper, { disabled: props.disabled, size: props.size, align: props.align, inline: props.inline, name: name, wrapperRef: wrapperRef, error: (_a = props.error) !== null && _a !== void 0 ? _a : "", invalid: Boolean(props.error || props.invalid), identifier: id, descriptionIdentifier: descriptionIdentifier, description: props.description, clearable: (_b = props.clearable) !== null && _b !== void 0 ? _b : "never", onClear: handleClear, type: props.multiline ? "textarea" : "text", placeholder: props.placeholder, value: props.value, prefix: props.prefix, suffix: props.suffix, readonly: props.readOnly, rows: rowRange.min, toolbar: props.toolbar, toolbarVisibility: props.toolbarVisibility, showMiniLabel: props.showMiniLabel },
|
|
184
|
+
React.createElement(React.Fragment, null,
|
|
185
|
+
props.multiline ? (React.createElement(TextArea, Object.assign({}, commonInputProps, { rows: rowRange.min }))) : (React.createElement(TextInput, Object.assign({}, commonInputProps, { pattern: props.pattern }))),
|
|
186
|
+
React.createElement(FormFieldPostFix.FormFieldPostFix, { variation: "spinner", visible: (_c = props.loading) !== null && _c !== void 0 ? _c : false }))));
|
|
187
|
+
});
|
|
188
|
+
function useInputTextId(props) {
|
|
189
|
+
const generatedId = React.useId();
|
|
190
|
+
return props.id || generatedId;
|
|
191
|
+
}
|
|
192
|
+
const TextArea = React.forwardRef(function TextArea(props, ref) {
|
|
193
|
+
return React.createElement("textarea", Object.assign({}, props, { ref: ref }));
|
|
194
|
+
});
|
|
195
|
+
const TextInput = React.forwardRef(function TextInput(props, ref) {
|
|
196
|
+
return React.createElement("input", Object.assign({}, props, { ref: ref }));
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
exports.InputText = InputText;
|