diff --git a/lib/index.ts b/lib/index.ts index 8388e508..127d68d7 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -136,6 +136,7 @@ export * from '@/components/organisms/FancyPasswordInput'; export * from '@/components/organisms/FancyTextInput'; export * from '@/components/organisms/FancyColorInput'; export * from '@/components/organisms/FancyListBox'; +export * from '@/components/organisms/FancyTextArea'; // ---------- Templates ------- // export * from '@/components/templates/FancyInfoCard'; diff --git a/src/Routes/InputsRoute/InputsRoute.tsx b/src/Routes/InputsRoute/InputsRoute.tsx index 789b668e..c96233fc 100644 --- a/src/Routes/InputsRoute/InputsRoute.tsx +++ b/src/Routes/InputsRoute/InputsRoute.tsx @@ -12,6 +12,7 @@ import { Card } from '@/components/molecules/Card'; import LabeledInput from '@/components/molecules/LabeledInput/LabeledInput'; import { TextInput } from '@/components/atoms/TextInput'; import FancyRange from '@/components/organisms/FancyRangeSlider/FancyRangeSlider'; +import FancyTextArea from '@/components/organisms/FancyTextArea/FancyTextArea'; const svg = ( @@ -28,6 +29,11 @@ export default function InputsRoute() { const [dropDown2, setDropDown2] = useState('test'); const [password, setPassword] = useState(''); const [newInput, setNewInput] = useState(''); + const [textArea, setTextArea] = useState(''); + + const handleTextArea = (value: ChangeEvent) => { + setTextArea(value.target.value); + }; const newInputHandler = (value: ChangeEvent) => { setNewInput(value.target.value); @@ -71,134 +77,142 @@ export default function InputsRoute() { `; return ( - - - - - } - /> - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + } + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); } diff --git a/src/components/atoms/DateInput/DateInput.style.tsx b/src/components/atoms/DateInput/DateInput.style.tsx index 707d3a89..5ebbbc98 100644 --- a/src/components/atoms/DateInput/DateInput.style.tsx +++ b/src/components/atoms/DateInput/DateInput.style.tsx @@ -14,9 +14,10 @@ type IRawInputWrapper = { export const StyledDatePicker = styled(RawInput)` color: ${({ $isActive, $themeType = 'secondary', $layer, theme }) => $isActive ? getBackgroundColor({ theme, $themeType, $layer }) : 'transparent'}; - height: ${({ theme }) => theme.globalElementSizes.md}; + height: 18px; transition: color 0.3s ease-in; font-family: inherit; + box-sizing: content-box; /* This renders a Placerholder in Text when its needed */ ${({ placeholder, $themeType = 'secondary', $layer = 4, value, theme, $align, $isActive }) => { diff --git a/src/components/atoms/DropDownSelect/DropDownSelect.style.tsx b/src/components/atoms/DropDownSelect/DropDownSelect.style.tsx index 81fff2ea..41527b87 100644 --- a/src/components/atoms/DropDownSelect/DropDownSelect.style.tsx +++ b/src/components/atoms/DropDownSelect/DropDownSelect.style.tsx @@ -20,7 +20,7 @@ export const SelectField = styled.select` `} background-repeat: no-repeat; - background-position: right ${({ theme }) => theme.spacing.xxs} bottom 30%; + background-position: right ${({ theme }) => theme.spacing.xxs} bottom 70%; text-align-last: ${({ $align }) => ($align !== 'center' ? 'left' : 'center')}; color: ${({ theme }) => theme.color.secondary[0]}; border: none; diff --git a/src/components/atoms/InputLabel/utils/generateLableVariant.ts b/src/components/atoms/InputLabel/utils/generateLableVariant.ts index cc01781c..f8b844cf 100644 --- a/src/components/atoms/InputLabel/utils/generateLableVariant.ts +++ b/src/components/atoms/InputLabel/utils/generateLableVariant.ts @@ -36,13 +36,13 @@ export function generateLableVariant(props: TgenerateLableVariant) { case 'center': return css` left: 50%; - top: ${$isActive ? '8px' : '56%'}; + top: ${$isActive ? '8px' : '21px'}; font-size: ${$isActive ? '12px' : '18px'}; transform: translateX(-50%) translateY(-50%); `; case 'right': return css` - top: ${$isActive ? '8px' : '56%'}; + top: ${$isActive ? '8px' : '21px'}; right: 0; font-size: ${$isActive ? '12px' : '18px'}; transform: translateY(-50%); @@ -50,7 +50,7 @@ export function generateLableVariant(props: TgenerateLableVariant) { case 'left': default: return css` - top: ${$isActive ? '8px' : '56%'}; + top: ${$isActive ? '8px' : '21px'}; font-size: ${$isActive ? '12px' : '18px'}; transform: translateY(-50%); `; diff --git a/src/components/atoms/PasswordInput/PasswordInput.style.tsx b/src/components/atoms/PasswordInput/PasswordInput.style.tsx index 9a5c1930..e515ef05 100644 --- a/src/components/atoms/PasswordInput/PasswordInput.style.tsx +++ b/src/components/atoms/PasswordInput/PasswordInput.style.tsx @@ -7,9 +7,9 @@ import { getBackgroundColor } from '@/design/designFunctions/colorCalculatorForC export const WrapperEye = styled.div<{ theme: TTheme; $themeType?: TUiColorsNotTransparent; $layer?: TLayer }>` position: absolute; - bottom: 0px; + bottom: 50%; + transform: translateY(65%); right: 0; - padding: ${({ theme }) => `${theme.spacing.xs} 0 ${theme.spacing.xxs} ${theme.spacing.xs}`}; box-sizing: border-box; svg { diff --git a/src/components/atoms/RawTextArea/RawTextArea.tsx b/src/components/atoms/RawTextArea/RawTextArea.tsx new file mode 100644 index 00000000..73ecf6ae --- /dev/null +++ b/src/components/atoms/RawTextArea/RawTextArea.tsx @@ -0,0 +1,32 @@ +import { getBackgroundColor } from '@/design/designFunctions/colorCalculatorForComponent'; +import { TLayer } from '@/types/TLayer'; +import { TStyledPrefixAndPicker } from '@/types/TStyledPrefixAndPicker'; +import { TTheme } from '@/types/TTheme'; +import { TUiColorsNotTransparent } from '@/types/TUiColorsNotTransparent'; + +import { styled } from 'styled-components'; + +type TRawTextArea = { + themeType?: TUiColorsNotTransparent; + layer?: TLayer; +}; + +export type TRawTextAreaWithHTMLAttrs = TRawTextArea & React.TextareaHTMLAttributes; + +type TRawTextAreaWith$ = TStyledPrefixAndPicker; + +const RawTextArea = styled.textarea` + border: none; + box-sizing: border-box; + appearance: none; + outline: none; + width: 100%; + font-family: inherit; + min-height: ${({ theme }) => theme.globalElementSizes.xs}; + font-size: ${({ theme }) => theme.fontSizes.interactiveMd.fontSize}; + background-color: transparent; + resize: vertical; + color: ${({ theme, $themeType = 'secondary', $layer }) => getBackgroundColor({ theme, $themeType, $layer })}; +`; + +export default RawTextArea; diff --git a/src/components/molecules/InputWrapper/InputWrapper.style.tsx b/src/components/molecules/InputWrapper/InputWrapper.style.tsx index 7a7ddf68..b176f007 100644 --- a/src/components/molecules/InputWrapper/InputWrapper.style.tsx +++ b/src/components/molecules/InputWrapper/InputWrapper.style.tsx @@ -4,14 +4,14 @@ import { TTheme } from '@/types/TTheme'; import { FancyBox } from '@/components/atoms/FancyBox'; import { disabledStyle } from '@/design/designFunctions/disabledStyle'; -const PositionWithLabel = css<{ theme: TTheme }>` - padding: ${({ theme }) => `${theme.spacing.xxs} ${theme.spacing.sm} ${theme.spacing.xs}`}; - height: ${({ theme }) => theme.globalElementSizes.lg}; +const PositionWithLabel = (theme: TTheme, $isTextArea: boolean) => css` + padding: ${theme.spacing.xxs} ${theme.spacing.sm} ${theme.spacing.xxs}; + height: ${!$isTextArea ? theme.globalElementSizes.lg : ''}; `; -const PositionWithoutLabel = css<{ theme: TTheme }>` - padding: ${({ theme }) => `2px ${theme.spacing.sm} ${theme.spacing.xxs}`}; - height: ${({ theme }) => theme.globalElementSizes.sm}; +const PositionWithoutLabel = (theme: TTheme, $isTextArea: boolean) => css` + padding: ${`2px ${theme.spacing.sm} ${theme.spacing.xxs}`}; + height: ${!$isTextArea ? theme.globalElementSizes.sm : ''}; `; type TExtendedFancyBox = { @@ -28,7 +28,7 @@ export const ExtendedFancyBox = styled(FancyBox)` border-radius: 12px; position: relative; align-items: center; - ${({ $hasLabel }) => ($hasLabel ? PositionWithLabel : PositionWithoutLabel)}; + ${({ $hasLabel, theme }) => ($hasLabel ? PositionWithLabel(theme, true) : PositionWithoutLabel(theme, true))}; width: ${({ $autoWidth }) => ($autoWidth ? 'auto' : '100%')}; ${({ $boxShadow, $isActive, theme }) => @@ -45,7 +45,7 @@ export const ExtendedFancyBox = styled(FancyBox)` // eslint-disable-next-line react-refresh/only-export-components export const generateIconStyle = (hasLabel: boolean) => css<{ theme: TTheme }>` flex-shrink: 0; - margin-top: ${hasLabel ? '10px' : '3px'}; + margin-top: ${hasLabel ? '10px' : '5px'}; transition: 0.25s; align-self: self-start; `; diff --git a/src/components/molecules/InputWrapper/InputWrapper.tsx b/src/components/molecules/InputWrapper/InputWrapper.tsx index 1ab4ebd5..ee39fa32 100644 --- a/src/components/molecules/InputWrapper/InputWrapper.tsx +++ b/src/components/molecules/InputWrapper/InputWrapper.tsx @@ -13,6 +13,7 @@ export default function InputWrapper(props: TInputWrapper) { id, hasValue, isActive = false, + isTextArea, disabled, InputElement, systemMessage, @@ -66,6 +67,7 @@ export default function InputWrapper(props: TInputWrapper) { ; @@ -29,5 +30,15 @@ export type TInputWrapper = { export type TInputWrapperUserInputProps = Omit< TInputWrapper, - 'children' | 'id' | 'autoWidth' | 'value' | 'borderRadius' | 'sizeC' | 'isActive' | 'hasValue' | 'as' | 'InputElement' + | 'children' + | 'id' + | 'autoWidth' + | 'value' + | 'borderRadius' + | 'sizeC' + | 'isActive' + | 'hasValue' + | 'as' + | 'InputElement' + | 'isTextArea' >; diff --git a/src/components/molecules/LabeledInput/LabeledInput.style.tsx b/src/components/molecules/LabeledInput/LabeledInput.style.tsx index 382db8ee..3a69cdc8 100644 --- a/src/components/molecules/LabeledInput/LabeledInput.style.tsx +++ b/src/components/molecules/LabeledInput/LabeledInput.style.tsx @@ -3,10 +3,24 @@ import { styled } from 'styled-components'; import { calcInputPadding } from '@/components/molecules/LabeledInput/utils/calcInputPadding'; import { getTextColor } from '@/design/designFunctions/colorCalculatorForComponent'; import { TTheme } from '@/types/TTheme'; +import { globalElementsizes } from '@/design/theme/globalSizes'; -export const Wrapper = styled.div` +const handleHeight = ({ $hasLabel = false, $isTextArea = false }) => { + if (!$isTextArea) { + if ($hasLabel) { + return globalElementsizes.md; + } else { + return globalElementsizes.sm; + } + } + return ''; +}; +export const Wrapper = styled.div<{ $hasLabel?: boolean; $isTextArea?: boolean }>` position: relative; width: 100%; + display: flex; + align-items: center; + height: ${({ $hasLabel, $isTextArea }) => handleHeight({ $hasLabel, $isTextArea })}; `; type TInputWrapper = { @@ -18,11 +32,13 @@ export const InputWrapper = styled.div` color: ${({ theme }) => getTextColor({ theme, $themeType: 'secondary', $textLayer: 4 })}; border-radius: 3px; outline: none; + width: 100%; background-color: transparent; box-sizing: border-box; /* Added to include padding in the width */ input:not([type='range']), - select { + select, + textarea { ${({ $isActive, $isLabelProvided }) => calcInputPadding({ $isActive, $isLabelProvided })} } diff --git a/src/components/molecules/LabeledInput/LabeledInput.tsx b/src/components/molecules/LabeledInput/LabeledInput.tsx index db187d06..b4582568 100644 --- a/src/components/molecules/LabeledInput/LabeledInput.tsx +++ b/src/components/molecules/LabeledInput/LabeledInput.tsx @@ -14,6 +14,7 @@ export default function LabeledInput(props: TLabeledInput) { label, hasValue, hasPlaceholder, + isTextArea, themeType = 'primary', layer = 3, underline, @@ -23,7 +24,7 @@ export default function LabeledInput(props: TLabeledInput) { } = props; return ( - + {/* The Labled thats animated and adjusts the padding with the type of the Input */} {label && ( )} diff --git a/src/components/molecules/LabeledInput/TLabledInput.model.ts b/src/components/molecules/LabeledInput/TLabledInput.model.ts index eadd3c89..eba9934b 100644 --- a/src/components/molecules/LabeledInput/TLabledInput.model.ts +++ b/src/components/molecules/LabeledInput/TLabledInput.model.ts @@ -1,5 +1,3 @@ -import { ReactElement } from 'react'; - import { TLayer } from '@/types/TLayer'; import { TTextAlignLC } from '@/types/TTextAlignLC'; import { TUiColorsMain } from '@/types/TUiColorsMain'; @@ -9,11 +7,12 @@ export type TLabeledInput = { id?: string; label?: string; hasPlaceholder?: boolean; - inputElement?: ReactElement; + inputElement?: React.ReactNode; systemMessageType?: TUiColorsSystemMessage; hasValue?: boolean; themeType?: Exclude; layer?: TLayer; + isTextArea?: boolean; underline?: boolean; isActive?: boolean; align?: TTextAlignLC; diff --git a/src/components/molecules/LabeledInput/utils/calcInputPadding.ts b/src/components/molecules/LabeledInput/utils/calcInputPadding.ts index d033ea53..956a8765 100644 --- a/src/components/molecules/LabeledInput/utils/calcInputPadding.ts +++ b/src/components/molecules/LabeledInput/utils/calcInputPadding.ts @@ -6,27 +6,31 @@ type TCalcInputPadding = { }; export function calcInputPadding(props: TCalcInputPadding) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { $isActive, $isLabelProvided } = props; if ($isLabelProvided) { - if ($isActive) { - return css` - padding: 16px 0 4px 0px; //if the input is active and the type is transparent - `; - } else { - return css` - padding: 12px 0 8px 0px; //if the input is not active and the type is transparent - `; - } + return css` + margin-top: 16px; + padding: 0 0 8px 0px; //if the input is not active and the type is transparent + `; + // old spacings remove when its not needed anymore + // if ($isActive) { + // return css` + // margin-top: 16px; + // padding: 0 0 4px 0px; //if the input is active and the type is transparent + // `; + // } else { + // return css` + // margin-top: 12px; + // padding: 0 0 8px 0px; //if the input is not active and the type is transparent + // `; + // } } else { - if ($isActive) { - return css` - padding: 2px 0 2px 0px; //if the input is active and the type is transparent - `; - } else { - return css` - padding: 2px 0 2px 0px; //if the input is not active and the type is transparent - `; - } + return css` + // old spacings remove when its not needed anymore + margin-top: 2px; + padding: 0 0 2px 0px; //if the input is not active and the type is transparent + `; } } diff --git a/src/components/organisms/FancyTextArea/FancyTextArea.model.ts b/src/components/organisms/FancyTextArea/FancyTextArea.model.ts new file mode 100644 index 00000000..56a90ccd --- /dev/null +++ b/src/components/organisms/FancyTextArea/FancyTextArea.model.ts @@ -0,0 +1,4 @@ +import { TRawTextAreaWithHTMLAttrs } from '@/components/atoms/RawTextArea/RawTextArea'; +import { TInputWrapperUserInputProps } from '@/components/molecules/InputWrapper'; + +export type TFancyTextArea = Omit & TRawTextAreaWithHTMLAttrs; diff --git a/src/components/organisms/FancyTextArea/FancyTextArea.tsx b/src/components/organisms/FancyTextArea/FancyTextArea.tsx new file mode 100644 index 00000000..6813b237 --- /dev/null +++ b/src/components/organisms/FancyTextArea/FancyTextArea.tsx @@ -0,0 +1,81 @@ +import { forwardRef, useId, useState } from 'react'; +import RawTextArea from '@/components/atoms/RawTextArea/RawTextArea'; +import { InputWrapper } from '@/components/molecules/InputWrapper'; +import { TFancyTextArea } from '@/components/organisms/FancyTextArea/FancyTextArea.model'; + +// --------------------------------------------------------------------------- // +// ---------- A FancyTextArea with a Background underline and Icon ---------- // +// --------------------------------------------------------------------------- // +const FancyTextArea = forwardRef((props, ref) => { + const { + id, + value, + themeType = 'primary', + layer = 2, + placeholder, + systemMessage, + disabled, + align, + icon, + label, + onFocus, + underline, + onBlur, + outlined, + outlinedBackgroundStrength, + outlinedRemoveBorder, + transparentBackground, + className, + ...inputProps + } = props; + + //the states activity of the input + const [isActive, setIsActive] = useState(false); + + // if no id is provided, generate a random one + const useid = useId(); + const usedId = id ? id : useid; + + return ( + { + onFocus && onFocus(e); + setIsActive(true); + }} + onBlur={(e) => { + onBlur && onBlur(e); + setIsActive(false); + }} + placeholder={placeholder} + {...inputProps} + /> + } + /> + ); +}); + +export default FancyTextArea; diff --git a/src/components/organisms/FancyTextArea/docu/FancyTextArea.mdx b/src/components/organisms/FancyTextArea/docu/FancyTextArea.mdx new file mode 100644 index 00000000..5092b5e0 --- /dev/null +++ b/src/components/organisms/FancyTextArea/docu/FancyTextArea.mdx @@ -0,0 +1,53 @@ +import { Meta, Title, Description, Canvas, Controls } from '@storybook/blocks'; + +import * as FancyTextAreaStories from './FancyTextArea.stories'; + + + + + +<Description /> + +## Setup Instructions + +To use the `FancyTextArea` component: + +1. **Import the Component:** + + ```jsx + import FancyTextArea from 'fui-fancyui'; + ``` + + (or wherever your component is located) + +2. **(Optional) Import Type Definitions (TypeScript):** + ```typescript + import { TFancyTextArea } from 'fui-fancyui'; + ``` + +## Example Usage + +```jsx +<FancyTextArea + id="description-input" + label="Description" + placeholder="Enter a detailed description..." + value={descriptionText} + onChange={handleDescriptionChange} + themeType="secondary" + layer={3} + systemMessage={validationError ? 'error' : ''} + icon={<InfoIcon />} +/> +``` + +<Canvas /> + +## Component Properties + +<Controls /> + +## List of Used Components + +- **RawTextArea:** The foundational text area component. +- **InputWrapper:** Provides structure and styling for the text area, including labels and system messages. diff --git a/src/components/organisms/FancyTextArea/docu/FancyTextArea.stories.tsx b/src/components/organisms/FancyTextArea/docu/FancyTextArea.stories.tsx new file mode 100644 index 00000000..5b7794bb --- /dev/null +++ b/src/components/organisms/FancyTextArea/docu/FancyTextArea.stories.tsx @@ -0,0 +1,172 @@ +// Import necessary dependencies +import { Meta, StoryObj } from '@storybook/react'; + +// Import the component to be tested +import FancyTextArea from '../FancyTextArea'; + +import SVGCheckMark from '../../../icons/SVGCheckMark/SVGCheckMark'; +import templateThemeType from '@/stories/templateSettingsForStorys/templatesForThemeType'; +import { useState } from 'react'; + +// Define metadata for the story +const meta = { + component: FancyTextArea, + title: 'components/organisms/FancyTextArea', + parameters: { + docs: { + description: { + component: + 'The `FancyTextArea` component is an enhanced text area input field with customizable styling, icons, and integrated state management. It builds upon the basic `RawTextArea` component by adding features such as labels, placeholders, system messages (for errors, success, or info), and visual themes.', + }, + }, + }, + // Define arguments for the story + argTypes: { + label: { + description: 'Label for the input', + control: { + type: 'text', + }, + }, + align: { + description: 'Alignment of the label', + control: { + type: 'select', + }, + }, + disabled: { + description: 'Disable the input', + control: { + type: 'boolean', + }, + }, + ...templateThemeType('mainThemeTypes', 'primary', 2), + systemMessage: { + description: 'Error message to be displayed', + control: { + type: 'object', + }, + }, + placeholder: { + description: 'Placeholder for the input', + control: { + type: 'text', + }, + }, + icon: { + description: 'Icon for the input', + control: { + type: 'object', + }, + }, + value: { + description: 'Value of the input', + control: { + type: 'text', + }, + }, + transparentBackground: { + description: 'The input has a transparent background', + control: { + type: 'boolean', + }, + }, + externalStyle: { + description: 'External style for the input', + control: { + type: 'object', + }, + }, + labelVariant: { + description: 'Variant of the label', + control: { + type: 'select', + }, + }, + outlined: { + description: 'Outlined input', + control: { + type: 'boolean', + }, + }, + outlinedBackgroundStrength: { + description: 'Background strength of the outlined input', + control: { + min: 0, + max: 1, + step: 0.1, + type: 'number', + }, + }, + underline: { + description: 'Underline the input', + control: { + type: 'boolean', + }, + }, + }, +} satisfies Meta<typeof FancyTextArea>; + +// Export the metadata +export default meta; +// Define the story object +type Story = StoryObj<typeof meta>; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const SateFunction = (args: any) => { + const [value, setValue] = useState(''); + + const handleStateChange = (e: React.ChangeEvent<HTMLInputElement>) => { + setValue(e.target.value); + }; + + return <FancyTextArea value={value} onChange={handleStateChange} {...args} />; +}; + +// Define the primary story +export const Primary: Story = { + render: (args) => <SateFunction {...args} />, + args: { + layer: 2, + themeType: 'primary', + align: 'left', + label: 'Label', + icon: <SVGCheckMark />, + }, +}; + +export const WithErrorState: Story = { + render: (args) => <SateFunction {...args} />, + args: { + layer: 2, + themeType: 'primary', + align: 'left', + label: 'Label', + icon: <SVGCheckMark />, + systemMessage: 'error', + }, +}; + +export const WithSuccessState: Story = { + render: (args) => <SateFunction {...args} />, + args: { + layer: 2, + themeType: 'primary', + align: 'left', + label: 'Label', + icon: <SVGCheckMark />, + systemMessage: 'success', + }, +}; + +export const WithInfoState: Story = { + render: (args) => <SateFunction {...args} />, + args: { + layer: 2, + themeType: 'primary', + align: 'left', + label: 'Label', + icon: <SVGCheckMark />, + systemMessage: 'info', + }, +}; diff --git a/src/components/organisms/FancyTextArea/index.ts b/src/components/organisms/FancyTextArea/index.ts new file mode 100644 index 00000000..32f98d10 --- /dev/null +++ b/src/components/organisms/FancyTextArea/index.ts @@ -0,0 +1,3 @@ +export { default as FancyTextArea } from './FancyTextArea'; + +export type { TFancyTextArea } from './FancyTextArea.model'; diff --git a/src/components/organisms/FancyTextInput/FancyTextInput.tsx b/src/components/organisms/FancyTextInput/FancyTextInput.tsx index b69357af..b6a1f79e 100644 --- a/src/components/organisms/FancyTextInput/FancyTextInput.tsx +++ b/src/components/organisms/FancyTextInput/FancyTextInput.tsx @@ -7,7 +7,7 @@ import { TFancyTextInput } from '@/components/organisms/FancyTextInput/TFancyTex // --------------------------------------------------------------------------- // // ----The TextInput Comonent with surrounding icon, label and underline ----- // // --------------------------------------------------------------------------- // -const FancyTextInpUtWithForWardRef = forwardRef<HTMLInputElement, TFancyTextInput>((props, ref) => { +const FancyTextInput = forwardRef<HTMLInputElement, TFancyTextInput>((props, ref) => { const { id, value, @@ -81,4 +81,4 @@ const FancyTextInpUtWithForWardRef = forwardRef<HTMLInputElement, TFancyTextInpu ); }); -export default FancyTextInpUtWithForWardRef; +export default FancyTextInput;