ref(ui-components) Improve Button component (#12015)

Bring web and native more in line
This commit is contained in:
Robert Pintilii 2022-08-22 12:40:59 +03:00 committed by GitHub
parent 2f10d80184
commit 40637aa3dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 110 additions and 108 deletions

View File

@ -1,5 +1,3 @@
// @flow
import { font, colors, colorMap, spacing, shape, typography } from '../Tokens';
import { createNativeTheme } from '../functions.native';

View File

@ -8,7 +8,6 @@ import {
} from 'react-native-paper';
import { BUTTON_MODES, BUTTON_TYPES } from '../../constants';
// @ts-ignore
import BaseTheme from '../BaseTheme.native';
import { ButtonProps } from '../types';
@ -17,7 +16,6 @@ import styles from './buttonStyles';
export interface IButtonProps extends ButtonProps {
color?: string;
labelStyle?: Object | undefined;
onPress?: Function;
style?: Object | undefined;
}
@ -26,9 +24,9 @@ const Button: React.FC<IButtonProps> = ({
color: buttonColor,
disabled,
icon,
label,
labelKey,
labelStyle,
onPress,
onClick: onPress,
style,
type
}: IButtonProps) => {
@ -70,7 +68,6 @@ const Button: React.FC<IButtonProps> = ({
<TouchableRipple
accessibilityLabel = { accessibilityLabel }
disabled = { disabled }
// @ts-ignore
onPress = { onPress }
rippleColor = 'transparent'
style = { [
@ -81,18 +78,18 @@ const Button: React.FC<IButtonProps> = ({
style = { [
buttonLabelStyles,
labelStyle
] }>{ t(label ?? '') }</Text>
] }>{ t(labelKey ?? '') }</Text>
</TouchableRipple>
);
}
return (
// @ts-ignore
<NativePaperButton
accessibilityLabel = { t(accessibilityLabel ?? '') }
children = { t(label ?? '') }
children = { t(labelKey ?? '') }
color = { color }
disabled = { disabled }
// @ts-ignore
icon = { icon }
labelStyle = { [
buttonLabelStyles,

View File

@ -1,3 +1,5 @@
import { GestureResponderEvent } from 'react-native';
import { BUTTON_TYPES } from '../constants';
export interface ButtonProps {
@ -18,9 +20,14 @@ export interface ButtonProps {
icon?: Function;
/**
* The text to be displayed on the button.
* The translation key of the text to be displayed on the button.
*/
label?: string;
labelKey?: string;
/**
* Click callback.
*/
onClick?: (e?: React.MouseEvent<HTMLButtonElement> | GestureResponderEvent) => void;
/**
* The type of button to be displayed.

View File

@ -1,5 +1,3 @@
// @flow
/**
* Custom theme for setting client branding.
*

View File

@ -1,6 +1,7 @@
import { makeStyles } from '@material-ui/core';
import clsx from 'clsx';
import React from 'react';
import { useTranslation } from 'react-i18next';
import Icon from '../../../icons/components/Icon';
import { withPixelLineHeight } from '../../../styles/functions.web';
@ -8,7 +9,6 @@ import { BUTTON_TYPES } from '../../constants';
import { Theme } from '../../types';
import { ButtonProps } from '../types';
interface IButtonProps extends ButtonProps {
/**
@ -32,9 +32,10 @@ interface IButtonProps extends ButtonProps {
isSubmit?: boolean;
/**
* Click callback.
* Text to be displayed on the component.
* Used when there's no labelKey.
*/
onClick?: (e?: React.MouseEvent<HTMLButtonElement>) => void;
label?: string;
/**
* Which size the button should be.
@ -185,19 +186,21 @@ const Button = ({
id,
isSubmit,
label,
labelKey,
onClick = () => null,
size = 'medium',
testId,
type = BUTTON_TYPES.PRIMARY
}: IButtonProps) => {
const styles = useStyles();
const { t } = useTranslation();
return (
<button
aria-label = { accessibilityLabel }
className = { clsx(styles.button, styles[type],
disabled && styles.disabled,
icon && !label && `${styles.iconButton} iconButton`,
icon && !(labelKey || label) && `${styles.iconButton} iconButton`,
styles[size], fullWidth && styles.fullWidth, className) }
data-testid = { testId }
disabled = { disabled }
@ -208,7 +211,9 @@ const Button = ({
{icon && <Icon
size = { 20 }
src = { icon } />}
{label && <span className = { icon ? styles.textWithIcon : '' }>{label}</span>}
{(labelKey || label) && <span className = { icon ? styles.textWithIcon : '' }>
{labelKey ? t(labelKey) : label}
</span>}
</button>
);
};

View File

@ -13,7 +13,9 @@ export enum BUTTON_TYPES {
/**
* The modes of the buttons.
*/
export const BUTTON_MODES = {
export const BUTTON_MODES: {
CONTAINED: 'contained'
} = {
CONTAINED: 'contained'
};

View File

@ -1,5 +1,3 @@
// @flow
import { DefaultTheme } from 'react-native-paper';
import { createColorTokens } from './utils';
@ -10,7 +8,7 @@ import { createColorTokens } from './utils';
* @param {Object} arg - The ui tokens.
* @returns {Object}
*/
export function createNativeTheme({ font, colors, colorMap, shape, spacing, typography }: Object) {
export function createNativeTheme({ font, colors, colorMap, shape, spacing, typography }: any): any {
return {
...DefaultTheme,
palette: createColorTokens(colorMap, colors),

View File

@ -6,7 +6,7 @@
* @param {Object} colors - An object containing all the theme colors.
* @returns {Object}
*/
export function createColorTokens(colorMap: Object, colors: Object): Object {
export function createColorTokens(colorMap: Object, colors: Object): any {
return Object.entries(colorMap)
.reduce((result, [ token, value ]: [any, keyof Object]) =>
Object.assign(result, { [token]: colors[value] || value }), {});

View File

@ -21,7 +21,7 @@ type Props = {
/**
* True if currently in a breakout room.
*/
_isInBreakoutRoom: boolean,
_isInBreakoutRoom: boolean,
/**
* True if the invite functions (dial out, invite, share...etc) are disabled.
@ -98,8 +98,8 @@ class LonelyMeetingExperience extends PureComponent<Props> {
<Button
accessibilityLabel = 'lonelyMeetingExperience.button'
icon = { this._renderAddPeopleIcon }
label = 'lonelyMeetingExperience.button'
onPress = { this._onPress }
labelKey = 'lonelyMeetingExperience.button'
onClick = { this._onPress }
style = { styles.lonelyButton }
type = { BUTTON_TYPES.PRIMARY } />
) }

View File

@ -30,10 +30,9 @@ const EndMeetingButton = () : JSX.Element => {
return (
<Button
accessibilityLabel = 'carmode.actions.leaveMeeting'
// @ts-ignore
icon = { EndMeetingIcon }
label = 'carmode.actions.leaveMeeting'
onPress = { onSelect }
labelKey = 'carmode.actions.leaveMeeting'
onClick = { onSelect }
style = { styles.endMeetingButton }
type = { BUTTON_TYPES.DESTRUCTIVE } />
);

View File

@ -28,10 +28,9 @@ const SelectSoundDevice = () : JSX.Element => {
return (
<Button
accessibilityLabel = 'carmode.actions.selectSoundDevice'
// @ts-ignore
icon = { AudioIcon }
label = 'carmode.actions.selectSoundDevice'
onPress = { onSelect }
labelKey = 'carmode.actions.selectSoundDevice'
onClick = { onSelect }
style = { styles.soundDeviceButton }
type = { BUTTON_TYPES.SECONDARY } />
);

View File

@ -190,15 +190,15 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
<View style = { styles.passwordJoinButtonsWrapper }>
<Button
accessibilityLabel = 'lobby.backToKnockModeButton'
label = 'lobby.backToKnockModeButton'
onPress = { this._onSwitchToKnockMode }
labelKey = 'lobby.backToKnockModeButton'
onClick = { this._onSwitchToKnockMode }
style = { styles.lobbyButton }
type = { BUTTON_TYPES.PRIMARY } />
<Button
accessibilityLabel = 'lobby.passwordJoinButton'
disabled = { !this.state.password }
label = 'lobby.passwordJoinButton'
onPress = { this._onJoinWithPassword }
labelKey = 'lobby.passwordJoinButton'
onClick = { this._onJoinWithPassword }
style = { styles.lobbyButton }
type = { BUTTON_TYPES.PRIMARY } />
</View>
@ -245,8 +245,8 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
_knocking && _isLobbyChatActive
&& <Button
accessibilityLabel = 'toolbar.openChat'
label = 'toolbar.openChat'
onPress = { this._onNavigateToLobbyChat }
labelKey = 'toolbar.openChat'
onClick = { this._onNavigateToLobbyChat }
style = { styles.openChatButton }
type = { BUTTON_TYPES.PRIMARY } />
}
@ -255,8 +255,8 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
|| <Button
accessibilityLabel = 'lobby.knockButton'
disabled = { !displayName }
label = 'lobby.knockButton'
onPress = { this._onAskToJoin }
labelKey = 'lobby.knockButton'
onClick = { this._onAskToJoin }
style = { styles.lobbyButton }
type = { BUTTON_TYPES.PRIMARY } />
}
@ -264,8 +264,8 @@ class LobbyScreen extends AbstractLobbyScreen<Props> {
_renderPassword
&& <Button
accessibilityLabel = 'lobby.enterPasswordButton'
label = 'lobby.enterPasswordButton'
onPress = { this._onSwitchToPasswordMode }
labelKey = 'lobby.enterPasswordButton'
onClick = { this._onSwitchToPasswordMode }
style = { styles.enterPasswordButton }
type = { BUTTON_TYPES.PRIMARY } />
}

View File

@ -25,8 +25,8 @@ const AddBreakoutRoomButton = () => {
return (
<Button
accessibilityLabel = 'breakoutRooms.actions.add'
label = 'breakoutRooms.actions.add'
onPress = { onAdd }
labelKey = 'breakoutRooms.actions.add'
onClick = { onAdd }
style = { styles.button }
type = { BUTTON_TYPES.SECONDARY } />
);

View File

@ -25,9 +25,9 @@ const AutoAssignButton = () => {
return (
<Button
accessibilityLabel = 'breakoutRooms.actions.autoAssign'
label = 'breakoutRooms.actions.autoAssign'
labelKey = 'breakoutRooms.actions.autoAssign'
labelStyle = { styles.autoAssignLabel }
onPress = { onAutoAssign }
onClick = { onAutoAssign }
style = { styles.autoAssignButton }
type = { BUTTON_TYPES.TERTIARY } />
);

View File

@ -29,8 +29,8 @@ const LeaveBreakoutRoomButton = () => {
return (
<Button
accessibilityLabel = 'breakoutRooms.actions.leaveBreakoutRoom'
label = 'breakoutRooms.actions.leaveBreakoutRoom'
onPress = { onLeave }
labelKey = 'breakoutRooms.actions.leaveBreakoutRoom'
onClick = { onLeave }
style = { styles.button }
type = { BUTTON_TYPES.DESTRUCTIVE } />
);

View File

@ -20,7 +20,7 @@ export const AddBreakoutRoomButton = () => {
<Button
accessibilityLabel = { t('breakoutRooms.actions.add') }
fullWidth = { true }
label = { t('breakoutRooms.actions.add') }
labelKey = { 'breakoutRooms.actions.add' }
onClick = { onAdd }
type = { BUTTON_TYPES.SECONDARY } />
);

View File

@ -20,7 +20,7 @@ export const AutoAssignButton = () => {
<Button
accessibilityLabel = { t('breakoutRooms.actions.autoAssign') }
fullWidth = { true }
label = { t('breakoutRooms.actions.autoAssign') }
labelKey = { 'breakoutRooms.actions.autoAssign' }
onClick = { onAutoAssign }
type = { BUTTON_TYPES.TERTIARY } />
);

View File

@ -45,7 +45,7 @@ const JoinActionButton = ({ room }: Props) => {
<Button
accessibilityLabel = { t('breakoutRooms.actions.join') }
className = { styles.button }
label = { t('breakoutRooms.actions.join') }
labelKey = { 'breakoutRooms.actions.join' }
onClick = { onJoinRoom }
size = 'small'
testId = { `join-room-${room.id}` } />

View File

@ -23,7 +23,7 @@ export const LeaveButton = () => {
<Button
accessibilityLabel = { t('breakoutRooms.actions.leaveBreakoutRoom') }
fullWidth = { true }
label = { t('breakoutRooms.actions.leaveBreakoutRoom') }
labelKey = { 'breakoutRooms.actions.leaveBreakoutRoom' }
onClick = { onLeave }
type = { BUTTON_TYPES.DESTRUCTIVE } />
);

View File

@ -39,8 +39,8 @@ export const LobbyParticipantItem = ({ participant: p }: Props) => {
videoMediaState = { MEDIA_STATE.NONE }>
<Button
accessibilityLabel = 'lobby.admit'
label = 'lobby.admit'
onPress = { admit }
labelKey = 'lobby.admit'
onClick = { admit }
style = { styles.participantActionsButtonAdmit }
type = { BUTTON_TYPES.PRIMARY } />
</ParticipantItem>

View File

@ -39,9 +39,9 @@ const LobbyParticipantList = () => {
participants.length > 1 && (
<Button
accessibilityLabel = 'lobby.admitAll'
label = 'lobby.admitAll'
labelKey = 'lobby.admitAll'
labelStyle = { styles.admitAllButtonLabel }
onPress = { admitAll }
onClick = { admitAll }
type = { BUTTON_TYPES.TERTIARY } />
)
}

View File

@ -229,8 +229,8 @@ class MeetingParticipantList extends PureComponent<Props> {
&& <Button
accessibilityLabel = 'participantsPane.actions.invite'
icon = { this._renderInviteMoreIcon }
label = 'participantsPane.actions.invite'
onPress = { this._onInvite }
labelKey = 'participantsPane.actions.invite'
onClick = { this._onInvite }
style = { styles.inviteButton }
type = { BUTTON_TYPES.PRIMARY } />
}

View File

@ -40,8 +40,8 @@ const ParticipantsPaneFooter = (): JSX.Element => {
showMuteAll && (
<Button
accessibilityLabel = 'participantsPane.actions.muteAll'
label = 'participantsPane.actions.muteAll'
onPress = { muteAll }
labelKey = 'participantsPane.actions.muteAll'
onClick = { muteAll }
type = { BUTTON_TYPES.SECONDARY } />
)
}

View File

@ -25,7 +25,7 @@ export const InviteButton = () => {
accessibilityLabel = { t('participantsPane.actions.invite') }
fullWidth = { true }
icon = { IconInviteMore }
label = { t('participantsPane.actions.invite') }
labelKey = { 'participantsPane.actions.invite' }
onClick = { onInvite }
type = { BUTTON_TYPES.PRIMARY } />
);

View File

@ -74,7 +74,7 @@ export const LobbyParticipantItem = ({
<Button
accessibilityLabel = { `${t('lobby.admit')} ${p.name}` }
className = { styles.button }
label = { t('lobby.admit') }
labelKey = { 'lobby.admit' }
onClick = { admit }
size = 'small'
testId = { `admit-${id}` } />);
@ -127,7 +127,7 @@ export const LobbyParticipantItem = ({
<Button
accessibilityLabel = { `${t('lobby.reject')} ${p.name}` }
className = { styles.button }
label = { t('lobby.reject') }
labelKey = { 'lobby.reject' }
onClick = { reject }
size = 'small'
testId = { `reject-${id}` }

View File

@ -262,7 +262,7 @@ class ParticipantsPane extends Component<Props, State> {
{_showMuteAllButton && (
<Button
accessibilityLabel = { t('participantsPane.actions.muteAll') }
label = { t('participantsPane.actions.muteAll') }
labelKey = { 'participantsPane.actions.muteAll' }
onClick = { this._onMuteAll }
type = { BUTTON_TYPES.SECONDARY } />
)}

View File

@ -53,15 +53,15 @@ const PollAnswer = (props: AbstractProps) => {
<View style = { chatStyles.buttonRow }>
<Button
accessibilityLabel = 'polls.answer.skip'
label = 'polls.answer.skip'
onPress = { changingVote ? skipChangeVote : skipAnswer }
labelKey = 'polls.answer.skip'
onClick = { changingVote ? skipChangeVote : skipAnswer }
style = { chatStyles.pollCreateButton }
type = { SECONDARY } />
<Button
accessibilityLabel = 'polls.answer.submit'
disabled = { isSubmitAnswerDisabled(checkBoxStates) }
label = 'polls.answer.submit'
onPress = { submitAnswer }
labelKey = 'polls.answer.submit'
onClick = { submitAnswer }
style = { chatStyles.pollCreateButton }
type = { PRIMARY } />
</View>

View File

@ -160,8 +160,8 @@ const PollCreate = (props: AbstractProps) => {
<Button
accessibilityLabel = 'polls.create.addOption'
disabled = { answers.length >= ANSWERS_LIMIT }
label = 'polls.create.addOption'
onPress = { () => {
labelKey = 'polls.create.addOption'
onClick = { () => {
// adding and answer
addAnswer();
requestFocus(answers.length);
@ -172,15 +172,15 @@ const PollCreate = (props: AbstractProps) => {
style = { buttonRowStyles }>
<Button
accessibilityLabel = 'polls.create.cancel'
label = 'polls.create.cancel'
onPress = { () => setCreateMode(false) }
labelKey = 'polls.create.cancel'
onClick = { () => setCreateMode(false) }
style = { chatStyles.pollCreateButton }
type = { SECONDARY } />
<Button
accessibilityLabel = 'polls.create.send'
disabled = { isSubmitDisabled }
label = 'polls.create.send'
onPress = { onSubmit }
labelKey = 'polls.create.send'
onClick = { onSubmit }
style = { chatStyles.pollCreateButton }
type = { PRIMARY } />
</View>

View File

@ -47,8 +47,8 @@ const PollsPane = (props: AbstractProps) => {
{
!createMode && <Button
accessibilityLabel = 'polls.create.create'
label = 'polls.create.create'
onPress = { onCreate }
labelKey = 'polls.create.create'
onClick = { onCreate }
style = { chatStyles.createPollButton }
type = { BUTTON_TYPES.PRIMARY } />
}

View File

@ -65,14 +65,14 @@ const PollAnswer = ({
accessibilityLabel = { t('polls.answer.skip') }
className = { styles.buttonMargin }
fullWidth = { true }
label = { t('polls.answer.skip') }
labelKey = { 'polls.answer.skip' }
onClick = { changingVote ? skipChangeVote : skipAnswer }
type = { BUTTON_TYPES.SECONDARY } />
<Button
accessibilityLabel = { t('polls.answer.submit') }
disabled = { isSubmitAnswerDisabled(checkBoxStates) }
fullWidth = { true }
label = { t('polls.answer.submit') }
labelKey = { 'polls.answer.submit' }
onClick = { submitAnswer } />
</div>
</div>

View File

@ -253,7 +253,7 @@ const PollCreate = ({
accessibilityLabel = { t('polls.create.addOption') }
disabled = { answers.length >= ANSWERS_LIMIT }
fullWidth = { true }
label = { t('polls.create.addOption') }
labelKey = { 'polls.create.addOption' }
onClick = { () => {
addAnswer();
requestFocus(answers.length);
@ -266,7 +266,7 @@ const PollCreate = ({
accessibilityLabel = { t('polls.create.cancel') }
className = { styles.buttonMargin }
fullWidth = { true }
label = { t('polls.create.cancel') }
labelKey = { 'polls.create.cancel' }
onClick = { () => setCreateMode(false) }
type = { BUTTON_TYPES.SECONDARY } />
<Button
@ -274,7 +274,7 @@ const PollCreate = ({
disabled = { isSubmitDisabled }
fullWidth = { true }
isSubmit = { true }
label = { t('polls.create.send') } />
labelKey = { 'polls.create.send' } />
</div>
</form>);

View File

@ -26,8 +26,7 @@ const PollsPane = (props: AbstractProps) => {
<Button
accessibilityLabel = { t('polls.create.create') }
fullWidth = { true }
label = { t('polls.create.create') }
// eslint-disable-next-line react/jsx-no-bind
labelKey = { 'polls.create.create' }
onClick = { onCreate } />
</div>
</div>;

View File

@ -158,14 +158,14 @@ const Prejoin: React.FC<PrejoinProps> = ({ navigation }: PrejoinProps) => {
<Button
accessibilityLabel = 'prejoin.joinMeeting'
disabled = { joinButtonDisabled }
label = 'prejoin.joinMeeting'
onPress = { onJoin }
labelKey = 'prejoin.joinMeeting'
onClick = { onJoin }
style = { styles.prejoinButton }
type = { PRIMARY } />
<Button
accessibilityLabel = 'prejoin.joinMeetingInLowBandwidthMode'
label = 'prejoin.joinMeetingInLowBandwidthMode'
onPress = { onJoinLowBandwidth }
labelKey = 'prejoin.joinMeetingInLowBandwidthMode'
onClick = { onJoinLowBandwidth }
style = { styles.prejoinButton }
type = { SECONDARY } />
</View>

View File

@ -151,8 +151,8 @@ class RaiseHandButton extends Component<Props, *> {
<Button
accessibilityLabel = { this.accessibilityLabel }
icon = { this._renderRaiseHandEmoji }
label = { this._getLabel() }
onPress = { this._onClick }
labelKey = { this._getLabel() }
onClick = { this._onClick }
style = { styles.raiseHandButton }
type = { BUTTON_TYPES.SECONDARY } />
);

View File

@ -30,14 +30,14 @@ const HighlightDialog = () => {
<View style = { styles.highlightDialogButtonsContainer } >
<Button
accessibilityLabel = 'dialog.Cancel'
label = 'dialog.Cancel'
onPress = { closeDialog }
labelKey = 'dialog.Cancel'
onClick = { closeDialog }
type = { BUTTON_TYPES.SECONDARY } />
<View style = { styles.highlightDialogButtonsSpace } />
<Button
accessibilityLabel = 'recording.highlight'
label = 'recording.highlight'
onPress = { highlightMoment }
labelKey = 'recording.highlight'
onClick = { highlightMoment }
type = { BUTTON_TYPES.PRIMARY } />
</View>
</View>

View File

@ -221,17 +221,17 @@ class SecurityDialog extends PureComponent<Props, State> {
<>
<Button
accessibilityLabel = 'dialog.Remove'
label = 'dialog.Remove'
labelKey = 'dialog.Remove'
labelStyle = { styles.passwordSetupButtonLabel }
onPress = { this._onCancel }
onClick = { this._onCancel }
type = { BUTTON_TYPES.TERTIARY } />
{
_password
&& <Button
accessibilityLabel = 'dialog.copy'
label = 'dialog.copy'
labelKey = 'dialog.copy'
labelStyle = { styles.passwordSetupButtonLabel }
onPress = { this._onCopy }
onClick = { this._onCopy }
type = { BUTTON_TYPES.TERTIARY } />
}
</>
@ -241,15 +241,15 @@ class SecurityDialog extends PureComponent<Props, State> {
<>
<Button
accessibilityLabel = 'dialog.Cancel'
label = 'dialog.Cancel'
labelKey = 'dialog.Cancel'
labelStyle = { styles.passwordSetupButtonLabel }
onPress = { this._onCancel }
onClick = { this._onCancel }
type = { BUTTON_TYPES.TERTIARY } />
<Button
accessibilityLabel = 'dialog.add'
label = 'dialog.add'
labelKey = 'dialog.add'
labelStyle = { styles.passwordSetupButtonLabel }
onPress = { this._onSubmit }
onClick = { this._onSubmit }
type = { BUTTON_TYPES.TERTIARY } />
</>
);
@ -258,9 +258,9 @@ class SecurityDialog extends PureComponent<Props, State> {
<Button
accessibilityLabel = 'info.addPassword'
disabled = { !_isModerator }
label = 'info.addPassword'
labelKey = 'info.addPassword'
labelStyle = { styles.passwordSetupButtonLabel }
onPress = { this._onAddPassword }
onClick = { this._onAddPassword }
type = { BUTTON_TYPES.TERTIARY } />
);
}
@ -274,9 +274,9 @@ class SecurityDialog extends PureComponent<Props, State> {
</Text>
<Button
accessibilityLabel = 'dialog.Remove'
label = 'dialog.Remove'
labelKey = 'dialog.Remove'
labelStyle = { styles.passwordSetupButtonLabel }
onPress = { this._onCancel }
onClick = { this._onCancel }
type = { BUTTON_TYPES.TERTIARY } />
</View>
);
@ -289,9 +289,9 @@ class SecurityDialog extends PureComponent<Props, State> {
<Button
accessibilityLabel = 'info.addPassword'
disabled = { !_isModerator }
label = 'info.addPassword'
labelKey = 'info.addPassword'
labelStyle = { styles.passwordSetupButtonLabel }
onPress = { this._onAddPassword }
onClick = { this._onAddPassword }
type = { BUTTON_TYPES.TERTIARY } />
</View>
);