1import React from 'react';
2
3import {
4  AppleAuthenticationButtonProps,
5  AppleAuthenticationButtonStyle,
6  AppleAuthenticationButtonType,
7} from './AppleAuthentication.types';
8import {
9  ExpoAppleAuthenticationButtonSignInWhite,
10  ExpoAppleAuthenticationButtonSignInWhiteOutline,
11  ExpoAppleAuthenticationButtonSignInBlack,
12  ExpoAppleAuthenticationButtonContinueWhite,
13  ExpoAppleAuthenticationButtonContinueWhiteOutline,
14  ExpoAppleAuthenticationButtonContinueBlack,
15  ExpoAppleAuthenticationButtonSignUpWhite,
16  ExpoAppleAuthenticationButtonSignUpWhiteOutline,
17  ExpoAppleAuthenticationButtonSignUpBlack,
18} from './ExpoAppleAuthenticationButton';
19
20// @needsAudit
21/**
22 * This component displays the proprietary "Sign In with Apple" / "Continue with Apple" button on
23 * your screen. The App Store Guidelines require you to use this component to start the
24 * authentication process instead of a custom button. Limited customization of the button is
25 * available via the provided properties.
26 *
27 * You should only attempt to render this if [`AppleAuthentication.isAvailableAsync()`](#isavailableasync)
28 * resolves to `true`. This component will render nothing if it is not available, and you will get
29 * a warning in development mode (`__DEV__ === true`).
30 *
31 * The properties of this component extend from `View`; however, you should not attempt to set
32 * `backgroundColor` or `borderRadius` with the `style` property. This will not work and is against
33 * the App Store Guidelines. Instead, you should use the `buttonStyle` property to choose one of the
34 * predefined color styles and the `cornerRadius` property to change the border radius of the
35 * button.
36 *
37 * Make sure to attach height and width via the style props as without these styles, the button will
38 * not appear on the screen.
39 *
40 * @see [Apple
41 * Documentation](https://developer.apple.com/documentation/authenticationservices/asauthorizationappleidbutton)
42 * for more details.
43 */
44const AppleAuthenticationButton: React.FC<AppleAuthenticationButtonProps> = ({
45  onPress,
46  buttonStyle,
47  buttonType,
48  ...restProps
49}) => {
50  if (!ExpoAppleAuthenticationButtonSignInWhite) {
51    if (__DEV__) {
52      console.warn("'AppleAuthenticationButton' is not available.");
53    }
54    return null;
55  }
56
57  const AppleAuthenticationButtonComponent = selectButtonComponent(buttonType, buttonStyle);
58
59  return <AppleAuthenticationButtonComponent onButtonPress={onPress} {...restProps} />;
60};
61
62const ButtonComponents: { [type: number]: { [style: number]: React.ElementType } } = {
63  [AppleAuthenticationButtonType.SIGN_IN]: {
64    [AppleAuthenticationButtonStyle.WHITE]: ExpoAppleAuthenticationButtonSignInWhite,
65    [AppleAuthenticationButtonStyle.WHITE_OUTLINE]: ExpoAppleAuthenticationButtonSignInWhiteOutline,
66    [AppleAuthenticationButtonStyle.BLACK]: ExpoAppleAuthenticationButtonSignInBlack,
67  },
68  [AppleAuthenticationButtonType.CONTINUE]: {
69    [AppleAuthenticationButtonStyle.WHITE]: ExpoAppleAuthenticationButtonContinueWhite,
70    [AppleAuthenticationButtonStyle.WHITE_OUTLINE]:
71      ExpoAppleAuthenticationButtonContinueWhiteOutline,
72    [AppleAuthenticationButtonStyle.BLACK]: ExpoAppleAuthenticationButtonContinueBlack,
73  },
74  [AppleAuthenticationButtonType.SIGN_UP]: {
75    [AppleAuthenticationButtonStyle.WHITE]: ExpoAppleAuthenticationButtonSignUpWhite,
76    [AppleAuthenticationButtonStyle.WHITE_OUTLINE]: ExpoAppleAuthenticationButtonSignUpWhiteOutline,
77    [AppleAuthenticationButtonStyle.BLACK]: ExpoAppleAuthenticationButtonSignUpBlack,
78  },
79};
80
81const selectButtonComponent = (
82  type: AppleAuthenticationButtonType,
83  style: AppleAuthenticationButtonStyle
84): React.ElementType => ButtonComponents[type][style];
85
86export default AppleAuthenticationButton;
87