Types on src/console

This commit is contained in:
Shin'ya Ueoka 2019-05-01 23:10:37 +09:00
parent 8cf8a0e625
commit 0452370df4
13 changed files with 206 additions and 105 deletions

View file

@ -1,7 +1,6 @@
import './console.scss';
import { connect } from 'react-redux';
import React from 'react';
import PropTypes from 'prop-types';
import Input from './console/Input';
import Completion from './console/Completion';
import Message from './console/Message';
@ -9,14 +8,29 @@ import * as consoleActions from '../../console/actions/console';
const COMPLETION_MAX_ITEMS = 33;
class Console extends React.Component {
interface Props {
mode?: string;
consoleText?: string;
messageText?: string;
children?: string;
}
class Console extends React.Component<Props> {
private input: HTMLInputElement | null;
constructor(props: Props) {
super(props);
this.input = null;
}
onBlur() {
if (this.props.mode === 'command' || this.props.mode === 'find') {
return this.props.dispatch(consoleActions.hideCommand());
}
}
doEnter(e) {
doEnter(e: React.KeyboardEvent<HTMLInputElement>) {
e.stopPropagation();
e.preventDefault();
@ -28,19 +42,19 @@ class Console extends React.Component {
}
}
selectNext(e) {
selectNext(e: React.KeyboardEvent<HTMLInputElement>) {
this.props.dispatch(consoleActions.completionNext());
e.stopPropagation();
e.preventDefault();
}
selectPrev(e) {
selectPrev(e: React.KeyboardEvent<HTMLInputElement>) {
this.props.dispatch(consoleActions.completionPrev());
e.stopPropagation();
e.preventDefault();
}
onKeyDown(e) {
onKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
if (e.keyCode === KeyboardEvent.DOM_VK_ESCAPE && e.ctrlKey) {
this.props.dispatch(consoleActions.hideCommand());
}
@ -81,7 +95,7 @@ class Console extends React.Component {
}
}
onChange(e) {
onChange(e: React.ChangeEvent<HTMLInputElement>) {
let text = e.target.value;
this.props.dispatch(consoleActions.setConsoleText(text));
if (this.props.mode === 'command') {
@ -90,7 +104,7 @@ class Console extends React.Component {
}
componentDidUpdate(prevProps) {
componentDidUpdate(prevProps: Props) {
if (!this.input) {
return;
}
@ -134,16 +148,11 @@ class Console extends React.Component {
focus() {
window.focus();
this.input.focus();
if (this.input) {
this.input.focus();
}
}
}
Console.propTypes = {
mode: PropTypes.string,
consoleText: PropTypes.string,
messageText: PropTypes.string,
children: PropTypes.string,
};
const mapStateToProps = state => state;
const mapStateToProps = (state: any) => state;
export default connect(mapStateToProps)(Console);

View file

@ -1,15 +1,36 @@
import React from 'react';
import PropTypes from 'prop-types';
import CompletionItem from './CompletionItem';
import CompletionTitle from './CompletionTitle';
class Completion extends React.Component {
constructor() {
super();
interface Item {
icon?: string;
caption?: string;
url?: string;
}
interface Group {
name: string;
items: Item[];
}
interface Props {
select: number;
size: number;
completions: Group[];
}
interface State {
viewOffset: number;
select: number;
}
class Completion extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { viewOffset: 0, select: -1 };
}
static getDerivedStateFromProps(nextProps, prevState) {
static getDerivedStateFromProps(nextProps: Props, prevState: State) {
if (prevState.select === nextProps.select) {
return null;
}
@ -24,6 +45,7 @@ class Completion extends React.Component {
}
index += g.items.length;
}
return -1;
})();
let viewOffset = 0;
@ -70,17 +92,4 @@ class Completion extends React.Component {
}
}
Completion.propTypes = {
select: PropTypes.number,
size: PropTypes.number,
completions: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.shape({
icon: PropTypes.string,
caption: PropTypes.string,
url: PropTypes.string,
})),
})),
};
export default Completion;

View file

@ -1,7 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';
const CompletionItem = (props) => {
interface Props {
highlight: boolean;
caption?: string;
url?: string;
icon?: string;
}
const CompletionItem = (props: Props) => {
let className = 'vimvixen-console-completion-item';
if (props.highlight) {
className += ' vimvixen-completion-selected';

View file

@ -1,14 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
const CompletionTitle = (props) => {
interface Props {
title: string;
}
const CompletionTitle = (props: Props) => {
return <li className='vimvixen-console-completion-title'>
{props.title}
</li>;
};
CompletionTitle.propTypes = {
title: PropTypes.string,
};
export default CompletionTitle;

View file

@ -1,9 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';
class Input extends React.Component {
interface Props {
mode: string;
value: string;
onBlur: (e: React.FocusEvent<Element>) => void;
onKeyDown: (e: React.KeyboardEvent<Element>) => void;
onChange: (e: React.ChangeEvent<Element>) => void;
}
class Input extends React.Component<Props> {
private input: HTMLInputElement | null;
constructor(props: Props) {
super(props);
this.input = null;
}
focus() {
this.input.focus();
if (this.input) {
this.input.focus();
}
}
render() {
@ -32,12 +49,4 @@ class Input extends React.Component {
}
}
Input.propTypes = {
mode: PropTypes.string,
value: PropTypes.string,
onBlur: PropTypes.func,
onKeyDown: PropTypes.func,
onChange: PropTypes.func,
};
export default Input;

View file

@ -1,7 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
const Message = (props) => {
interface Props {
mode: string;
children: string[];
}
const Message = (props: Props) => {
switch (props.mode) {
case 'error':
return (
@ -16,10 +20,7 @@ const Message = (props) => {
</p>
);
}
};
Message.propTypes = {
children: PropTypes.string,
return null;
};
export default Message;