Skip to content

Commit 839ceb3

Browse files
authored
chore(rna): add labelHidden support and example apps (#3043)
1 parent d56b4aa commit 839ceb3

File tree

7 files changed

+137
-12
lines changed

7 files changed

+137
-12
lines changed

examples/react-native/src/App/App.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import React from 'react';
22

3-
// import Example from '../features/Authenticator/Demo/Example';
4-
import Example from '../features/Authenticator/Slots/Example';
3+
import Example from '../features/Authenticator/Demo/Example';
4+
// import Example from '../features/Authenticator/Fields/Example';
5+
// import Example from '../features/Authenticator/LabelHidden/Example';
6+
// import Example from '../features/Authenticator/Slots/Example';
57
// import Example from '../features/Authenticator/Styles/Example';
68

79
// import { Demo as InAppDemo } from '../features/InAppMessaging';

examples/react-native/src/features/Authenticator/Demo/Example.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
import React from 'react';
2-
import { StyleSheet, View } from 'react-native';
2+
import { Button, StyleSheet, View } from 'react-native';
33

44
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
55
import { Amplify } from 'aws-amplify';
66

7-
import { Button } from '../../../ui';
8-
97
// replace with actual amplify config from environments
108
// import config from '../../../aws-exports';
119

1210
Amplify.configure({});
1311

1412
function SignOutButton() {
1513
const { signOut } = useAuthenticator();
16-
return <Button onPress={signOut}>Sign Out</Button>;
14+
return <Button onPress={signOut} title="Sign Out" />;
1715
}
1816

1917
function App() {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react';
2+
import { Button, StyleSheet, View } from 'react-native';
3+
4+
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
5+
import { Amplify } from 'aws-amplify';
6+
7+
// replace with actual amplify config from environments
8+
// import config from '../../../aws-exports';
9+
10+
Amplify.configure({});
11+
12+
function SignOutButton() {
13+
const { signOut } = useAuthenticator();
14+
return <Button onPress={signOut} title="Sign Out" />;
15+
}
16+
17+
function App() {
18+
return (
19+
<Authenticator.Provider>
20+
<Authenticator
21+
components={{
22+
SignUp: ({ fields, ...props }) => (
23+
<Authenticator.SignUp
24+
{...props}
25+
fields={[
26+
...fields,
27+
{
28+
name: 'preferred_username',
29+
label: 'Preferred Username',
30+
type: 'default',
31+
placeholder: 'Enter your preferred username',
32+
},
33+
]}
34+
/>
35+
),
36+
}}
37+
>
38+
<View style={style.container}>
39+
<SignOutButton />
40+
</View>
41+
</Authenticator>
42+
</Authenticator.Provider>
43+
);
44+
}
45+
46+
const style = StyleSheet.create({
47+
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
48+
});
49+
50+
export default App;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from 'react';
2+
import { Button, StyleSheet, View } from 'react-native';
3+
4+
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native';
5+
import { Amplify } from 'aws-amplify';
6+
7+
// replace with actual amplify config from environments
8+
// import config from '../../../aws-exports';
9+
10+
Amplify.configure({});
11+
12+
function SignOutButton() {
13+
const { signOut } = useAuthenticator();
14+
return <Button onPress={signOut} title="Sign Out" />;
15+
}
16+
17+
function App() {
18+
return (
19+
<Authenticator.Provider>
20+
<Authenticator
21+
components={{
22+
SignIn: ({ fields, ...props }) => (
23+
<Authenticator.SignIn
24+
{...props}
25+
fields={fields.map((field) => ({ ...field, labelHidden: true }))}
26+
/>
27+
),
28+
}}
29+
>
30+
<View style={style.container}>
31+
<SignOutButton />
32+
</View>
33+
</Authenticator>
34+
</Authenticator.Provider>
35+
);
36+
}
37+
38+
const style = StyleSheet.create({
39+
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
40+
});
41+
42+
export default App;

packages/react-native/src/Authenticator/hooks/types.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,20 @@ export type TextFieldOnBlur = TextFieldProps['onBlur'];
1717
export type OnChangeText = TextFieldProps['onChangeText'];
1818

1919
type FieldOptions<FieldProps, Type extends AuthenticatorFieldTypeKey> = {
20-
type: Type;
2120
name: string;
22-
required?: boolean;
2321
onBlur?: Type extends 'radio' ? RadioFieldOnBlur : TextFieldOnBlur;
22+
required?: boolean;
23+
type: Type;
2424
} & Omit<FieldProps, 'disabled' | 'onBlur'>;
2525

2626
type PasswordFieldOptions = FieldOptions<PasswordFieldProps, 'password'>;
2727
type PhoneFieldOptions = FieldOptions<PhoneNumberFieldProps, 'phone'>;
2828
type DefaultFieldOptions = FieldOptions<TextFieldProps, 'default'>;
29-
export type TextFieldOptionsType =
29+
export type TextFieldOptionsType = (
3030
| PasswordFieldOptions
3131
| PhoneFieldOptions
32-
| DefaultFieldOptions;
32+
| DefaultFieldOptions
33+
) & { labelHidden?: boolean };
3334

3435
export type RadioFieldOptions = FieldOptions<RadioProps<string>, 'radio'>;
3536

packages/react-native/src/Authenticator/hooks/useFieldValues/__tests__/useFieldValues.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import useFieldValues from '../useFieldValues';
1414
const warnSpy = jest.spyOn(Logger.prototype, 'warn').mockImplementation();
1515

1616
const textField = {
17+
label: 'test',
1718
type: 'default',
1819
name: 'test',
1920
value: 'testValue',
@@ -61,6 +62,28 @@ describe('useFieldValues', () => {
6162
});
6263
});
6364

65+
it('removes hidden labels from text fields', () => {
66+
const { result } = renderHook(() =>
67+
useFieldValues({
68+
...props,
69+
fields: [{ ...textField, labelHidden: true }],
70+
})
71+
);
72+
expect(result.current).toStrictEqual({
73+
disableFormSubmit: false,
74+
fields: [
75+
{
76+
...textField,
77+
label: undefined,
78+
onBlur: expect.any(Function),
79+
onChangeText: expect.any(Function),
80+
value: undefined,
81+
},
82+
],
83+
handleFormSubmit: expect.any(Function),
84+
});
85+
});
86+
6487
it('returns the expected values for radio fields', () => {
6588
const { result } = renderHook(() =>
6689
useFieldValues({
@@ -205,6 +228,7 @@ describe('useFieldValues', () => {
205228
fields: [
206229
{
207230
...mockTextField,
231+
label: undefined,
208232
onBlur: expect.any(Function),
209233
onChangeText: expect.any(Function),
210234
value: undefined,
@@ -216,6 +240,7 @@ describe('useFieldValues', () => {
216240

217241
it('enables form submit if required fields have values', () => {
218242
const mockTextField = {
243+
label: 'test',
219244
type: 'default',
220245
name: 'test',
221246
required: true,

packages/react-native/src/Authenticator/hooks/useFieldValues/useFieldValues.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export default function useFieldValues<FieldType extends TypedField>({
5050
return { ...field, onChange };
5151
}
5252

53-
const { name } = field;
53+
const { name, label, labelHidden, ...rest } = field;
5454

5555
const onBlur: TextFieldOnBlur = (event) => {
5656
// call `onBlur` passed as text `field` option
@@ -70,7 +70,14 @@ export default function useFieldValues<FieldType extends TypedField>({
7070
setValues({ ...values, [name]: value });
7171
};
7272

73-
return { ...field, onBlur, onChangeText, name, value: values[name] };
73+
return {
74+
...rest,
75+
label: labelHidden ? undefined : label,
76+
onBlur,
77+
onChangeText,
78+
name,
79+
value: values[name],
80+
};
7481
}) as FieldType[];
7582

7683
const disableFormSubmit = isRadioFieldComponent

0 commit comments

Comments
 (0)