feat(ui-components) Add toggle component (#11933)
This commit is contained in:
parent
3e66e0009d
commit
db54c45b13
|
@ -0,0 +1,117 @@
|
|||
import { makeStyles } from '@material-ui/core';
|
||||
import clsx from 'clsx';
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import { isMobileBrowser } from '../../../environment/utils';
|
||||
|
||||
interface SwitchProps {
|
||||
|
||||
/**
|
||||
* Whether or not the toggle is on.
|
||||
*/
|
||||
checked: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the toggle is disabled.
|
||||
*/
|
||||
disabled?: boolean;
|
||||
|
||||
/**
|
||||
* Id of the toggle.
|
||||
*/
|
||||
id?: string;
|
||||
|
||||
/**
|
||||
* Toggle change callback.
|
||||
*/
|
||||
onChange: (on?: boolean) => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme: any) => {
|
||||
return {
|
||||
container: {
|
||||
position: 'relative',
|
||||
backgroundColor: theme.palette.ui05,
|
||||
borderRadius: '12px',
|
||||
width: '40px',
|
||||
height: '24px',
|
||||
border: 0,
|
||||
outline: 0,
|
||||
cursor: 'pointer',
|
||||
transition: '.3s',
|
||||
display: 'inline-block',
|
||||
|
||||
'&.disabled': {
|
||||
backgroundColor: theme.palette.ui05,
|
||||
cursor: 'default',
|
||||
|
||||
'& .toggle': {
|
||||
backgroundColor: theme.palette.ui03
|
||||
}
|
||||
},
|
||||
|
||||
'&.is-mobile': {
|
||||
height: '32px',
|
||||
width: '50px',
|
||||
borderRadius: '32px'
|
||||
}
|
||||
},
|
||||
|
||||
containerOn: {
|
||||
backgroundColor: theme.palette.action01
|
||||
},
|
||||
|
||||
toggle: {
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
position: 'absolute',
|
||||
top: '4px',
|
||||
left: '4px',
|
||||
backgroundColor: theme.palette.ui10,
|
||||
borderRadius: '100%',
|
||||
transition: '.3s',
|
||||
|
||||
'&.is-mobile': {
|
||||
width: '24px',
|
||||
height: '24px'
|
||||
}
|
||||
},
|
||||
|
||||
toggleOn: {
|
||||
left: '20px',
|
||||
|
||||
'&.is-mobile': {
|
||||
left: '22px'
|
||||
}
|
||||
},
|
||||
|
||||
checkbox: {
|
||||
height: 0,
|
||||
width: 0
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const Switch = ({ id, checked, disabled, onChange }: SwitchProps) => {
|
||||
const styles = useStyles();
|
||||
const isMobile = isMobileBrowser();
|
||||
|
||||
const change = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
onChange(e.target.checked);
|
||||
}, []);
|
||||
|
||||
return (<label
|
||||
className = { clsx('toggle-container', styles.container, checked && styles.containerOn,
|
||||
isMobile && 'is-mobile', disabled && 'disabled') }>
|
||||
<input
|
||||
type = 'checkbox'
|
||||
{ ...(id ? { id } : {}) }
|
||||
checked = { checked }
|
||||
className = { styles.checkbox }
|
||||
disabled = { disabled }
|
||||
onChange = { change } />
|
||||
<div className = { clsx('toggle', styles.toggle, checked && styles.toggleOn, isMobile && 'is-mobile') } />
|
||||
</label>);
|
||||
};
|
||||
|
||||
export default Switch;
|
|
@ -1,14 +1,18 @@
|
|||
/* @flow */
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import React, { Component } from 'react';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { createE2EEEvent, sendAnalytics } from '../../analytics';
|
||||
// @ts-ignore
|
||||
import { translate } from '../../base/i18n';
|
||||
import { Switch } from '../../base/react';
|
||||
import { connect } from '../../base/redux';
|
||||
import { connect } from '../../base/redux/functions';
|
||||
import Switch from '../../base/ui/components/web/Switch';
|
||||
// @ts-ignore
|
||||
import { toggleE2EE } from '../actions';
|
||||
// @ts-ignore
|
||||
import { MAX_MODE } from '../constants';
|
||||
// @ts-ignore
|
||||
import { doesEveryoneSupportE2EE } from '../functions';
|
||||
|
||||
type Props = {
|
||||
|
@ -21,7 +25,7 @@ type Props = {
|
|||
/**
|
||||
* Custom e2ee labels.
|
||||
*/
|
||||
_e2eeLabels: Object,
|
||||
_e2eeLabels: any,
|
||||
|
||||
/**
|
||||
* Whether the switch is currently enabled or not.
|
||||
|
@ -69,7 +73,7 @@ class E2EESection extends Component<Props, State> {
|
|||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
static getDerivedStateFromProps(props: Props, state: Object) {
|
||||
static getDerivedStateFromProps(props: Props, state: State) {
|
||||
if (props._toggled !== state.toggled) {
|
||||
|
||||
return {
|
||||
|
@ -124,17 +128,15 @@ class E2EESection extends Component<Props, State> {
|
|||
{ label }
|
||||
</label>
|
||||
<Switch
|
||||
checked = { toggled }
|
||||
disabled = { !_enabled }
|
||||
id = 'e2ee-section-switch'
|
||||
onValueChange = { this._onToggle }
|
||||
value = { toggled } />
|
||||
onChange = { this._onToggle } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
_onToggle: () => void;
|
||||
|
||||
/**
|
||||
* Callback to be invoked when the user toggles E2EE on or off.
|
||||
*
|
||||
|
@ -160,11 +162,11 @@ class E2EESection extends Component<Props, State> {
|
|||
* @private
|
||||
* @returns {Props}
|
||||
*/
|
||||
function mapStateToProps(state) {
|
||||
function mapStateToProps(state: any) {
|
||||
const { enabled: e2eeEnabled, maxMode } = state['features/e2ee'];
|
||||
const { e2eeLabels } = state['features/base/config'];
|
||||
|
||||
let descriptionResource = '';
|
||||
let descriptionResource: string|undefined = '';
|
||||
|
||||
if (e2eeLabels) {
|
||||
// When e2eeLabels are present, the descriptionResouse is ignored.
|
|
@ -1,12 +1,15 @@
|
|||
// @flow
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
import React, { PureComponent } from 'react';
|
||||
|
||||
// @ts-ignore
|
||||
import { translate } from '../../../base/i18n';
|
||||
// @ts-ignore
|
||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||
import { Switch } from '../../../base/react';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { connect } from '../../../base/redux/functions';
|
||||
import Switch from '../../../base/ui/components/web/Switch';
|
||||
// @ts-ignore
|
||||
import { isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
||||
// @ts-ignore
|
||||
import { toggleLobbyMode } from '../../actions';
|
||||
|
||||
type Props = {
|
||||
|
@ -64,7 +67,7 @@ class LobbySection extends PureComponent<Props, State> {
|
|||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
static getDerivedStateFromProps(props: Props, state: Object) {
|
||||
static getDerivedStateFromProps(props: Props, state: State) {
|
||||
if (props._lobbyEnabled !== state.lobbyEnabled) {
|
||||
|
||||
return {
|
||||
|
@ -100,9 +103,9 @@ class LobbySection extends PureComponent<Props, State> {
|
|||
{ t('lobby.toggleLabel') }
|
||||
</label>
|
||||
<Switch
|
||||
checked = { this.state.lobbyEnabled }
|
||||
id = 'lobby-section-switch'
|
||||
onValueChange = { this._onToggleLobby }
|
||||
value = { this.state.lobbyEnabled } />
|
||||
onChange = { this._onToggleLobby } />
|
||||
</div>
|
||||
</div>
|
||||
<div className = 'separator-line' />
|
||||
|
@ -110,8 +113,6 @@ class LobbySection extends PureComponent<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
_onToggleLobby: () => void;
|
||||
|
||||
/**
|
||||
* Callback to be invoked when the user toggles the lobby feature on or off.
|
||||
*
|
||||
|
@ -134,14 +135,12 @@ class LobbySection extends PureComponent<Props, State> {
|
|||
* @param {Object} state - The Redux state.
|
||||
* @returns {Props}
|
||||
*/
|
||||
function mapStateToProps(state: Object): $Shape<Props> {
|
||||
function mapStateToProps(state: any): Partial<Props> {
|
||||
const { conference } = state['features/base/conference'];
|
||||
const { hideLobbyButton } = state['features/base/config'];
|
||||
|
||||
return {
|
||||
_lobbyEnabled: state['features/lobby'].lobbyEnabled,
|
||||
|
||||
// $FlowExpectedError
|
||||
_visible: conference?.isLobbySupported() && isLocalParticipantModerator(state)
|
||||
&& !hideLobbyButton && !isInBreakoutRoom(state)
|
||||
};
|
Loading…
Reference in New Issue