Skip to content

Commit 4014b12

Browse files
committed
added isDirty flag
1 parent 0063311 commit 4014b12

File tree

6 files changed

+68
-25
lines changed

6 files changed

+68
-25
lines changed

packages/components/src/formControls/InputText/InputText.stories.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ const meta: Meta<typeof FormControlInputTextStateful> = {
1919
value: {
2020
control: 'text',
2121
},
22+
onChange: {
23+
control: false,
24+
},
25+
onValidate: {
26+
control: false,
27+
},
28+
input: {
29+
control: false,
30+
},
2231
},
2332
args: {
2433
id: 'default-input',
@@ -79,4 +88,4 @@ export const Number: Story = {
7988
type: 'number',
8089
},
8190
},
82-
};
91+
};

packages/components/src/formControls/InputText/InputText.test.stories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,4 @@ export const Required: Story = {
8383
await expect(input).toHaveAttribute('aria-invalid', 'true');
8484
});
8585
},
86-
};
86+
};

packages/components/src/formControls/InputText/InputText.tsx

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
import React, { useContext, useEffect, useMemo } from 'react';
1+
import React, { useEffect } from 'react';
22

3+
import { useInitValidators, useValidateInput } from './InputText.utils';
34
import BaseFormControl from '@ids-internal/partials/BaseFormControl';
45
import InputText from '../../inputs/InputText';
5-
import IsEmptyStringValidator from '@ibexa/ids-core/validators/IsEmptyStringValidator';
6-
import { TranslatorContext } from '@ids-context/Translator';
7-
import { validateInput } from '@ids-internal/shared/validators';
86
import withStateValue from '@ids-internal/hoc/withStateValue';
97

10-
import { FormControlInputTextProps } from './InputText.types';
11-
import { ValidationResult } from '@ibexa/ids-core/types/validation';
8+
import { FormControlInputTextProps, ValueType } from './InputText.types';
129

1310
const FormControlInputText = ({
1411
helperText,
@@ -22,21 +19,9 @@ const FormControlInputText = ({
2219
onValidate = () => undefined,
2320
value = '',
2421
}: FormControlInputTextProps) => {
25-
const translator = useContext(TranslatorContext);
2622
const required = input.required ?? false;
27-
const validators = useMemo(() => {
28-
const validatorsList = [];
29-
30-
if (required) {
31-
validatorsList.push(new IsEmptyStringValidator(translator));
32-
}
33-
34-
return validatorsList;
35-
}, [required, translator]);
36-
const { isValid, messages } = useMemo<ValidationResult>(
37-
() => validateInput<string | number>(value, validators),
38-
[value, validators],
39-
);
23+
const validators = useInitValidators({ required });
24+
const { isValid, messages } = useValidateInput({ validators, value });
4025
const helperTextProps = {
4126
children: isValid ? helperText : messages.join(', '),
4227
type: isValid ? ('default' as const) : ('error' as const),
@@ -71,4 +56,4 @@ const FormControlInputText = ({
7156

7257
export default FormControlInputText;
7358

74-
export const FormControlInputTextStateful = withStateValue<string | number>(FormControlInputText);
59+
export const FormControlInputTextStateful = withStateValue<ValueType>(FormControlInputText);

packages/components/src/formControls/InputText/InputText.types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,8 @@ export interface FormControlInputTextProps extends BaseComponentAttributes {
1515
onChange?: BasicInputTextProps['onChange'];
1616
onValidate?: (isValid: boolean, messages: string[]) => void;
1717
value?: BasicInputTextProps['value'];
18-
}
18+
}
19+
20+
export type OnChangeArgsType = Parameters<NonNullable<FormControlInputTextProps['onChange']>>;
21+
22+
export type ValueType = NonNullable<FormControlInputTextProps['value']>;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
2+
3+
import BaseValidator from '@ibexa/ids-core/validators/BaseValidator';
4+
import IsEmptyStringValidator from '@ibexa/ids-core/validators/IsEmptyStringValidator';
5+
import { TranslatorContext } from '@ids-context/Translator';
6+
import { ValidationResult } from '@ibexa/ids-core/types/validation';
7+
import { validateInput } from '@ids-internal/shared/validators';
8+
9+
import { ValueType } from './InputText.types';
10+
11+
export const useInitValidators = ({ required }: { required: boolean }) => {
12+
const translator = useContext(TranslatorContext);
13+
const validators = useMemo(() => {
14+
const validatorsList: BaseValidator<ValueType>[] = [];
15+
16+
if (required) {
17+
validatorsList.push(new IsEmptyStringValidator(translator));
18+
}
19+
20+
return validatorsList;
21+
}, [required, translator]);
22+
23+
return validators;
24+
};
25+
26+
export const useValidateInput = ({ validators, value }: { validators: BaseValidator<ValueType>[]; value: ValueType }): ValidationResult => {
27+
const initialValue = useRef(value);
28+
const [isDirty, setIsDirty] = useState(false);
29+
30+
useEffect(() => {
31+
if (initialValue.current !== value) {
32+
setIsDirty(true);
33+
}
34+
35+
initialValue.current = value;
36+
}, [value]);
37+
38+
return useMemo(() => {
39+
if (!isDirty) {
40+
return { isValid: true, messages: [] };
41+
}
42+
43+
return validateInput<ValueType>(value, validators);
44+
}, [initialValue.current, value, validators]);
45+
};

packages/components/src/formControls/InputText/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ import { FormControlInputTextProps } from './InputText.types';
33

44
export default FormControlInputText;
55
export { FormControlInputTextStateful };
6-
export type { FormControlInputTextProps };
6+
export type { FormControlInputTextProps };

0 commit comments

Comments
 (0)