@utilitywarehouse/hearth-react-native 0.32.0 → 0.32.1
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +12 -15
- package/CHANGELOG.md +8 -1
- package/build/components/Card/Card.props.d.ts +1 -1
- package/build/components/Card/CardRoot.js +19 -0
- package/build/components/Input/Input.js +13 -31
- package/build/components/StepperInput/StepperInput.js +12 -29
- package/build/components/Textarea/Textarea.js +12 -30
- package/build/components/VerificationInput/VerificationInput.js +12 -22
- package/build/hooks/index.d.ts +1 -0
- package/build/hooks/index.js +1 -0
- package/build/hooks/useFormFieldAccessibility.d.ts +17 -0
- package/build/hooks/useFormFieldAccessibility.js +32 -0
- package/build/hooks/useFormFieldAccessibility.test.d.ts +1 -0
- package/build/hooks/useFormFieldAccessibility.test.js +56 -0
- package/package.json +4 -2
- package/src/components/Banner/Banner.stories.tsx +14 -0
- package/src/components/Card/Card.docs.mdx +16 -17
- package/src/components/Card/Card.props.ts +1 -0
- package/src/components/Card/Card.stories.tsx +35 -21
- package/src/components/Card/CardRoot.tsx +19 -0
- package/src/components/Icon/Icon.docs.mdx +1 -1
- package/src/components/Input/Input.tsx +14 -35
- package/src/components/List/List.docs.mdx +4 -2
- package/src/components/StepperInput/StepperInput.tsx +13 -40
- package/src/components/Textarea/Textarea.tsx +13 -34
- package/src/components/VerificationInput/VerificationInput.tsx +13 -25
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useFormFieldAccessibility.test.tsx +74 -0
- package/src/hooks/useFormFieldAccessibility.ts +67 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import useFormFieldAccessibility from './useFormFieldAccessibility';
|
|
4
|
+
|
|
5
|
+
type HookArgs = Parameters<typeof useFormFieldAccessibility>[0];
|
|
6
|
+
|
|
7
|
+
const renderHook = (args: HookArgs) => {
|
|
8
|
+
let result: ReturnType<typeof useFormFieldAccessibility> | undefined;
|
|
9
|
+
|
|
10
|
+
const TestComponent = () => {
|
|
11
|
+
result = useFormFieldAccessibility(args);
|
|
12
|
+
return null;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
renderToStaticMarkup(<TestComponent />);
|
|
16
|
+
|
|
17
|
+
if (!result) {
|
|
18
|
+
throw new Error('Hook did not return a result');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe('useFormFieldAccessibility', () => {
|
|
25
|
+
it('builds a label from the field label and required state', () => {
|
|
26
|
+
expect(
|
|
27
|
+
renderHook({
|
|
28
|
+
label: 'Email',
|
|
29
|
+
required: true,
|
|
30
|
+
})
|
|
31
|
+
).toEqual({
|
|
32
|
+
accessibilityHint: undefined,
|
|
33
|
+
accessibilityLabel: 'Email, required',
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('builds a hint from helper text and validation feedback', () => {
|
|
38
|
+
expect(
|
|
39
|
+
renderHook({
|
|
40
|
+
helperText: 'Enter the code we sent you',
|
|
41
|
+
validationStatus: 'invalid',
|
|
42
|
+
invalidText: 'Code is invalid',
|
|
43
|
+
})
|
|
44
|
+
).toEqual({
|
|
45
|
+
accessibilityHint: 'Enter the code we sent you, Code is invalid',
|
|
46
|
+
accessibilityLabel: undefined,
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('falls back to provided accessibility props when no composed value exists', () => {
|
|
51
|
+
expect(
|
|
52
|
+
renderHook({
|
|
53
|
+
fallbackLabel: 'Custom label',
|
|
54
|
+
fallbackHint: 'Custom hint',
|
|
55
|
+
})
|
|
56
|
+
).toEqual({
|
|
57
|
+
accessibilityHint: 'Custom hint',
|
|
58
|
+
accessibilityLabel: 'Custom label',
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('supports omitting the required suffix from the label', () => {
|
|
63
|
+
expect(
|
|
64
|
+
renderHook({
|
|
65
|
+
label: 'Verification code',
|
|
66
|
+
required: true,
|
|
67
|
+
includeRequiredInLabel: false,
|
|
68
|
+
})
|
|
69
|
+
).toEqual({
|
|
70
|
+
accessibilityHint: undefined,
|
|
71
|
+
accessibilityLabel: 'Verification code',
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
type ValidationStatus = 'initial' | 'valid' | 'invalid';
|
|
4
|
+
|
|
5
|
+
type UseFormFieldAccessibilityArgs = {
|
|
6
|
+
label?: string;
|
|
7
|
+
helperText?: string;
|
|
8
|
+
validText?: string;
|
|
9
|
+
invalidText?: string;
|
|
10
|
+
required?: boolean;
|
|
11
|
+
validationStatus?: ValidationStatus;
|
|
12
|
+
fallbackLabel?: string;
|
|
13
|
+
fallbackHint?: string;
|
|
14
|
+
includeRequiredInLabel?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const useFormFieldAccessibility = ({
|
|
18
|
+
label,
|
|
19
|
+
helperText,
|
|
20
|
+
validText,
|
|
21
|
+
invalidText,
|
|
22
|
+
required = false,
|
|
23
|
+
validationStatus = 'initial',
|
|
24
|
+
fallbackLabel,
|
|
25
|
+
fallbackHint,
|
|
26
|
+
includeRequiredInLabel = true,
|
|
27
|
+
}: UseFormFieldAccessibilityArgs) => {
|
|
28
|
+
const accessibilityLabel = useMemo(() => {
|
|
29
|
+
const nextAccessibilityLabelParts: string[] = [];
|
|
30
|
+
|
|
31
|
+
if (label) {
|
|
32
|
+
nextAccessibilityLabelParts.push(label);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (includeRequiredInLabel && required) {
|
|
36
|
+
nextAccessibilityLabelParts.push('required');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const nextAccessibilityLabel = nextAccessibilityLabelParts.join(', ');
|
|
40
|
+
return nextAccessibilityLabel || fallbackLabel;
|
|
41
|
+
}, [fallbackLabel, includeRequiredInLabel, label, required]);
|
|
42
|
+
|
|
43
|
+
const accessibilityHint = useMemo(() => {
|
|
44
|
+
const accessibilityHints: string[] = [];
|
|
45
|
+
|
|
46
|
+
if (helperText) {
|
|
47
|
+
accessibilityHints.push(helperText);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (validationStatus === 'invalid' && invalidText) {
|
|
51
|
+
accessibilityHints.push(invalidText);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (validationStatus === 'valid' && validText) {
|
|
55
|
+
accessibilityHints.push(validText);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return accessibilityHints.join(', ') || fallbackHint;
|
|
59
|
+
}, [fallbackHint, helperText, invalidText, validText, validationStatus]);
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
accessibilityHint,
|
|
63
|
+
accessibilityLabel,
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default useFormFieldAccessibility;
|