@dt-dds/react-text-field 1.0.0-beta.89 → 1.0.0-beta.90

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # @dt-ui/react-text-field
2
2
 
3
+ ## 1.0.0-beta.90
4
+
5
+ ### Minor Changes
6
+
7
+ - feat: add ref to text field
8
+
9
+ ### Patch Changes
10
+
11
+ - @dt-dds/react-spinner@1.0.0-beta.85
12
+
3
13
  ## 1.0.0-beta.89
4
14
 
5
15
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { CustomTheme } from '@dt-dds/themes';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
3
- import { BaseProps, Scale } from '@dt-dds/react-core';
4
2
  import * as react from 'react';
5
3
  import { ReactNode, ComponentPropsWithoutRef, RefObject } from 'react';
4
+ import { BaseProps, Scale } from '@dt-dds/react-core';
6
5
  import * as _emotion_styled from '@emotion/styled';
7
6
  import * as _emotion_react from '@emotion/react';
8
7
 
@@ -28,8 +27,9 @@ interface TextFieldProps extends ComponentPropsWithoutRef<'input'>, BaseProps {
28
27
  scale?: Scale;
29
28
  backgroundFill?: TextFieldBackgroundFill;
30
29
  onResetInput?: () => void;
30
+ isInputFocused?: boolean;
31
31
  }
32
- declare const TextField: ({ dataTestId, hasError, extraPrefix, extraSuffix, label, labelIcon, isFloatingLabel, name, id, required, requiredMessage, style, children, initialValue, inputRef, message: messageProp, type, variant, scale, backgroundFill, disabled, onChange, onResetInput, ...rest }: TextFieldProps) => react_jsx_runtime.JSX.Element;
32
+ declare const TextField: react.ForwardRefExoticComponent<TextFieldProps & react.RefAttributes<HTMLDivElement>>;
33
33
 
34
34
  interface TextFieldStyledProps {
35
35
  isFloatingLabel?: boolean;
@@ -38,6 +38,7 @@ interface TextFieldStyledProps {
38
38
  interface InputFieldStyledProps {
39
39
  isFloatingLabel: boolean;
40
40
  scale: Scale;
41
+ isFocused: boolean;
41
42
  }
42
43
  interface InputWrapperStyledProps {
43
44
  isFloatingLabel: boolean;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { CustomTheme } from '@dt-dds/themes';
2
- import * as react_jsx_runtime from 'react/jsx-runtime';
3
- import { BaseProps, Scale } from '@dt-dds/react-core';
4
2
  import * as react from 'react';
5
3
  import { ReactNode, ComponentPropsWithoutRef, RefObject } from 'react';
4
+ import { BaseProps, Scale } from '@dt-dds/react-core';
6
5
  import * as _emotion_styled from '@emotion/styled';
7
6
  import * as _emotion_react from '@emotion/react';
8
7
 
@@ -28,8 +27,9 @@ interface TextFieldProps extends ComponentPropsWithoutRef<'input'>, BaseProps {
28
27
  scale?: Scale;
29
28
  backgroundFill?: TextFieldBackgroundFill;
30
29
  onResetInput?: () => void;
30
+ isInputFocused?: boolean;
31
31
  }
32
- declare const TextField: ({ dataTestId, hasError, extraPrefix, extraSuffix, label, labelIcon, isFloatingLabel, name, id, required, requiredMessage, style, children, initialValue, inputRef, message: messageProp, type, variant, scale, backgroundFill, disabled, onChange, onResetInput, ...rest }: TextFieldProps) => react_jsx_runtime.JSX.Element;
32
+ declare const TextField: react.ForwardRefExoticComponent<TextFieldProps & react.RefAttributes<HTMLDivElement>>;
33
33
 
34
34
  interface TextFieldStyledProps {
35
35
  isFloatingLabel?: boolean;
@@ -38,6 +38,7 @@ interface TextFieldStyledProps {
38
38
  interface InputFieldStyledProps {
39
39
  isFloatingLabel: boolean;
40
40
  scale: Scale;
41
+ isFocused: boolean;
41
42
  }
42
43
  interface InputWrapperStyledProps {
43
44
  isFloatingLabel: boolean;
package/dist/index.js CHANGED
@@ -140,7 +140,7 @@ var InputContainerStyled = import_styled.default.div`
140
140
  `}
141
141
  `;
142
142
  var InputFieldStyled = import_styled.default.input`
143
- ${({ theme, isFloatingLabel, scale }) => `
143
+ ${({ theme, isFloatingLabel, scale, isFocused }) => `
144
144
  ${theme.fontStyles.bodyMdRegular}
145
145
  border: 0;
146
146
  outline: 0;
@@ -168,11 +168,7 @@ var InputFieldStyled = import_styled.default.input`
168
168
  }
169
169
 
170
170
  &::placeholder {
171
- color: ${isFloatingLabel ? "transparent" : theme.palette.content.medium};
172
- }
173
-
174
- &:focus::placeholder {
175
- color: ${theme.palette.content.medium};
171
+ color: ${isFloatingLabel && !isFocused ? "transparent" : theme.palette.content.medium};
176
172
  }
177
173
 
178
174
  &:disabled {
@@ -293,211 +289,219 @@ var InputWrapperStyled = import_styled.default.div`
293
289
 
294
290
  // src/TextField.tsx
295
291
  var import_jsx_runtime = require("react/jsx-runtime");
296
- var TextField = (_a) => {
297
- var _b = _a, {
298
- dataTestId,
299
- hasError = false,
300
- extraPrefix,
301
- extraSuffix,
302
- label,
303
- labelIcon,
304
- isFloatingLabel = true,
305
- name,
306
- id,
307
- required,
308
- requiredMessage,
309
- style,
310
- children,
311
- initialValue,
312
- inputRef,
313
- message: messageProp = "",
314
- type = "text",
315
- variant = "outlined",
316
- scale = "standard",
317
- backgroundFill = "default",
318
- disabled = false,
319
- onChange = () => null,
320
- onResetInput = () => null
321
- } = _b, rest = __objRest(_b, [
322
- "dataTestId",
323
- "hasError",
324
- "extraPrefix",
325
- "extraSuffix",
326
- "label",
327
- "labelIcon",
328
- "isFloatingLabel",
329
- "name",
330
- "id",
331
- "required",
332
- "requiredMessage",
333
- "style",
334
- "children",
335
- "initialValue",
336
- "inputRef",
337
- "message",
338
- "type",
339
- "variant",
340
- "scale",
341
- "backgroundFill",
342
- "disabled",
343
- "onChange",
344
- "onResetInput"
345
- ]);
346
- const [activeInput, setActiveInput] = (0, import_react.useState)(false);
347
- const [inputValue, setInputValue] = (0, import_react.useState)("");
348
- const [hasRequiredError, setHasRequiredError] = (0, import_react.useState)(false);
349
- const textFieldId = id != null ? id : label.replaceAll(" ", "-").toLowerCase();
350
- const testId = dataTestId != null ? dataTestId : `${label.replaceAll(" ", "-").toLowerCase()}-text-field`;
351
- (0, import_react.useEffect)(() => {
352
- if (!!initialValue) {
353
- setInputValue(initialValue);
292
+ var EXTRA_SUFFIX_DATA_TEST_ID = "extra-suffix";
293
+ var TextField = (0, import_react.forwardRef)(
294
+ (_a, ref) => {
295
+ var _b = _a, {
296
+ dataTestId,
297
+ hasError = false,
298
+ extraPrefix,
299
+ extraSuffix,
300
+ label,
301
+ labelIcon,
302
+ isFloatingLabel = true,
303
+ name,
304
+ id,
305
+ required,
306
+ requiredMessage,
307
+ style,
308
+ children,
309
+ initialValue,
310
+ inputRef,
311
+ isInputFocused,
312
+ message: messageProp = "",
313
+ type = "text",
314
+ variant = "outlined",
315
+ scale = "standard",
316
+ backgroundFill = "default",
317
+ disabled = false,
318
+ onChange = () => null,
319
+ onResetInput = () => null
320
+ } = _b, rest = __objRest(_b, [
321
+ "dataTestId",
322
+ "hasError",
323
+ "extraPrefix",
324
+ "extraSuffix",
325
+ "label",
326
+ "labelIcon",
327
+ "isFloatingLabel",
328
+ "name",
329
+ "id",
330
+ "required",
331
+ "requiredMessage",
332
+ "style",
333
+ "children",
334
+ "initialValue",
335
+ "inputRef",
336
+ "isInputFocused",
337
+ "message",
338
+ "type",
339
+ "variant",
340
+ "scale",
341
+ "backgroundFill",
342
+ "disabled",
343
+ "onChange",
344
+ "onResetInput"
345
+ ]);
346
+ const [activeInput, setActiveInput] = (0, import_react.useState)(false);
347
+ const [inputValue, setInputValue] = (0, import_react.useState)("");
348
+ const [hasRequiredError, setHasRequiredError] = (0, import_react.useState)(false);
349
+ const textFieldId = id != null ? id : label.replaceAll(" ", "-").toLowerCase();
350
+ const testId = dataTestId != null ? dataTestId : `${label.replaceAll(" ", "-").toLowerCase()}-text-field`;
351
+ (0, import_react.useEffect)(() => {
352
+ if (!!initialValue) {
353
+ setInputValue(initialValue);
354
+ setHasRequiredError(false);
355
+ } else {
356
+ setInputValue("");
357
+ }
358
+ }, [initialValue]);
359
+ const handleChange = (event) => {
360
+ setInputValue(event.target.value);
354
361
  setHasRequiredError(false);
355
- } else {
362
+ if (onChange) {
363
+ onChange(event);
364
+ }
365
+ };
366
+ const onFocus = (event) => {
367
+ if (!rest.readOnly) {
368
+ setActiveInput(true);
369
+ }
370
+ if (rest.onFocus) {
371
+ rest.onFocus(event);
372
+ }
373
+ };
374
+ const onBlur = (event) => {
375
+ var _a2;
376
+ setActiveInput(false);
377
+ const isEmptyOrOnlySpaces = event.currentTarget.value.trim().length === 0;
378
+ const isExtraSuffixClicked = ((_a2 = event.relatedTarget) == null ? void 0 : _a2.getAttribute("data-testid")) === EXTRA_SUFFIX_DATA_TEST_ID;
379
+ if (isEmptyOrOnlySpaces && required && !isExtraSuffixClicked) {
380
+ setHasRequiredError(true);
381
+ }
382
+ if (rest.onBlur) {
383
+ rest.onBlur(event);
384
+ }
385
+ };
386
+ const handleResetInput = () => {
356
387
  setInputValue("");
357
- }
358
- }, [initialValue]);
359
- const handleChange = (event) => {
360
- setInputValue(event.target.value);
361
- setHasRequiredError(false);
362
- if (onChange) {
363
- onChange(event);
364
- }
365
- };
366
- const onFocus = (event) => {
367
- if (!rest.readOnly) {
368
- setActiveInput(true);
369
- }
370
- if (rest.onFocus) {
371
- rest.onFocus(event);
372
- }
373
- };
374
- const onBlur = (event) => {
375
- setActiveInput(false);
376
- const isEmptyOrOnlySpaces = event.currentTarget.value.trim().length === 0;
377
- if (isEmptyOrOnlySpaces && required) {
378
- setHasRequiredError(true);
379
- }
380
- if (rest.onBlur) {
381
- rest.onBlur(event);
382
- }
383
- };
384
- const handleResetInput = () => {
385
- setInputValue("");
386
- setActiveInput(false);
387
- onResetInput();
388
- };
389
- const handleExtraPreffixEnter = (event) => event.code === "Enter" && (extraPrefix == null ? void 0 : extraPrefix.onClick) && extraPrefix.onClick(inputValue);
390
- const handleExtraSuffixEnter = (event) => event.code === "Enter" && (extraSuffix == null ? void 0 : extraSuffix.onClick) && extraSuffix.onClick(inputValue);
391
- const messageColor = disabled ? "content.light" : "content.medium";
392
- const showError = hasError || hasRequiredError;
393
- const message = hasRequiredError ? requiredMessage != null ? requiredMessage : messageProp : messageProp;
394
- const isActiveInput = activeInput || !!inputValue.trim();
395
- const isSearchType = type === "search";
396
- const extraPreffixOnClick = (extraPrefix == null ? void 0 : extraPrefix.onClick) ? extraPrefix.onClick : null;
397
- const extraSuffixOnClick = (extraSuffix == null ? void 0 : extraSuffix.onClick) ? extraSuffix.onClick : null;
398
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
399
- TextFieldStyled,
400
- {
401
- "data-testid": testId,
402
- hasPrefix: !!extraPrefix,
403
- isFloatingLabel,
404
- style,
405
- children: [
406
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InputContainerStyled, { isFloatingLabel, children: [
407
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
408
- import_react_label_field.LabelField,
409
- {
410
- hasError: showError,
411
- htmlFor: textFieldId,
412
- icon: labelIcon,
413
- isActive: activeInput,
414
- isCentered: !isActiveInput && isFloatingLabel,
415
- isDisabled: disabled,
416
- isFloating: isFloatingLabel,
417
- isInputFilled: !!inputValue,
418
- isRequired: required,
419
- scale,
420
- children: label
421
- }
422
- ),
423
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
424
- InputWrapperStyled,
388
+ setActiveInput(false);
389
+ onResetInput();
390
+ };
391
+ const handleExtraPrefixEnter = (event) => event.code === "Enter" && (extraPrefix == null ? void 0 : extraPrefix.onClick) && extraPrefix.onClick(inputValue);
392
+ const handleExtraSuffixEnter = (event) => event.code === "Enter" && (extraSuffix == null ? void 0 : extraSuffix.onClick) && extraSuffix.onClick(inputValue);
393
+ const messageColor = disabled ? "content.light" : "content.medium";
394
+ const showError = hasError || hasRequiredError;
395
+ const message = hasRequiredError ? requiredMessage != null ? requiredMessage : messageProp : messageProp;
396
+ const isActiveInput = isInputFocused || activeInput || !!inputValue.trim();
397
+ const isSearchType = type === "search";
398
+ const extraPrefixOnClick = (extraPrefix == null ? void 0 : extraPrefix.onClick) ? extraPrefix.onClick : null;
399
+ const extraSuffixOnClick = (extraSuffix == null ? void 0 : extraSuffix.onClick) ? extraSuffix.onClick : null;
400
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
401
+ TextFieldStyled,
402
+ {
403
+ "data-testid": testId,
404
+ hasPrefix: !!extraPrefix,
405
+ isFloatingLabel,
406
+ style,
407
+ children: [
408
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(InputContainerStyled, { isFloatingLabel, ref, children: [
409
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
410
+ import_react_label_field.LabelField,
411
+ {
412
+ hasError: showError,
413
+ htmlFor: textFieldId,
414
+ icon: labelIcon,
415
+ isActive: isActiveInput,
416
+ isCentered: !isActiveInput && isFloatingLabel,
417
+ isDisabled: disabled,
418
+ isFloating: isFloatingLabel,
419
+ isInputFilled: !!inputValue,
420
+ isRequired: required,
421
+ scale,
422
+ children: label
423
+ }
424
+ ),
425
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
426
+ InputWrapperStyled,
427
+ {
428
+ backgroundFill,
429
+ "data-testid": `${testId}-wrapper`,
430
+ hasError: showError,
431
+ isFloatingLabel,
432
+ variant,
433
+ children: [
434
+ (extraPrefix == null ? void 0 : extraPrefix.component) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
435
+ InputExtraPrefixStyled,
436
+ __spreadProps(__spreadValues({
437
+ "data-testid": "extra-prefix"
438
+ }, !!extraPrefixOnClick && {
439
+ tabIndex: 0,
440
+ onClick: () => !disabled && extraPrefixOnClick(inputValue),
441
+ onKeyDown: handleExtraPrefixEnter
442
+ }), {
443
+ children: extraPrefix.component
444
+ })
445
+ ) : null,
446
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
447
+ InputFieldStyled,
448
+ __spreadProps(__spreadValues({
449
+ "data-error": showError,
450
+ "data-testid": `${testId}-input`,
451
+ disabled,
452
+ id: textFieldId,
453
+ isFloatingLabel,
454
+ isFocused: isActiveInput,
455
+ name: name != null ? name : textFieldId,
456
+ ref: inputRef,
457
+ scale,
458
+ type,
459
+ value: inputValue
460
+ }, rest), {
461
+ onBlur,
462
+ onChange: handleChange,
463
+ onFocus
464
+ })
465
+ ),
466
+ isSearchType && !!inputValue ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
467
+ import_react_icon_button.IconButton,
468
+ {
469
+ dataTestId: "reset-icon",
470
+ onClick: handleResetInput,
471
+ style: { marginRight: 12 },
472
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icon.Icon, { code: "close" })
473
+ }
474
+ ) : null,
475
+ (extraSuffix == null ? void 0 : extraSuffix.component) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
476
+ InputExtraSuffixStyled,
477
+ __spreadProps(__spreadValues({
478
+ "data-testid": EXTRA_SUFFIX_DATA_TEST_ID
479
+ }, !!extraSuffixOnClick && {
480
+ tabIndex: 0,
481
+ onClick: () => !disabled && extraSuffixOnClick(inputValue),
482
+ onKeyDown: handleExtraSuffixEnter
483
+ }), {
484
+ children: extraSuffix.component
485
+ })
486
+ ) : null
487
+ ]
488
+ }
489
+ )
490
+ ] }),
491
+ message ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextFieldMessageStyled, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
492
+ import_react_typography.Typography,
425
493
  {
426
- backgroundFill,
427
- "data-testid": `${testId}-wrapper`,
428
- hasError: showError,
429
- isFloatingLabel,
430
- variant,
431
- children: [
432
- (extraPrefix == null ? void 0 : extraPrefix.component) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
433
- InputExtraPrefixStyled,
434
- __spreadProps(__spreadValues({
435
- "data-testid": "extra-preffix"
436
- }, !!extraPreffixOnClick && {
437
- tabIndex: 0,
438
- onClick: () => extraPreffixOnClick(inputValue),
439
- onKeyDown: handleExtraPreffixEnter
440
- }), {
441
- children: extraPrefix.component
442
- })
443
- ) : null,
444
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
445
- InputFieldStyled,
446
- __spreadProps(__spreadValues({
447
- "data-error": showError,
448
- "data-testid": `${testId}-input`,
449
- disabled,
450
- id: textFieldId,
451
- isFloatingLabel,
452
- name: name != null ? name : textFieldId,
453
- ref: inputRef,
454
- scale,
455
- type,
456
- value: inputValue
457
- }, rest), {
458
- onBlur,
459
- onChange: handleChange,
460
- onFocus
461
- })
462
- ),
463
- isSearchType && !!inputValue ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
464
- import_react_icon_button.IconButton,
465
- {
466
- dataTestId: "reset-icon",
467
- onClick: handleResetInput,
468
- style: { marginRight: 12 },
469
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_icon.Icon, { code: "close" })
470
- }
471
- ) : null,
472
- (extraSuffix == null ? void 0 : extraSuffix.component) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
473
- InputExtraSuffixStyled,
474
- __spreadProps(__spreadValues({
475
- "data-testid": "extra-suffix"
476
- }, !!extraSuffixOnClick && {
477
- tabIndex: 0,
478
- onClick: () => extraSuffixOnClick(inputValue),
479
- onKeyDown: handleExtraSuffixEnter
480
- }), {
481
- children: extraSuffix.component
482
- })
483
- ) : null
484
- ]
494
+ color: showError ? "error.default" : messageColor,
495
+ fontStyles: "bodySmRegular",
496
+ children: message
485
497
  }
486
- )
487
- ] }),
488
- message ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TextFieldMessageStyled, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
489
- import_react_typography.Typography,
490
- {
491
- color: showError ? "error.default" : messageColor,
492
- fontStyles: "bodySmRegular",
493
- children: message
494
- }
495
- ) }) : null,
496
- children
497
- ]
498
- }
499
- );
500
- };
498
+ ) }) : null,
499
+ children
500
+ ]
501
+ }
502
+ );
503
+ }
504
+ );
501
505
  // Annotate the CommonJS export names for ESM import in node:
502
506
  0 && (module.exports = {
503
507
  InputContainerStyled,
package/dist/index.mjs CHANGED
@@ -36,6 +36,7 @@ import { IconButton } from "@dt-dds/react-icon-button";
36
36
  import { LabelField } from "@dt-dds/react-label-field";
37
37
  import { Typography } from "@dt-dds/react-typography";
38
38
  import {
39
+ forwardRef,
39
40
  useEffect,
40
41
  useState
41
42
  } from "react";
@@ -103,7 +104,7 @@ var InputContainerStyled = styled.div`
103
104
  `}
104
105
  `;
105
106
  var InputFieldStyled = styled.input`
106
- ${({ theme, isFloatingLabel, scale }) => `
107
+ ${({ theme, isFloatingLabel, scale, isFocused }) => `
107
108
  ${theme.fontStyles.bodyMdRegular}
108
109
  border: 0;
109
110
  outline: 0;
@@ -131,11 +132,7 @@ var InputFieldStyled = styled.input`
131
132
  }
132
133
 
133
134
  &::placeholder {
134
- color: ${isFloatingLabel ? "transparent" : theme.palette.content.medium};
135
- }
136
-
137
- &:focus::placeholder {
138
- color: ${theme.palette.content.medium};
135
+ color: ${isFloatingLabel && !isFocused ? "transparent" : theme.palette.content.medium};
139
136
  }
140
137
 
141
138
  &:disabled {
@@ -256,211 +253,219 @@ var InputWrapperStyled = styled.div`
256
253
 
257
254
  // src/TextField.tsx
258
255
  import { jsx, jsxs } from "react/jsx-runtime";
259
- var TextField = (_a) => {
260
- var _b = _a, {
261
- dataTestId,
262
- hasError = false,
263
- extraPrefix,
264
- extraSuffix,
265
- label,
266
- labelIcon,
267
- isFloatingLabel = true,
268
- name,
269
- id,
270
- required,
271
- requiredMessage,
272
- style,
273
- children,
274
- initialValue,
275
- inputRef,
276
- message: messageProp = "",
277
- type = "text",
278
- variant = "outlined",
279
- scale = "standard",
280
- backgroundFill = "default",
281
- disabled = false,
282
- onChange = () => null,
283
- onResetInput = () => null
284
- } = _b, rest = __objRest(_b, [
285
- "dataTestId",
286
- "hasError",
287
- "extraPrefix",
288
- "extraSuffix",
289
- "label",
290
- "labelIcon",
291
- "isFloatingLabel",
292
- "name",
293
- "id",
294
- "required",
295
- "requiredMessage",
296
- "style",
297
- "children",
298
- "initialValue",
299
- "inputRef",
300
- "message",
301
- "type",
302
- "variant",
303
- "scale",
304
- "backgroundFill",
305
- "disabled",
306
- "onChange",
307
- "onResetInput"
308
- ]);
309
- const [activeInput, setActiveInput] = useState(false);
310
- const [inputValue, setInputValue] = useState("");
311
- const [hasRequiredError, setHasRequiredError] = useState(false);
312
- const textFieldId = id != null ? id : label.replaceAll(" ", "-").toLowerCase();
313
- const testId = dataTestId != null ? dataTestId : `${label.replaceAll(" ", "-").toLowerCase()}-text-field`;
314
- useEffect(() => {
315
- if (!!initialValue) {
316
- setInputValue(initialValue);
256
+ var EXTRA_SUFFIX_DATA_TEST_ID = "extra-suffix";
257
+ var TextField = forwardRef(
258
+ (_a, ref) => {
259
+ var _b = _a, {
260
+ dataTestId,
261
+ hasError = false,
262
+ extraPrefix,
263
+ extraSuffix,
264
+ label,
265
+ labelIcon,
266
+ isFloatingLabel = true,
267
+ name,
268
+ id,
269
+ required,
270
+ requiredMessage,
271
+ style,
272
+ children,
273
+ initialValue,
274
+ inputRef,
275
+ isInputFocused,
276
+ message: messageProp = "",
277
+ type = "text",
278
+ variant = "outlined",
279
+ scale = "standard",
280
+ backgroundFill = "default",
281
+ disabled = false,
282
+ onChange = () => null,
283
+ onResetInput = () => null
284
+ } = _b, rest = __objRest(_b, [
285
+ "dataTestId",
286
+ "hasError",
287
+ "extraPrefix",
288
+ "extraSuffix",
289
+ "label",
290
+ "labelIcon",
291
+ "isFloatingLabel",
292
+ "name",
293
+ "id",
294
+ "required",
295
+ "requiredMessage",
296
+ "style",
297
+ "children",
298
+ "initialValue",
299
+ "inputRef",
300
+ "isInputFocused",
301
+ "message",
302
+ "type",
303
+ "variant",
304
+ "scale",
305
+ "backgroundFill",
306
+ "disabled",
307
+ "onChange",
308
+ "onResetInput"
309
+ ]);
310
+ const [activeInput, setActiveInput] = useState(false);
311
+ const [inputValue, setInputValue] = useState("");
312
+ const [hasRequiredError, setHasRequiredError] = useState(false);
313
+ const textFieldId = id != null ? id : label.replaceAll(" ", "-").toLowerCase();
314
+ const testId = dataTestId != null ? dataTestId : `${label.replaceAll(" ", "-").toLowerCase()}-text-field`;
315
+ useEffect(() => {
316
+ if (!!initialValue) {
317
+ setInputValue(initialValue);
318
+ setHasRequiredError(false);
319
+ } else {
320
+ setInputValue("");
321
+ }
322
+ }, [initialValue]);
323
+ const handleChange = (event) => {
324
+ setInputValue(event.target.value);
317
325
  setHasRequiredError(false);
318
- } else {
326
+ if (onChange) {
327
+ onChange(event);
328
+ }
329
+ };
330
+ const onFocus = (event) => {
331
+ if (!rest.readOnly) {
332
+ setActiveInput(true);
333
+ }
334
+ if (rest.onFocus) {
335
+ rest.onFocus(event);
336
+ }
337
+ };
338
+ const onBlur = (event) => {
339
+ var _a2;
340
+ setActiveInput(false);
341
+ const isEmptyOrOnlySpaces = event.currentTarget.value.trim().length === 0;
342
+ const isExtraSuffixClicked = ((_a2 = event.relatedTarget) == null ? void 0 : _a2.getAttribute("data-testid")) === EXTRA_SUFFIX_DATA_TEST_ID;
343
+ if (isEmptyOrOnlySpaces && required && !isExtraSuffixClicked) {
344
+ setHasRequiredError(true);
345
+ }
346
+ if (rest.onBlur) {
347
+ rest.onBlur(event);
348
+ }
349
+ };
350
+ const handleResetInput = () => {
319
351
  setInputValue("");
320
- }
321
- }, [initialValue]);
322
- const handleChange = (event) => {
323
- setInputValue(event.target.value);
324
- setHasRequiredError(false);
325
- if (onChange) {
326
- onChange(event);
327
- }
328
- };
329
- const onFocus = (event) => {
330
- if (!rest.readOnly) {
331
- setActiveInput(true);
332
- }
333
- if (rest.onFocus) {
334
- rest.onFocus(event);
335
- }
336
- };
337
- const onBlur = (event) => {
338
- setActiveInput(false);
339
- const isEmptyOrOnlySpaces = event.currentTarget.value.trim().length === 0;
340
- if (isEmptyOrOnlySpaces && required) {
341
- setHasRequiredError(true);
342
- }
343
- if (rest.onBlur) {
344
- rest.onBlur(event);
345
- }
346
- };
347
- const handleResetInput = () => {
348
- setInputValue("");
349
- setActiveInput(false);
350
- onResetInput();
351
- };
352
- const handleExtraPreffixEnter = (event) => event.code === "Enter" && (extraPrefix == null ? void 0 : extraPrefix.onClick) && extraPrefix.onClick(inputValue);
353
- const handleExtraSuffixEnter = (event) => event.code === "Enter" && (extraSuffix == null ? void 0 : extraSuffix.onClick) && extraSuffix.onClick(inputValue);
354
- const messageColor = disabled ? "content.light" : "content.medium";
355
- const showError = hasError || hasRequiredError;
356
- const message = hasRequiredError ? requiredMessage != null ? requiredMessage : messageProp : messageProp;
357
- const isActiveInput = activeInput || !!inputValue.trim();
358
- const isSearchType = type === "search";
359
- const extraPreffixOnClick = (extraPrefix == null ? void 0 : extraPrefix.onClick) ? extraPrefix.onClick : null;
360
- const extraSuffixOnClick = (extraSuffix == null ? void 0 : extraSuffix.onClick) ? extraSuffix.onClick : null;
361
- return /* @__PURE__ */ jsxs(
362
- TextFieldStyled,
363
- {
364
- "data-testid": testId,
365
- hasPrefix: !!extraPrefix,
366
- isFloatingLabel,
367
- style,
368
- children: [
369
- /* @__PURE__ */ jsxs(InputContainerStyled, { isFloatingLabel, children: [
370
- /* @__PURE__ */ jsx(
371
- LabelField,
372
- {
373
- hasError: showError,
374
- htmlFor: textFieldId,
375
- icon: labelIcon,
376
- isActive: activeInput,
377
- isCentered: !isActiveInput && isFloatingLabel,
378
- isDisabled: disabled,
379
- isFloating: isFloatingLabel,
380
- isInputFilled: !!inputValue,
381
- isRequired: required,
382
- scale,
383
- children: label
384
- }
385
- ),
386
- /* @__PURE__ */ jsxs(
387
- InputWrapperStyled,
352
+ setActiveInput(false);
353
+ onResetInput();
354
+ };
355
+ const handleExtraPrefixEnter = (event) => event.code === "Enter" && (extraPrefix == null ? void 0 : extraPrefix.onClick) && extraPrefix.onClick(inputValue);
356
+ const handleExtraSuffixEnter = (event) => event.code === "Enter" && (extraSuffix == null ? void 0 : extraSuffix.onClick) && extraSuffix.onClick(inputValue);
357
+ const messageColor = disabled ? "content.light" : "content.medium";
358
+ const showError = hasError || hasRequiredError;
359
+ const message = hasRequiredError ? requiredMessage != null ? requiredMessage : messageProp : messageProp;
360
+ const isActiveInput = isInputFocused || activeInput || !!inputValue.trim();
361
+ const isSearchType = type === "search";
362
+ const extraPrefixOnClick = (extraPrefix == null ? void 0 : extraPrefix.onClick) ? extraPrefix.onClick : null;
363
+ const extraSuffixOnClick = (extraSuffix == null ? void 0 : extraSuffix.onClick) ? extraSuffix.onClick : null;
364
+ return /* @__PURE__ */ jsxs(
365
+ TextFieldStyled,
366
+ {
367
+ "data-testid": testId,
368
+ hasPrefix: !!extraPrefix,
369
+ isFloatingLabel,
370
+ style,
371
+ children: [
372
+ /* @__PURE__ */ jsxs(InputContainerStyled, { isFloatingLabel, ref, children: [
373
+ /* @__PURE__ */ jsx(
374
+ LabelField,
375
+ {
376
+ hasError: showError,
377
+ htmlFor: textFieldId,
378
+ icon: labelIcon,
379
+ isActive: isActiveInput,
380
+ isCentered: !isActiveInput && isFloatingLabel,
381
+ isDisabled: disabled,
382
+ isFloating: isFloatingLabel,
383
+ isInputFilled: !!inputValue,
384
+ isRequired: required,
385
+ scale,
386
+ children: label
387
+ }
388
+ ),
389
+ /* @__PURE__ */ jsxs(
390
+ InputWrapperStyled,
391
+ {
392
+ backgroundFill,
393
+ "data-testid": `${testId}-wrapper`,
394
+ hasError: showError,
395
+ isFloatingLabel,
396
+ variant,
397
+ children: [
398
+ (extraPrefix == null ? void 0 : extraPrefix.component) ? /* @__PURE__ */ jsx(
399
+ InputExtraPrefixStyled,
400
+ __spreadProps(__spreadValues({
401
+ "data-testid": "extra-prefix"
402
+ }, !!extraPrefixOnClick && {
403
+ tabIndex: 0,
404
+ onClick: () => !disabled && extraPrefixOnClick(inputValue),
405
+ onKeyDown: handleExtraPrefixEnter
406
+ }), {
407
+ children: extraPrefix.component
408
+ })
409
+ ) : null,
410
+ /* @__PURE__ */ jsx(
411
+ InputFieldStyled,
412
+ __spreadProps(__spreadValues({
413
+ "data-error": showError,
414
+ "data-testid": `${testId}-input`,
415
+ disabled,
416
+ id: textFieldId,
417
+ isFloatingLabel,
418
+ isFocused: isActiveInput,
419
+ name: name != null ? name : textFieldId,
420
+ ref: inputRef,
421
+ scale,
422
+ type,
423
+ value: inputValue
424
+ }, rest), {
425
+ onBlur,
426
+ onChange: handleChange,
427
+ onFocus
428
+ })
429
+ ),
430
+ isSearchType && !!inputValue ? /* @__PURE__ */ jsx(
431
+ IconButton,
432
+ {
433
+ dataTestId: "reset-icon",
434
+ onClick: handleResetInput,
435
+ style: { marginRight: 12 },
436
+ children: /* @__PURE__ */ jsx(Icon, { code: "close" })
437
+ }
438
+ ) : null,
439
+ (extraSuffix == null ? void 0 : extraSuffix.component) ? /* @__PURE__ */ jsx(
440
+ InputExtraSuffixStyled,
441
+ __spreadProps(__spreadValues({
442
+ "data-testid": EXTRA_SUFFIX_DATA_TEST_ID
443
+ }, !!extraSuffixOnClick && {
444
+ tabIndex: 0,
445
+ onClick: () => !disabled && extraSuffixOnClick(inputValue),
446
+ onKeyDown: handleExtraSuffixEnter
447
+ }), {
448
+ children: extraSuffix.component
449
+ })
450
+ ) : null
451
+ ]
452
+ }
453
+ )
454
+ ] }),
455
+ message ? /* @__PURE__ */ jsx(TextFieldMessageStyled, { children: /* @__PURE__ */ jsx(
456
+ Typography,
388
457
  {
389
- backgroundFill,
390
- "data-testid": `${testId}-wrapper`,
391
- hasError: showError,
392
- isFloatingLabel,
393
- variant,
394
- children: [
395
- (extraPrefix == null ? void 0 : extraPrefix.component) ? /* @__PURE__ */ jsx(
396
- InputExtraPrefixStyled,
397
- __spreadProps(__spreadValues({
398
- "data-testid": "extra-preffix"
399
- }, !!extraPreffixOnClick && {
400
- tabIndex: 0,
401
- onClick: () => extraPreffixOnClick(inputValue),
402
- onKeyDown: handleExtraPreffixEnter
403
- }), {
404
- children: extraPrefix.component
405
- })
406
- ) : null,
407
- /* @__PURE__ */ jsx(
408
- InputFieldStyled,
409
- __spreadProps(__spreadValues({
410
- "data-error": showError,
411
- "data-testid": `${testId}-input`,
412
- disabled,
413
- id: textFieldId,
414
- isFloatingLabel,
415
- name: name != null ? name : textFieldId,
416
- ref: inputRef,
417
- scale,
418
- type,
419
- value: inputValue
420
- }, rest), {
421
- onBlur,
422
- onChange: handleChange,
423
- onFocus
424
- })
425
- ),
426
- isSearchType && !!inputValue ? /* @__PURE__ */ jsx(
427
- IconButton,
428
- {
429
- dataTestId: "reset-icon",
430
- onClick: handleResetInput,
431
- style: { marginRight: 12 },
432
- children: /* @__PURE__ */ jsx(Icon, { code: "close" })
433
- }
434
- ) : null,
435
- (extraSuffix == null ? void 0 : extraSuffix.component) ? /* @__PURE__ */ jsx(
436
- InputExtraSuffixStyled,
437
- __spreadProps(__spreadValues({
438
- "data-testid": "extra-suffix"
439
- }, !!extraSuffixOnClick && {
440
- tabIndex: 0,
441
- onClick: () => extraSuffixOnClick(inputValue),
442
- onKeyDown: handleExtraSuffixEnter
443
- }), {
444
- children: extraSuffix.component
445
- })
446
- ) : null
447
- ]
458
+ color: showError ? "error.default" : messageColor,
459
+ fontStyles: "bodySmRegular",
460
+ children: message
448
461
  }
449
- )
450
- ] }),
451
- message ? /* @__PURE__ */ jsx(TextFieldMessageStyled, { children: /* @__PURE__ */ jsx(
452
- Typography,
453
- {
454
- color: showError ? "error.default" : messageColor,
455
- fontStyles: "bodySmRegular",
456
- children: message
457
- }
458
- ) }) : null,
459
- children
460
- ]
461
- }
462
- );
463
- };
462
+ ) }) : null,
463
+ children
464
+ ]
465
+ }
466
+ );
467
+ }
468
+ );
464
469
  export {
465
470
  InputContainerStyled,
466
471
  InputExtraPrefixStyled,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dt-dds/react-text-field",
3
- "version": "1.0.0-beta.89",
3
+ "version": "1.0.0-beta.90",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./dist/index.js"
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@dt-dds/react-core": "1.0.0-beta.51",
24
- "@dt-dds/react-spinner": "1.0.0-beta.84",
24
+ "@dt-dds/react-spinner": "1.0.0-beta.85",
25
25
  "@dt-dds/react-label-field": "1.0.0-beta.52",
26
26
  "@dt-dds/react-typography": "1.0.0-beta.42",
27
27
  "@dt-dds/react-icon-button": "1.0.0-beta.20",