[refacto] Introduce stateless TextInputV2 (#5013)
## Context As discussed with @lucasbordeau and @charlesBochet we are looking at making low level UI components stateless when possible. Therefore TextInput should not handle a hotkey state. Instead hotkeys should be defined in the parent component (as done here in CreateProfile). Introducing here TextInputV2 that is stateless and that can already replace TextInput without any behaviour change everywhere it is used with `disableHotkey` prop. ## How was it tested? Locally + Storybook --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -1,8 +1,9 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { Controller, SubmitHandler, useForm } from 'react-hook-form';
|
||||
import styled from '@emotion/styled';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { SubTitle } from '@/auth/components/SubTitle';
|
||||
@ -13,10 +14,12 @@ import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePictureUploader';
|
||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||
import { H2Title } from '@/ui/display/typography/components/H2Title';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { MainButton } from '@/ui/input/button/components/MainButton';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||
|
||||
const StyledContentContainer = styled.div`
|
||||
@ -123,17 +126,22 @@ export const CreateProfile = () => {
|
||||
],
|
||||
);
|
||||
|
||||
const [isEditingMode, setIsEditingMode] = useState(false);
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.Enter,
|
||||
() => {
|
||||
if (isEditingMode) {
|
||||
onSubmit(getValues());
|
||||
}
|
||||
},
|
||||
PageHotkeyScope.CreateProfile,
|
||||
);
|
||||
|
||||
if (onboardingStatus !== OnboardingStatus.OngoingProfileCreation) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const onNameInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
onSubmit(getValues());
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title withMarginTop={false}>Create profile</Title>
|
||||
@ -157,17 +165,19 @@ export const CreateProfile = () => {
|
||||
field: { onChange, onBlur, value },
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<TextInput
|
||||
<TextInputV2
|
||||
autoFocus
|
||||
label="First Name"
|
||||
value={value}
|
||||
onBlur={onBlur}
|
||||
onFocus={() => setIsEditingMode(true)}
|
||||
onBlur={() => {
|
||||
onBlur();
|
||||
setIsEditingMode(false);
|
||||
}}
|
||||
onChange={onChange}
|
||||
placeholder="Tim"
|
||||
error={error?.message}
|
||||
fullWidth
|
||||
onKeyDown={onNameInputKeyDown}
|
||||
disableHotkeys
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
@ -178,16 +188,18 @@ export const CreateProfile = () => {
|
||||
field: { onChange, onBlur, value },
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<TextInput
|
||||
<TextInputV2
|
||||
label="Last Name"
|
||||
value={value}
|
||||
onBlur={onBlur}
|
||||
onFocus={() => setIsEditingMode(true)}
|
||||
onBlur={() => {
|
||||
onBlur();
|
||||
setIsEditingMode(false);
|
||||
}}
|
||||
onChange={onChange}
|
||||
placeholder="Cook"
|
||||
error={error?.message}
|
||||
fullWidth
|
||||
onKeyDown={onNameInputKeyDown}
|
||||
disableHotkeys
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@ -20,7 +20,7 @@ import { H2Title } from '@/ui/display/typography/components/H2Title';
|
||||
import { Loader } from '@/ui/feedback/loader/components/Loader.tsx';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { MainButton } from '@/ui/input/button/components/MainButton';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||
import { useActivateWorkspaceMutation } from '~/generated/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
@ -141,7 +141,7 @@ export const CreateWorkspace = () => {
|
||||
field: { onChange, onBlur, value },
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<TextInput
|
||||
<TextInputV2
|
||||
autoFocus
|
||||
value={value}
|
||||
placeholder="Apple"
|
||||
@ -150,7 +150,6 @@ export const CreateWorkspace = () => {
|
||||
error={error?.message}
|
||||
onKeyDown={handleKeyDown}
|
||||
fullWidth
|
||||
disableHotkeys
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@ -18,7 +18,7 @@ import { PASSWORD_REGEX } from '@/auth/utils/passwordRegex';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { MainButton } from '@/ui/input/button/components/MainButton';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { TextInputV2 } from '@/ui/input/components/TextInputV2';
|
||||
import { AnimatedEaseIn } from '@/ui/utilities/animation/components/AnimatedEaseIn';
|
||||
import {
|
||||
useUpdatePasswordViaResetTokenMutation,
|
||||
@ -191,12 +191,11 @@ export const PasswordReset = () => {
|
||||
}}
|
||||
>
|
||||
<StyledInputContainer>
|
||||
<TextInput
|
||||
<TextInputV2
|
||||
autoFocus
|
||||
value={email}
|
||||
placeholder="Email"
|
||||
fullWidth
|
||||
disableHotkeys
|
||||
disabled
|
||||
/>
|
||||
</StyledInputContainer>
|
||||
@ -218,7 +217,7 @@ export const PasswordReset = () => {
|
||||
fieldState: { error },
|
||||
}) => (
|
||||
<StyledInputContainer>
|
||||
<TextInput
|
||||
<TextInputV2
|
||||
autoFocus
|
||||
value={value}
|
||||
type="password"
|
||||
@ -227,7 +226,6 @@ export const PasswordReset = () => {
|
||||
onChange={onChange}
|
||||
error={error?.message}
|
||||
fullWidth
|
||||
disableHotkeys
|
||||
/>
|
||||
</StyledInputContainer>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user