From 4d043107b80e104c3a029acb405dd69a8371a9a8 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Sat, 3 Apr 2021 18:05:20 +0900 Subject: Make Completion as a React.FC --- src/console/components/Console.tsx | 8 -- src/console/components/console/Completion.tsx | 136 ++++++++++++-------------- src/console/components/console/Input.tsx | 60 +++++------- src/console/reducers/index.ts | 2 - 4 files changed, 87 insertions(+), 119 deletions(-) (limited to 'src') diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx index 18a6632..bb9aee7 100644 --- a/src/console/components/Console.tsx +++ b/src/console/components/Console.tsx @@ -28,15 +28,11 @@ interface DispatchProps { type Props = StateProps & DispatchProps; class Console extends React.Component { - private input: React.RefObject; - private commandLineParser: CommandLineParser = new CommandLineParser(); private consoleFrameClient = new ConsoleFrameClient(); constructor(props: Props) { super(props); - - this.input = React.createRef(); } onBlur() { @@ -167,7 +163,6 @@ class Console extends React.Component { select={this.props.select} /> { this.props.dispatch(consoleActions.setColorScheme()); window.focus(); - if (this.input.current) { - this.input.current.focus(); - } } private updateCompletions(text: string) { diff --git a/src/console/components/console/Completion.tsx b/src/console/components/console/Completion.tsx index 09ae278..ed271aa 100644 --- a/src/console/components/console/Completion.tsx +++ b/src/console/components/console/Completion.tsx @@ -19,97 +19,85 @@ interface Props { completions: Group[]; } -interface State { - viewOffset: number; - select: number; -} - -class Completion extends React.Component { - constructor(props: Props) { - super(props); - this.state = { viewOffset: 0, select: -1 }; - } +const Completion: React.FC = ({ select, size, completions }) => { + const [viewOffset, setViewOffset] = React.useState(0); + const [prevSelect, setPrevSelect] = React.useState(-1); - static getDerivedStateFromProps(nextProps: Props, prevState: State) { - if (prevState.select === nextProps.select) { - return null; + React.useEffect(() => { + if (select === prevSelect) { + return; } const viewSelect = (() => { let index = 0; - for (let i = 0; i < nextProps.completions.length; ++i) { + for (let i = 0; i < completions.length; ++i) { ++index; - const g = nextProps.completions[i]; - if (nextProps.select + i + 1 < index + g.items.length) { - return nextProps.select + i + 1; + const g = completions[i]; + if (select + i + 1 < index + g.items.length) { + return select + i + 1; } index += g.items.length; } return -1; })(); - let viewOffset = 0; - if (nextProps.select < 0) { - viewOffset = 0; - } else if (prevState.select < nextProps.select) { - viewOffset = Math.max( - prevState.viewOffset, - viewSelect - nextProps.size + 1 - ); - } else if (prevState.select > nextProps.select) { - viewOffset = Math.min(prevState.viewOffset, viewSelect); - } - return { viewOffset, select: nextProps.select }; - } + const nextViewOffset = (() => { + if (prevSelect < select) { + return Math.max(viewOffset, viewSelect - size + 1); + } else if (prevSelect > select) { + return Math.min(viewOffset, viewSelect); + } + return 0; + })(); + + setPrevSelect(select); + setViewOffset(nextViewOffset); + }, [select]); - render() { - let itemIndex = 0; - let viewIndex = 0; - const groups: Array = []; - const viewOffset = this.state.viewOffset; - const viewSize = this.props.size; + let itemIndex = 0; + let viewIndex = 0; + const groups: Array = []; - this.props.completions.forEach((group, groupIndex) => { - const items = []; - const title = ( - { + const items = []; + const title = ( + + ); + ++viewIndex; + for (const item of group.items) { + items.push( + ); ++viewIndex; - for (const item of group.items) { - items.push( - - ); - ++viewIndex; - ++itemIndex; - } - groups.push( -
- {title} -
    {items}
-
- ); - }); + ++itemIndex; + } + groups.push( +
+ {title} +
    {items}
+
+ ); + }); - return
{groups}
; - } -} + return
{groups}
; +}; export default Completion; diff --git a/src/console/components/console/Input.tsx b/src/console/components/console/Input.tsx index 448b096..bf48d75 100644 --- a/src/console/components/console/Input.tsx +++ b/src/console/components/console/Input.tsx @@ -26,42 +26,32 @@ interface Props { onChange: (e: React.ChangeEvent) => void; } -class Input extends React.Component { - private input: React.RefObject; - - constructor(props: Props) { - super(props); - - this.input = React.createRef(); - } - - focus() { - if (this.input.current) { - this.input.current.focus(); - } +const Input: React.FC = (props) => { + const input = React.useRef(null); + + React.useEffect(() => { + input?.current?.focus(); + }, []); + + let prompt = ""; + if (props.mode === "command") { + prompt = ":"; + } else if (props.mode === "find") { + prompt = "/"; } - render() { - let prompt = ""; - if (this.props.mode === "command") { - prompt = ":"; - } else if (this.props.mode === "find") { - prompt = "/"; - } - - return ( - - {prompt} - - - ); - } -} + return ( + + {prompt} + + + ); +}; export default Input; diff --git a/src/console/reducers/index.ts b/src/console/reducers/index.ts index 752dfd9..dbaf97d 100644 --- a/src/console/reducers/index.ts +++ b/src/console/reducers/index.ts @@ -11,7 +11,6 @@ export interface State { completionSource: string; completions: Completions; select: number; - viewIndex: number; colorscheme: ColorScheme; } @@ -23,7 +22,6 @@ const defaultState = { completionSource: "", completions: [], select: -1, - viewIndex: 0, colorscheme: ColorScheme.System, }; -- cgit v1.2.3