0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

refactor(console): remove redundant hasError prop from text input (#3672)

This commit is contained in:
Xiao Yijun 2023-04-10 11:20:49 +08:00 committed by GitHub
parent 764d0dd5ac
commit 4220f554db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 38 additions and 64 deletions

View file

@ -71,9 +71,7 @@ function MultiTextInput({
> >
<div className={styles.deletableInput}> <div className={styles.deletableInput}>
<TextInput <TextInput
hasError={Boolean( error={Boolean(error?.inputs?.[fieldIndex] ?? (fieldIndex === 0 && error?.required))}
error?.inputs?.[fieldIndex] ?? (fieldIndex === 0 && error?.required)
)}
value={fieldValue} value={fieldValue}
placeholder={placeholder} placeholder={placeholder}
onChange={({ currentTarget: { value } }) => { onChange={({ currentTarget: { value } }) => {

View file

@ -14,24 +14,13 @@ import {
import * as styles from './index.module.scss'; import * as styles from './index.module.scss';
type Props = Omit<HTMLProps<HTMLInputElement>, 'size'> & { type Props = Omit<HTMLProps<HTMLInputElement>, 'size'> & {
hasError?: boolean; error?: string | boolean;
errorMessage?: string;
icon?: ReactElement; icon?: ReactElement;
suffix?: ReactElement; suffix?: ReactElement;
}; };
function TextInput( function TextInput(
{ { error, icon, suffix, disabled, className, readOnly, type = 'text', ...rest }: Props,
errorMessage,
hasError = Boolean(errorMessage),
icon,
suffix,
disabled,
className,
readOnly,
type = 'text',
...rest
}: Props,
reference: Ref<Nullable<HTMLInputElement>> reference: Ref<Nullable<HTMLInputElement>>
) { ) {
const innerRef = useRef<HTMLInputElement>(null); const innerRef = useRef<HTMLInputElement>(null);
@ -64,7 +53,7 @@ function TextInput(
<div <div
className={classNames( className={classNames(
styles.container, styles.container,
hasError && styles.error, error && styles.error,
icon && styles.withIcon, icon && styles.withIcon,
disabled && styles.disabled, disabled && styles.disabled,
readOnly && styles.readOnly readOnly && styles.readOnly
@ -77,7 +66,9 @@ function TextInput(
className: classNames([suffix.props.className, styles.suffix]), className: classNames([suffix.props.className, styles.suffix]),
})} })}
</div> </div>
{hasError && errorMessage && <div className={styles.errorMessage}>{errorMessage}</div>} {Boolean(error) && typeof error === 'string' && (
<div className={styles.errorMessage}>{error}</div>
)}
</div> </div>
); );
} }

View file

@ -99,7 +99,7 @@ function UriInputField({ appId, name, title, isSingle = false }: Props) {
<TextInput <TextInput
className={styles.field} className={styles.field}
value={value[0]} value={value[0]}
errorMessage={errorObject?.required ?? errorObject?.inputs?.[0]} error={errorObject?.required ?? errorObject?.inputs?.[0]}
onChange={({ currentTarget: { value } }) => { onChange={({ currentTarget: { value } }) => {
onChange([value]); onChange([value]);
}} }}

View file

@ -137,8 +137,7 @@ function SignInExperience() {
validate: (value) => validate: (value) =>
!value || uriValidator(value) || t('errors.invalid_uri_format'), !value || uriValidator(value) || t('errors.invalid_uri_format'),
})} })}
hasError={Boolean(errors.logo)} error={errors.logo?.message}
errorMessage={errors.logo?.message}
/> />
)} )}
</FormField> </FormField>

View file

@ -79,15 +79,14 @@ function CreatePermissionModal({ resourceId, onClose }: Props) {
message: t('api_resource_details.permission.forbidden_space_in_name'), message: t('api_resource_details.permission.forbidden_space_in_name'),
}, },
})} })}
hasError={Boolean(errors.name)} error={errors.name?.message}
errorMessage={errors.name?.message}
/> />
</FormField> </FormField>
<FormField isRequired title="api_resource_details.permission.description"> <FormField isRequired title="api_resource_details.permission.description">
<TextInput <TextInput
placeholder={t('api_resource_details.permission.description_placeholder')} placeholder={t('api_resource_details.permission.description_placeholder')}
{...register('description', { required: true })} {...register('description', { required: true })}
hasError={Boolean(errors.description)} error={Boolean(errors.description)}
/> />
</FormField> </FormField>
</form> </form>

View file

@ -61,7 +61,7 @@ function ApiResourceSettings() {
<FormField isRequired title="api_resources.api_name"> <FormField isRequired title="api_resources.api_name">
<TextInput <TextInput
{...register('name', { required: true })} {...register('name', { required: true })}
hasError={Boolean(errors.name)} error={Boolean(errors.name)}
readOnly={isLogtoManagementApiResource} readOnly={isLogtoManagementApiResource}
placeholder={t('api_resources.api_name_placeholder')} placeholder={t('api_resources.api_name_placeholder')}
/> />
@ -73,7 +73,7 @@ function ApiResourceSettings() {
valueAsNumber: true, valueAsNumber: true,
})} })}
type="number" type="number"
hasError={Boolean(errors.accessTokenTtl)} error={Boolean(errors.accessTokenTtl)}
placeholder={t('api_resource_details.token_expiration_time_in_seconds_placeholder')} placeholder={t('api_resource_details.token_expiration_time_in_seconds_placeholder')}
/> />
</FormField> </FormField>

View file

@ -48,7 +48,7 @@ function Settings({ data }: Props) {
<FormField isRequired title="application_details.application_name"> <FormField isRequired title="application_details.application_name">
<TextInput <TextInput
{...register('name', { required: true })} {...register('name', { required: true })}
hasError={Boolean(errors.name)} error={Boolean(errors.name)}
placeholder={t('application_details.application_name_placeholder')} placeholder={t('application_details.application_name_placeholder')}
/> />
</FormField> </FormField>

View file

@ -118,7 +118,7 @@ function CreateForm({ isOpen, onClose }: Props) {
<TextInput <TextInput
{...register('name', { required: true })} {...register('name', { required: true })}
placeholder={t('applications.application_name_placeholder')} placeholder={t('applications.application_name_placeholder')}
hasError={Boolean(errors.name)} error={Boolean(errors.name)}
/> />
</FormField> </FormField>
<FormField title="applications.application_description"> <FormField title="applications.application_description">

View file

@ -77,7 +77,7 @@ function SenderTester({ connectorFactoryId, connectorType, className, parse }: P
className={styles.textField} className={styles.textField}
> >
<TextInput <TextInput
hasError={Boolean(inputError)} error={Boolean(inputError)}
type={isSms ? 'tel' : 'email'} type={isSms ? 'tel' : 'email'}
placeholder={ placeholder={
isSms isSms

View file

@ -125,7 +125,7 @@ function ConfigForm({ formItems }: Props) {
// This will happen when connector's version is ahead of AC // This will happen when connector's version is ahead of AC
return ( return (
<TextInput <TextInput
hasError={hasError} error={hasError}
value={typeof value === 'string' ? value : ''} value={typeof value === 'string' ? value : ''}
onChange={onChange} onChange={onChange}
/> />

View file

@ -69,15 +69,14 @@ function BasicForm({
<FormField isRequired title="connectors.guide.name" tip={t('connectors.guide.name_tip')}> <FormField isRequired title="connectors.guide.name" tip={t('connectors.guide.name_tip')}>
<TextInput <TextInput
placeholder={t('connectors.guide.name_placeholder')} placeholder={t('connectors.guide.name_placeholder')}
hasError={Boolean(errors.name)} error={Boolean(errors.name)}
{...register('name', { required: true })} {...register('name', { required: true })}
/> />
</FormField> </FormField>
<FormField title="connectors.guide.logo" tip={t('connectors.guide.logo_tip')}> <FormField title="connectors.guide.logo" tip={t('connectors.guide.logo_tip')}>
<TextInput <TextInput
placeholder={t('connectors.guide.logo_placeholder')} placeholder={t('connectors.guide.logo_placeholder')}
hasError={Boolean(errors.logo)} error={errors.logo?.message}
errorMessage={errors.logo?.message}
{...register('logo', { {...register('logo', {
validate: (value) => validate: (value) =>
!value || uriValidator(value) || t('errors.invalid_uri_format'), !value || uriValidator(value) || t('errors.invalid_uri_format'),
@ -88,8 +87,7 @@ function BasicForm({
<FormField title="connectors.guide.logo_dark" tip={t('connectors.guide.logo_dark_tip')}> <FormField title="connectors.guide.logo_dark" tip={t('connectors.guide.logo_dark_tip')}>
<TextInput <TextInput
placeholder={t('connectors.guide.logo_dark_placeholder')} placeholder={t('connectors.guide.logo_dark_placeholder')}
hasError={Boolean(errors.logoDark)} error={errors.logoDark?.message}
errorMessage={errors.logoDark?.message}
{...register('logoDark', { {...register('logoDark', {
validate: (value) => validate: (value) =>
!value || uriValidator(value) || t('errors.invalid_uri_format'), !value || uriValidator(value) || t('errors.invalid_uri_format'),
@ -129,7 +127,7 @@ function BasicForm({
> >
<TextInput <TextInput
placeholder={t('connectors.guide.target_placeholder')} placeholder={t('connectors.guide.target_placeholder')}
hasError={Boolean(errors.target)} error={Boolean(errors.target)}
disabled={!isAllowEditTarget} disabled={!isAllowEditTarget}
{...register('target', { required: true })} {...register('target', { required: true })}
/> />

View file

@ -144,7 +144,7 @@ function BasicUserInfoUpdateModal({ field, value: initialValue, isOpen, onClose
// eslint-disable-next-line jsx-a11y/no-autofocus // eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus autoFocus
placeholder={getInputPlaceholder()} placeholder={getInputPlaceholder()}
errorMessage={errors[field]?.message} error={errors[field]?.message}
onKeyDown={(event) => { onKeyDown={(event) => {
if (event.key === 'Enter') { if (event.key === 'Enter') {
void onSubmit(); void onSubmit();

View file

@ -106,7 +106,7 @@ function ChangePasswordModal() {
// eslint-disable-next-line jsx-a11y/no-autofocus // eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus autoFocus
type={showPassword ? 'text' : 'password'} type={showPassword ? 'text' : 'password'}
errorMessage={errors.newPassword?.message} error={errors.newPassword?.message}
suffix={ suffix={
<IconButton <IconButton
onMouseDown={(event) => { onMouseDown={(event) => {
@ -125,7 +125,7 @@ function ChangePasswordModal() {
validate: (value) => value === watch('newPassword') || t('profile.password.do_not_match'), validate: (value) => value === watch('newPassword') || t('profile.password.do_not_match'),
})} })}
type={showPassword ? 'text' : 'password'} type={showPassword ? 'text' : 'password'}
errorMessage={errors.confirmPassword?.message} error={errors.confirmPassword?.message}
suffix={ suffix={
<IconButton <IconButton
onMouseDown={(event) => { onMouseDown={(event) => {

View file

@ -63,7 +63,7 @@ function LinkEmailModal() {
})} })}
// eslint-disable-next-line jsx-a11y/no-autofocus // eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus autoFocus
errorMessage={errors.email?.message} error={errors.email?.message}
onKeyDown={(event) => { onKeyDown={(event) => {
if (event.key === 'Enter') { if (event.key === 'Enter') {
onSubmit(); onSubmit();

View file

@ -79,7 +79,7 @@ function VerifyPasswordModal() {
{...register('password', { required: t('profile.password.required') })} {...register('password', { required: t('profile.password.required') })}
// eslint-disable-next-line jsx-a11y/no-autofocus // eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus autoFocus
errorMessage={errors.password?.message} error={errors.password?.message}
type={showPassword ? 'text' : 'password'} type={showPassword ? 'text' : 'password'}
suffix={ suffix={
<IconButton <IconButton

View file

@ -52,12 +52,12 @@ function RoleSettings() {
learnMoreLink="https://docs.logto.io/docs/recipes/rbac/manage-permissions-and-roles#manage-roles" learnMoreLink="https://docs.logto.io/docs/recipes/rbac/manage-permissions-and-roles#manage-roles"
> >
<FormField isRequired title="role_details.field_name"> <FormField isRequired title="role_details.field_name">
<TextInput {...register('name', { required: true })} hasError={Boolean(errors.name)} /> <TextInput {...register('name', { required: true })} error={Boolean(errors.name)} />
</FormField> </FormField>
<FormField isRequired title="role_details.field_description"> <FormField isRequired title="role_details.field_description">
<TextInput <TextInput
{...register('description', { required: true })} {...register('description', { required: true })}
hasError={Boolean(errors.description)} error={Boolean(errors.description)}
/> />
</FormField> </FormField>
</FormCard> </FormCard>

View file

@ -83,14 +83,14 @@ function CreateRoleForm({ onClose }: Props) {
: true, : true,
})} })}
placeholder={t('roles.role_name_placeholder')} placeholder={t('roles.role_name_placeholder')}
errorMessage={errors.name?.message} error={errors.name?.message}
/> />
</FormField> </FormField>
<FormField isRequired title="roles.role_description"> <FormField isRequired title="roles.role_description">
<TextInput <TextInput
{...register('description', { required: true })} {...register('description', { required: true })}
placeholder={t('roles.role_description_placeholder')} placeholder={t('roles.role_description_placeholder')}
hasError={Boolean(errors.description)} error={Boolean(errors.description)}
/> />
</FormField> </FormField>
<FormField title="roles.assign_permissions"> <FormField title="roles.assign_permissions">

View file

@ -86,8 +86,7 @@ function BrandingForm() {
validate: (value) => validate: (value) =>
!value || uriValidator(value) || t('errors.invalid_uri_format'), !value || uriValidator(value) || t('errors.invalid_uri_format'),
})} })}
hasError={Boolean(errors.branding?.logoUrl)} error={errors.branding?.logoUrl?.message}
errorMessage={errors.branding?.logoUrl?.message}
placeholder={t('sign_in_exp.branding.logo_image_url_placeholder')} placeholder={t('sign_in_exp.branding.logo_image_url_placeholder')}
/> />
</FormField> </FormField>
@ -97,8 +96,7 @@ function BrandingForm() {
validate: (value) => validate: (value) =>
!value || uriValidator(value) || t('errors.invalid_uri_format'), !value || uriValidator(value) || t('errors.invalid_uri_format'),
})} })}
hasError={Boolean(errors.branding?.favicon)} error={errors.branding?.favicon?.message}
errorMessage={errors.branding?.favicon?.message}
placeholder={t('sign_in_exp.branding.favicon')} placeholder={t('sign_in_exp.branding.favicon')}
/> />
</FormField> </FormField>
@ -157,8 +155,7 @@ function BrandingForm() {
validate: (value) => validate: (value) =>
!value || uriValidator(value) || t('errors.invalid_uri_format'), !value || uriValidator(value) || t('errors.invalid_uri_format'),
})} })}
hasError={Boolean(errors.branding?.darkLogoUrl)} error={errors.branding?.darkLogoUrl?.message}
errorMessage={errors.branding?.darkLogoUrl?.message}
placeholder={t('sign_in_exp.branding.dark_logo_image_url_placeholder')} placeholder={t('sign_in_exp.branding.dark_logo_image_url_placeholder')}
/> />
</FormField> </FormField>

View file

@ -24,8 +24,7 @@ function TermsForm() {
{...register('termsOfUseUrl', { {...register('termsOfUseUrl', {
validate: (value) => !value || uriValidator(value) || t('errors.invalid_uri_format'), validate: (value) => !value || uriValidator(value) || t('errors.invalid_uri_format'),
})} })}
hasError={Boolean(errors.termsOfUseUrl)} error={errors.termsOfUseUrl?.message}
errorMessage={errors.termsOfUseUrl?.message}
placeholder={t('sign_in_exp.others.terms_of_use.terms_of_use_placeholder')} placeholder={t('sign_in_exp.others.terms_of_use.terms_of_use_placeholder')}
/> />
</FormField> </FormField>
@ -34,8 +33,7 @@ function TermsForm() {
{...register('privacyPolicyUrl', { {...register('privacyPolicyUrl', {
validate: (value) => !value || uriValidator(value) || t('errors.invalid_uri_format'), validate: (value) => !value || uriValidator(value) || t('errors.invalid_uri_format'),
})} })}
hasError={Boolean(errors.termsOfUseUrl)} error={errors.termsOfUseUrl?.message}
errorMessage={errors.termsOfUseUrl?.message}
placeholder={t('sign_in_exp.others.terms_of_use.privacy_policy_placeholder')} placeholder={t('sign_in_exp.others.terms_of_use.privacy_policy_placeholder')}
/> />
</FormField> </FormField>

View file

@ -116,8 +116,7 @@ function UserSettings() {
validate: (value) => validate: (value) =>
!value || uriValidator(value) || t('errors.invalid_uri_format'), !value || uriValidator(value) || t('errors.invalid_uri_format'),
})} })}
hasError={Boolean(errors.avatar)} error={errors.avatar?.message}
errorMessage={errors.avatar?.message}
placeholder={t('user_details.field_avatar_placeholder')} placeholder={t('user_details.field_avatar_placeholder')}
/> />
</FormField> </FormField>

View file

@ -109,16 +109,11 @@ function CreateForm({ onClose, onCreate }: Props) {
message: t('errors.username_pattern_error'), message: t('errors.username_pattern_error'),
}, },
})} })}
hasError={Boolean(errors.username)} error={errors.username?.message}
errorMessage={errors.username?.message}
/> />
</FormField> </FormField>
<FormField title="users.create_form_name"> <FormField title="users.create_form_name">
<TextInput <TextInput {...register('name')} error={errors.name?.message} />
{...register('name')}
hasError={Boolean(errors.name)}
errorMessage={errors.name?.message}
/>
</FormField> </FormField>
</form> </form>
</ModalLayout> </ModalLayout>