Skip to content

Commit 8cc5853

Browse files
chore(authenticator): Add Authenticator Component Overrides Sample Application and Documentation (#6416)
* chore(react-native): expose Authenticator component props, add UI override example * chore: add rn component overrides / examples * chore: add rn component overrides docs * chore: add basic component override tests * chore: update export snap * Create three-phones-look.md * chore: remove babel optional require --------- Co-authored-by: Caleb Pollman <cpollman@amazon.com>
1 parent 4e9ec64 commit 8cc5853

File tree

31 files changed

+1384
-105
lines changed

31 files changed

+1384
-105
lines changed

.changeset/three-phones-look.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@aws-amplify/ui-docs": patch
3+
"@aws-amplify/ui-react-native-example": patch
4+
"@aws-amplify/ui-e2e": patch
5+
"@aws-amplify/ui-react-native": patch
6+
---
7+
8+
chore(authenticator): Add Authenticator Component Overrides Sample Application and Documentation

docs/src/pages/[platform]/connected-components/authenticator/customization/customization.headers-and-footers.react-native.mdx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Tabs } from '@aws-amplify/ui-react';
2+
13
## Authenticator Container, Header & Footer Slots
24

35
The Authenticator has several "slots" that you can customize to add messaging & functionality to meet your app's needs.
@@ -30,3 +32,68 @@ The `Authenticator` subcomponents can be overridden allowing for advanced use ca
3032
```jsx expoSnack file=../../../../../../../examples/react-native/src/features/Authenticator/Component/Example.tsx
3133

3234
```
35+
36+
### Override components with third-party component library
37+
The following example shows how to override each component in the Authenticator to produce a distinct look and feel using a third-party component library.
38+
39+
<Tabs.Container defaultValue="example">
40+
<Tabs.List style={{ overflowX: 'scroll', paddingBottom: 8 }}>
41+
<Tabs.Item value="example">Example.tsx</Tabs.Item>
42+
<Tabs.Item value="confirm-reset-password">
43+
ConfirmResetPassword.tsx
44+
</Tabs.Item>
45+
<Tabs.Item value="confirm-sign-in">ConfirmSignIn.tsx</Tabs.Item>
46+
<Tabs.Item value="confirm-verify-user">ConfirmVerifyUser.tsx</Tabs.Item>
47+
<Tabs.Item value="force-new-password">ForceNewPassword.tsx</Tabs.Item>
48+
<Tabs.Item value="forgot-password">ForgotPassword.tsx</Tabs.Item>
49+
<Tabs.Item value="setup-totp">SetupTotp.tsx</Tabs.Item>
50+
<Tabs.Item value="sign-in">SignIn.tsx</Tabs.Item>
51+
<Tabs.Item value="sign-up">SignUp.tsx</Tabs.Item>
52+
<Tabs.Item value="verify-user">VerifyUser.tsx</Tabs.Item>
53+
<Tabs.Item value="components">components.tsx</Tabs.Item>
54+
</Tabs.List>
55+
<Tabs.Panel value="example">
56+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/Example.tsx
57+
```
58+
</Tabs.Panel>
59+
<Tabs.Panel value="confirm-reset-password">
60+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/ConfirmResetPassword.tsx
61+
```
62+
</Tabs.Panel>
63+
<Tabs.Panel value="confirm-sign-in">
64+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/ConfirmSignIn.tsx
65+
```
66+
</Tabs.Panel>
67+
<Tabs.Panel value="confirm-verify-user">
68+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/ConfirmVerifyUser.tsx
69+
```
70+
</Tabs.Panel>
71+
<Tabs.Panel value="force-new-password">
72+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/ForceNewPassword.tsx
73+
```
74+
</Tabs.Panel>
75+
<Tabs.Panel value="forgot-password">
76+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/ForgotPassword.tsx
77+
```
78+
</Tabs.Panel>
79+
<Tabs.Panel value="setup-totp">
80+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/SetupTotp.tsx
81+
```
82+
</Tabs.Panel>
83+
<Tabs.Panel value="sign-in">
84+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/SignIn.tsx
85+
```
86+
</Tabs.Panel>
87+
<Tabs.Panel value="sign-up">
88+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/SignUp.tsx
89+
```
90+
</Tabs.Panel>
91+
<Tabs.Panel value="verify-user">
92+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/VerifyUser.tsx
93+
```
94+
</Tabs.Panel>
95+
<Tabs.Panel value="components">
96+
```jsx file=../../../../../../../examples/react-native/src/features/Authenticator/OverrideComponents/components.tsx
97+
```
98+
</Tabs.Panel>
99+
</Tabs.Container>

examples/react-native/babel.config.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
module.exports = {
22
presets: ['module:metro-react-native-babel-preset'],
33
plugins: [
4-
[
5-
'module:react-native-dotenv',
6-
{
7-
moduleName: '@env',
8-
path: '.env',
9-
},
10-
],
4+
['module:react-native-dotenv', { moduleName: '@env', path: '.env' }],
115
],
126
};
Binary file not shown.

examples/react-native/ios/Podfile.lock

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,9 @@ PODS:
364364
- React-perflogger (= 0.71.16)
365365
- RNCAsyncStorage (1.18.1):
366366
- React-Core
367+
- RNVectorIcons (10.2.0):
368+
- RCT-Folly (= 2021.07.22.00)
369+
- React-Core
367370
- Yoga (1.14.0)
368371

369372
DEPENDENCIES:
@@ -409,6 +412,7 @@ DEPENDENCIES:
409412
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
410413
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
411414
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
415+
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
412416
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
413417

414418
SPEC REPOS:
@@ -497,12 +501,14 @@ EXTERNAL SOURCES:
497501
:path: "../node_modules/react-native/ReactCommon"
498502
RNCAsyncStorage:
499503
:path: "../node_modules/@react-native-async-storage/async-storage"
504+
RNVectorIcons:
505+
:path: "../node_modules/react-native-vector-icons"
500506
Yoga:
501507
:path: "../node_modules/react-native/ReactCommon/yoga"
502508

503509
SPEC CHECKSUMS:
504-
AmplifyRTNCore: 7aabcf40316c2f5c853c1ef73139af3b24a5406b
505-
AmplifyRTNWebBrowser: c80e90e76b89ed768370e1a2d2400fe2fd672bfc
510+
AmplifyRTNCore: 61f4fc669a2284d2cb50e8c3d4563fac1e4505bd
511+
AmplifyRTNWebBrowser: c84ed53a38c31aede2a29ddc78184b3ef33b8549
506512
boost: 7dcd2de282d72e344012f7d6564d024930a6a440
507513
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
508514
FBLazyVector: 9840513ec2766e31fb9e34c2dabb2c4671400fcd
@@ -511,38 +517,39 @@ SPEC CHECKSUMS:
511517
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
512518
hermes-engine: 2382506846564caf4152c45390dc24f08fce7057
513519
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
514-
RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
520+
RCT-Folly: 8dc08ca5a393b48b1c523ab6220dfdcc0fe000ad
515521
RCTRequired: 44a3cda52ccac0be738fbf43fef90f3546a48c52
516522
RCTTypeSafety: da7fbf9826fc898ca8b10dc840f2685562039a64
517523
React: defd955b6d6ffb9791bb66dee08d90b87a8e2c0c
518524
React-callinvoker: 39ea57213d56ec9c527d51bd0dfb45cbb12ef447
519-
React-Codegen: 71cbc1bc384f9d19a41e4d00dfd0e7762ec5ef4a
520-
React-Core: 898cb2f7785640e21d381b23fc64a2904628b368
521-
React-CoreModules: 7f71e7054395d61585048061a66d67b58d3d27b7
522-
React-cxxreact: 57fca29dd6995de0ee360980709c4be82d40cda1
523-
React-hermes: 33229fc1867df496665b36b222a82a0f850bcae1
524-
React-jsi: 3a55652789df6ddd777cce9601bf000e18d6b9df
525-
React-jsiexecutor: 9b2a87f674f30da4706af52520e4860974cec149
525+
React-Codegen: a383556237715e2f75fb0678a932bc5ad53995a5
526+
React-Core: d28fd78dc9ba11686213ef1304b876fbe14504b0
527+
React-CoreModules: f1e28e36e71add156b108ff1dd00cfdb5399da68
528+
React-cxxreact: e0f18fd5ccd178950aeaca8e5e71bea4c1854f69
529+
React-hermes: 82799e534d3329c041d7b736ea201e7b95da1112
530+
React-jsi: 4f0c076e37f6c6b9e1ebf5783918a2b3de3697f7
531+
React-jsiexecutor: 173c86f9ab3434c9134ade7294f8be06398b4f0a
526532
React-jsinspector: b3b341764ccda14f3659c00a9bc5b098b334db2b
527-
React-logger: dc96fadd2f7f6bc38efc3cfb5fef876d4e6290a2
528-
react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb
529-
react-native-launch-arguments: 8e21f656fb7ade515fd974209b06be1b9279c91e
530-
react-native-netinfo: 1a6035d3b9780221d407c277ebfb5722ace00658
531-
react-native-safe-area-context: 238cd8b619e05cb904ccad97ef42e84d1b5ae6ec
533+
React-logger: 9fce62c1d7893429ce7558b9f6b83c5c79f946d1
534+
react-native-get-random-values: 419569b6ed3d15bfb9b6781b2f2e058f8e8d2698
535+
react-native-launch-arguments: c16edb82a61942e0be7c2542b8a0eae4ee501460
536+
react-native-netinfo: 98ba850c436e81a5e811abb5055952db52d5d023
537+
react-native-safe-area-context: 71b3a0d71549684af7f975f12f3bd7039ea54b14
532538
React-perflogger: c944b06edad34f5ecded0f29a6e66290a005d365
533539
React-RCTActionSheet: fa467f37777dacba2c72da4be7ae065da4482d7d
534540
React-RCTAnimation: 0591ee5f9e3d8c864a0937edea2165fe968e7099
535-
React-RCTAppDelegate: 8b7f60103a83ad1670bda690571e73efddba29a0
536-
React-RCTBlob: 082e8612f48b0ec12ca6dc949fb7c310593eff83
541+
React-RCTAppDelegate: 04d2661dee11a68f5fd32c4b5d7ffa0dc0721094
542+
React-RCTBlob: 8f263e84a89652c58899d2444c2a915aa5057feb
537543
React-RCTImage: 6300660ef04d0e8a710ad9ea5d2fb4d9521c200d
538544
React-RCTLinking: 7703ee1b10d3568c143a489ae74adc419c3f3ef3
539545
React-RCTNetwork: 5748c647e09c66b918f81ae15ed7474327f653be
540546
React-RCTSettings: 8c8a84ee363db9cbc287c8b8f2fb782acf7ba414
541547
React-RCTText: d5e53c0741e3e2df91317781e993b5e42bd70448
542548
React-RCTVibration: 052dd488ba95f461a37c992b9e01bd4bcc59a7b6
543549
React-runtimeexecutor: b5abe02558421897cd9f73d4f4b6adb4bc297083
544-
ReactCommon: a1a263d94f02a0dc8442f341d5a11b3d7a9cd44d
545-
RNCAsyncStorage: b90b71f45b8b97be43bc4284e71a6af48ac9f547
550+
ReactCommon: a9f87edf02caaec81cc0873f8261c863db124663
551+
RNCAsyncStorage: 01062b75ce749e3a18091a9ad7749effdf09ea43
552+
RNVectorIcons: 42c2c63b4d6e909a2b2497017e03ea04034b6722
546553
Yoga: e29645ec5a66fb00934fad85338742d1c247d4cb
547554

548555
PODFILE CHECKSUM: 86255707601fa0f502375c1c40775dbd535ed624

examples/react-native/ios/ReactNative.xcodeproj/project.pbxproj

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNative/Info.plist; sourceTree = "<group>"; };
3838
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNative/main.m; sourceTree = "<group>"; };
3939
19F6CBCC0A4E27FBF8BF4A61 /* libPods-ReactNative-ReactNativeTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNative-ReactNativeTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
40+
1D0CC3252D77A9FE00266072 /* MaterialCommunityIcons.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = MaterialCommunityIcons.ttf; sourceTree = "<group>"; };
4041
3B4392A12AC88292D35C810B /* Pods-ReactNative.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNative.debug.xcconfig"; path = "Target Support Files/Pods-ReactNative/Pods-ReactNative.debug.xcconfig"; sourceTree = "<group>"; };
4142
5709B34CF0A7D63546082F79 /* Pods-ReactNative.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNative.release.xcconfig"; path = "Target Support Files/Pods-ReactNative/Pods-ReactNative.release.xcconfig"; sourceTree = "<group>"; };
4243
5B7EB9410499542E8C5724F5 /* Pods-ReactNative-ReactNativeTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNative-ReactNativeTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNative-ReactNativeTests/Pods-ReactNative-ReactNativeTests.debug.xcconfig"; sourceTree = "<group>"; };
@@ -96,6 +97,14 @@
9697
name = ReactNative;
9798
sourceTree = "<group>";
9899
};
100+
1D0CC3242D77A98000266072 /* Fonts */ = {
101+
isa = PBXGroup;
102+
children = (
103+
1D0CC3252D77A9FE00266072 /* MaterialCommunityIcons.ttf */,
104+
);
105+
path = Fonts;
106+
sourceTree = "<group>";
107+
};
99108
2D16E6871FA4F8E400B85C8A /* Frameworks */ = {
100109
isa = PBXGroup;
101110
children = (
@@ -122,6 +131,7 @@
122131
83CBBA001A601CBA00E9B192 /* Products */,
123132
2D16E6871FA4F8E400B85C8A /* Frameworks */,
124133
BBD78D7AC51CEA395F1C20DB /* Pods */,
134+
1D0CC3242D77A98000266072 /* Fonts */,
125135
);
126136
indentWidth = 2;
127137
sourceTree = "<group>";
Lines changed: 59 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,68 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
4+
<dict>
5+
<key>UIAppFonts</key>
6+
<array>
7+
<string>MaterialCommunityIcons.ttf</string>
8+
</array>
9+
<key>CFBundleDevelopmentRegion</key>
10+
<string>en</string>
11+
<key>CFBundleDisplayName</key>
12+
<string>ReactNative</string>
13+
<key>CFBundleExecutable</key>
14+
<string>$(EXECUTABLE_NAME)</string>
15+
<key>CFBundleIdentifier</key>
16+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
17+
<key>CFBundleInfoDictionaryVersion</key>
18+
<string>6.0</string>
19+
<key>CFBundleName</key>
20+
<string>$(PRODUCT_NAME)</string>
21+
<key>CFBundlePackageType</key>
22+
<string>APPL</string>
23+
<key>CFBundleShortVersionString</key>
24+
<string>$(MARKETING_VERSION)</string>
25+
<key>CFBundleSignature</key>
26+
<string>????</string>
27+
<key>CFBundleVersion</key>
28+
<string>$(CURRENT_PROJECT_VERSION)</string>
29+
<key>LSRequiresIPhoneOS</key>
30+
<true/>
31+
<key>NSAppTransportSecurity</key>
432
<dict>
5-
<key>CFBundleDevelopmentRegion</key>
6-
<string>en</string>
7-
<key>CFBundleDisplayName</key>
8-
<string>ReactNative</string>
9-
<key>CFBundleExecutable</key>
10-
<string>$(EXECUTABLE_NAME)</string>
11-
<key>CFBundleIdentifier</key>
12-
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
13-
<key>CFBundleInfoDictionaryVersion</key>
14-
<string>6.0</string>
15-
<key>CFBundleName</key>
16-
<string>$(PRODUCT_NAME)</string>
17-
<key>CFBundlePackageType</key>
18-
<string>APPL</string>
19-
<key>CFBundleShortVersionString</key>
20-
<string>$(MARKETING_VERSION)</string>
21-
<key>CFBundleSignature</key>
22-
<string>????</string>
23-
<key>CFBundleVersion</key>
24-
<string>$(CURRENT_PROJECT_VERSION)</string>
25-
<key>LSRequiresIPhoneOS</key>
26-
<true/>
27-
<key>NSAppTransportSecurity</key>
33+
<key>NSExceptionDomains</key>
2834
<dict>
29-
<key>NSExceptionDomains</key>
35+
<key>localhost</key>
3036
<dict>
31-
<key>localhost</key>
32-
<dict>
33-
<key>NSExceptionAllowsInsecureHTTPLoads</key>
34-
<true/>
35-
</dict>
37+
<key>NSExceptionAllowsInsecureHTTPLoads</key>
38+
<true/>
3639
</dict>
3740
</dict>
38-
<key>NSLocationWhenInUseUsageDescription</key>
39-
<string/>
40-
<key>UILaunchStoryboardName</key>
41-
<string>LaunchScreen</string>
42-
<key>UIRequiredDeviceCapabilities</key>
43-
<array>
44-
<string>armv7</string>
45-
</array>
46-
<key>UISupportedInterfaceOrientations</key>
47-
<array>
48-
<string>UIInterfaceOrientationPortrait</string>
49-
<string>UIInterfaceOrientationLandscapeLeft</string>
50-
<string>UIInterfaceOrientationLandscapeRight</string>
51-
</array>
52-
<key>UIViewControllerBasedStatusBarAppearance</key>
53-
<false/>
54-
<key>CFBundleURLTypes</key>
55-
<array>
56-
<dict>
57-
<key>CFBundleURLSchemes</key>
58-
<array>
59-
<string>fed-auth-example</string>
60-
</array>
61-
</dict>
62-
</array>
6341
</dict>
64-
</plist>
42+
<key>NSLocationWhenInUseUsageDescription</key>
43+
<string></string>
44+
<key>UILaunchStoryboardName</key>
45+
<string>LaunchScreen</string>
46+
<key>UIRequiredDeviceCapabilities</key>
47+
<array>
48+
<string>armv7</string>
49+
</array>
50+
<key>UISupportedInterfaceOrientations</key>
51+
<array>
52+
<string>UIInterfaceOrientationPortrait</string>
53+
<string>UIInterfaceOrientationLandscapeLeft</string>
54+
<string>UIInterfaceOrientationLandscapeRight</string>
55+
</array>
56+
<key>UIViewControllerBasedStatusBarAppearance</key>
57+
<false/>
58+
<key>CFBundleURLTypes</key>
59+
<array>
60+
<dict>
61+
<key>CFBundleURLSchemes</key>
62+
<array>
63+
<string>fed-auth-example</string>
64+
</array>
65+
</dict>
66+
</array>
67+
</dict>
68+
</plist>

examples/react-native/metro.config.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ const INTERNAL_DEPENDENCY_DIRECTORY_NAMES = [
1616
'ui',
1717
];
1818

19+
// 3rd party react native module names
20+
const EXTERNAL_MODULE_NAMES = [
21+
'@aws-amplify/react-native',
22+
'react-native',
23+
'react-native-paper',
24+
'react-native-url-polyfill',
25+
'react-native-safe-area-context',
26+
'react-native-vector-icons',
27+
];
28+
1929
const EXAMPLE_APP_PACKAGE_JSON = require('./package.json');
2030
const EXAMPLE_APP_ROOT = __dirname;
2131

@@ -144,20 +154,12 @@ config.server.enhanceMiddleware = (middleware) => {
144154
};
145155
};
146156

147-
config.resolver.extraNodeModules = {
148-
'@aws-amplify/react-native': path.resolve(
149-
__dirname,
150-
'node_modules/@aws-amplify/react-native'
151-
),
152-
'react-native': path.resolve(__dirname, 'node_modules/react-native'),
153-
'react-native-url-polyfill': path.resolve(
154-
__dirname,
155-
'node_modules/react-native-url-polyfill'
156-
),
157-
'react-native-safe-area-context': path.resolve(
158-
__dirname,
159-
'node_modules/react-native-safe-area-context'
160-
),
161-
};
157+
config.resolver.extraNodeModules = EXTERNAL_MODULE_NAMES.reduce(
158+
(modules, moduleName) => ({
159+
...modules,
160+
[moduleName]: path.resolve(__dirname, `node_modules/${moduleName}`),
161+
}),
162+
{}
163+
);
162164

163165
module.exports = config;

0 commit comments

Comments
 (0)