mirror of https://github.com/vector-im/riot-web
Convert AddressSelector to TS
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>pull/21833/head
parent
8bbd91547d
commit
28871ee07d
|
@ -15,30 +15,36 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import React, { createRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import * as sdk from '../../../index';
|
import * as sdk from '../../../index';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { UserAddressType } from '../../../UserAddress';
|
|
||||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
onSelected: (index: number) => void;
|
||||||
|
|
||||||
|
// List of the addresses to display
|
||||||
|
addressList; // FIXME: UserAddressType should be an interface
|
||||||
|
// Whether to show the address on the address tiles
|
||||||
|
showAddress?: boolean;
|
||||||
|
truncateAt: number;
|
||||||
|
selected?: number;
|
||||||
|
|
||||||
|
// Element to put as a header on top of the list
|
||||||
|
header?: JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
selected: number;
|
||||||
|
hover: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.elements.AddressSelector")
|
@replaceableComponent("views.elements.AddressSelector")
|
||||||
export default class AddressSelector extends React.Component {
|
export default class AddressSelector extends React.Component<IProps, IState> {
|
||||||
static propTypes = {
|
private scrollElement = createRef<HTMLDivElement>();
|
||||||
onSelected: PropTypes.func.isRequired,
|
private addressListElement = createRef<HTMLDivElement>();
|
||||||
|
|
||||||
// List of the addresses to display
|
constructor(props: IProps) {
|
||||||
addressList: PropTypes.arrayOf(UserAddressType).isRequired,
|
|
||||||
// Whether to show the address on the address tiles
|
|
||||||
showAddress: PropTypes.bool,
|
|
||||||
truncateAt: PropTypes.number.isRequired,
|
|
||||||
selected: PropTypes.number,
|
|
||||||
|
|
||||||
// Element to put as a header on top of the list
|
|
||||||
header: PropTypes.node,
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -48,10 +54,10 @@ export default class AddressSelector extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
|
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
|
||||||
UNSAFE_componentWillReceiveProps(props) { // eslint-disable-line camelcase
|
UNSAFE_componentWillReceiveProps(props: IProps) { // eslint-disable-line
|
||||||
// Make sure the selected item isn't outside the list bounds
|
// Make sure the selected item isn't outside the list bounds
|
||||||
const selected = this.state.selected;
|
const selected = this.state.selected;
|
||||||
const maxSelected = this._maxSelected(props.addressList);
|
const maxSelected = this.maxSelected(props.addressList);
|
||||||
if (selected > maxSelected) {
|
if (selected > maxSelected) {
|
||||||
this.setState({ selected: maxSelected });
|
this.setState({ selected: maxSelected });
|
||||||
}
|
}
|
||||||
|
@ -60,13 +66,13 @@ export default class AddressSelector extends React.Component {
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
// As the user scrolls with the arrow keys keep the selected item
|
// As the user scrolls with the arrow keys keep the selected item
|
||||||
// at the top of the window.
|
// at the top of the window.
|
||||||
if (this.scrollElement && this.props.addressList.length > 0 && !this.state.hover) {
|
if (this.scrollElement.current && this.props.addressList.length > 0 && !this.state.hover) {
|
||||||
const elementHeight = this.addressListElement.getBoundingClientRect().height;
|
const elementHeight = this.addressListElement.current.getBoundingClientRect().height;
|
||||||
this.scrollElement.scrollTop = (this.state.selected * elementHeight) - elementHeight;
|
this.scrollElement.current.scrollTop = (this.state.selected * elementHeight) - elementHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moveSelectionTop = () => {
|
public moveSelectionTop = (): void => {
|
||||||
if (this.state.selected > 0) {
|
if (this.state.selected > 0) {
|
||||||
this.setState({
|
this.setState({
|
||||||
selected: 0,
|
selected: 0,
|
||||||
|
@ -75,7 +81,7 @@ export default class AddressSelector extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
moveSelectionUp = () => {
|
public moveSelectionUp = (): void => {
|
||||||
if (this.state.selected > 0) {
|
if (this.state.selected > 0) {
|
||||||
this.setState({
|
this.setState({
|
||||||
selected: this.state.selected - 1,
|
selected: this.state.selected - 1,
|
||||||
|
@ -84,8 +90,8 @@ export default class AddressSelector extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
moveSelectionDown = () => {
|
public moveSelectionDown = (): void => {
|
||||||
if (this.state.selected < this._maxSelected(this.props.addressList)) {
|
if (this.state.selected < this.maxSelected(this.props.addressList)) {
|
||||||
this.setState({
|
this.setState({
|
||||||
selected: this.state.selected + 1,
|
selected: this.state.selected + 1,
|
||||||
hover: false,
|
hover: false,
|
||||||
|
@ -93,26 +99,26 @@ export default class AddressSelector extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
chooseSelection = () => {
|
public chooseSelection = (): void => {
|
||||||
this.selectAddress(this.state.selected);
|
this.selectAddress(this.state.selected);
|
||||||
};
|
};
|
||||||
|
|
||||||
onClick = index => {
|
private onClick = (index: number): void => {
|
||||||
this.selectAddress(index);
|
this.selectAddress(index);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMouseEnter = index => {
|
private onMouseEnter = (index: number): void => {
|
||||||
this.setState({
|
this.setState({
|
||||||
selected: index,
|
selected: index,
|
||||||
hover: true,
|
hover: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onMouseLeave = () => {
|
private onMouseLeave = (): void => {
|
||||||
this.setState({ hover: false });
|
this.setState({ hover: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
selectAddress = index => {
|
private selectAddress = (index: number): void => {
|
||||||
// Only try to select an address if one exists
|
// Only try to select an address if one exists
|
||||||
if (this.props.addressList.length !== 0) {
|
if (this.props.addressList.length !== 0) {
|
||||||
this.props.onSelected(index);
|
this.props.onSelected(index);
|
||||||
|
@ -120,9 +126,9 @@ export default class AddressSelector extends React.Component {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
createAddressListTiles() {
|
private createAddressListTiles(): JSX.Element[] {
|
||||||
const AddressTile = sdk.getComponent("elements.AddressTile");
|
const AddressTile = sdk.getComponent("elements.AddressTile");
|
||||||
const maxSelected = this._maxSelected(this.props.addressList);
|
const maxSelected = this.maxSelected(this.props.addressList);
|
||||||
const addressList = [];
|
const addressList = [];
|
||||||
|
|
||||||
// Only create the address elements if there are address
|
// Only create the address elements if there are address
|
||||||
|
@ -143,7 +149,7 @@ export default class AddressSelector extends React.Component {
|
||||||
onMouseEnter={this.onMouseEnter.bind(this, i)}
|
onMouseEnter={this.onMouseEnter.bind(this, i)}
|
||||||
onMouseLeave={this.onMouseLeave}
|
onMouseLeave={this.onMouseLeave}
|
||||||
key={this.props.addressList[i].addressType + "/" + this.props.addressList[i].address}
|
key={this.props.addressList[i].addressType + "/" + this.props.addressList[i].address}
|
||||||
ref={(ref) => { this.addressListElement = ref; }}
|
ref={this.addressListElement}
|
||||||
>
|
>
|
||||||
<AddressTile
|
<AddressTile
|
||||||
address={this.props.addressList[i]}
|
address={this.props.addressList[i]}
|
||||||
|
@ -159,7 +165,7 @@ export default class AddressSelector extends React.Component {
|
||||||
return addressList;
|
return addressList;
|
||||||
}
|
}
|
||||||
|
|
||||||
_maxSelected(list) {
|
private maxSelected(list): number {
|
||||||
const listSize = list.length === 0 ? 0 : list.length - 1;
|
const listSize = list.length === 0 ? 0 : list.length - 1;
|
||||||
const maxSelected = listSize > (this.props.truncateAt - 1) ? (this.props.truncateAt - 1) : listSize;
|
const maxSelected = listSize > (this.props.truncateAt - 1) ? (this.props.truncateAt - 1) : listSize;
|
||||||
return maxSelected;
|
return maxSelected;
|
||||||
|
@ -172,7 +178,7 @@ export default class AddressSelector extends React.Component {
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes} ref={(ref) => {this.scrollElement = ref;}}>
|
<div className={classes} ref={this.scrollElement}>
|
||||||
{ this.props.header }
|
{ this.props.header }
|
||||||
{ this.createAddressListTiles() }
|
{ this.createAddressListTiles() }
|
||||||
</div>
|
</div>
|
Loading…
Reference in New Issue