mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-18 14:38:40 -09:00
Convert tab, tabs and searchBox to function components
This commit is contained in:
parent
a793a1d9a4
commit
6c8d0433d2
3 changed files with 360 additions and 391 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import React, {useCallback} from 'react';
|
||||
import React, {useCallback, useRef, useEffect} from 'react';
|
||||
import type {SearchBoxProps} from '../hyper';
|
||||
import {VscArrowUp} from '@react-icons/all-files/vsc/VscArrowUp';
|
||||
import {VscArrowDown} from '@react-icons/all-files/vsc/VscArrowDown';
|
||||
|
|
@ -82,35 +82,7 @@ const SearchButton = ({
|
|||
);
|
||||
};
|
||||
|
||||
class SearchBox extends React.PureComponent<SearchBoxProps> {
|
||||
searchTerm: string;
|
||||
input: HTMLInputElement | null = null;
|
||||
searchButtonColors: SearchButtonColors;
|
||||
|
||||
constructor(props: SearchBoxProps) {
|
||||
super(props);
|
||||
this.searchTerm = '';
|
||||
this.searchButtonColors = {
|
||||
backgroundColor: this.props.borderColor,
|
||||
selectionColor: this.props.selectionColor,
|
||||
foregroundColor: this.props.foregroundColor
|
||||
};
|
||||
}
|
||||
|
||||
handleChange = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
this.searchTerm = event.currentTarget.value;
|
||||
if (event.shiftKey && event.key === 'Enter') {
|
||||
this.props.prev(this.searchTerm);
|
||||
} else if (event.key === 'Enter') {
|
||||
this.props.next(this.searchTerm);
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
this.input?.focus();
|
||||
}
|
||||
|
||||
render() {
|
||||
const SearchBox = (props: SearchBoxProps) => {
|
||||
const {
|
||||
caseSensitive,
|
||||
wholeWord,
|
||||
|
|
@ -127,45 +99,47 @@ class SearchBox extends React.PureComponent<SearchBoxProps> {
|
|||
borderColor,
|
||||
selectionColor,
|
||||
font
|
||||
} = this.props;
|
||||
} = props;
|
||||
|
||||
const searchTermRef = useRef<string>('');
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(event: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
searchTermRef.current = event.currentTarget.value;
|
||||
if (event.shiftKey && event.key === 'Enter') {
|
||||
prev(searchTermRef.current);
|
||||
} else if (event.key === 'Enter') {
|
||||
next(searchTermRef.current);
|
||||
}
|
||||
},
|
||||
[prev, next]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
inputRef.current?.focus();
|
||||
}, [inputRef.current]);
|
||||
|
||||
const searchButtonColors: SearchButtonColors = {
|
||||
backgroundColor: borderColor,
|
||||
selectionColor,
|
||||
foregroundColor
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex-row search-container">
|
||||
<div className="flex-row search-box">
|
||||
<input
|
||||
className="search-input"
|
||||
type="text"
|
||||
onKeyDown={this.handleChange}
|
||||
ref={(input) => {
|
||||
this.input = input;
|
||||
}}
|
||||
placeholder="Search"
|
||||
></input>
|
||||
<input className="search-input" type="text" onKeyDown={handleChange} ref={inputRef} placeholder="Search" />
|
||||
|
||||
<SearchButton
|
||||
onClick={toggleCaseSensitive}
|
||||
active={caseSensitive}
|
||||
title="Match Case"
|
||||
{...this.searchButtonColors}
|
||||
>
|
||||
<SearchButton onClick={toggleCaseSensitive} active={caseSensitive} title="Match Case" {...searchButtonColors}>
|
||||
<VscCaseSensitive size="14px" />
|
||||
</SearchButton>
|
||||
|
||||
<SearchButton
|
||||
onClick={toggleWholeWord}
|
||||
active={wholeWord}
|
||||
title="Match Whole Word"
|
||||
{...this.searchButtonColors}
|
||||
>
|
||||
<SearchButton onClick={toggleWholeWord} active={wholeWord} title="Match Whole Word" {...searchButtonColors}>
|
||||
<VscWholeWord size="14px" />
|
||||
</SearchButton>
|
||||
|
||||
<SearchButton
|
||||
onClick={toggleRegex}
|
||||
active={regex}
|
||||
title="Use Regular Expression"
|
||||
{...this.searchButtonColors}
|
||||
>
|
||||
<SearchButton onClick={toggleRegex} active={regex} title="Use Regular Expression" {...searchButtonColors}>
|
||||
<VscRegex size="14px" />
|
||||
</SearchButton>
|
||||
</div>
|
||||
|
|
@ -180,24 +154,24 @@ class SearchBox extends React.PureComponent<SearchBoxProps> {
|
|||
|
||||
<div className="flex-row">
|
||||
<SearchButton
|
||||
onClick={() => prev(this.searchTerm)}
|
||||
onClick={() => prev(searchTermRef.current)}
|
||||
active={false}
|
||||
title="Previous Match"
|
||||
{...this.searchButtonColors}
|
||||
{...searchButtonColors}
|
||||
>
|
||||
<VscArrowUp size="14px" />
|
||||
</SearchButton>
|
||||
|
||||
<SearchButton
|
||||
onClick={() => next(this.searchTerm)}
|
||||
onClick={() => next(searchTermRef.current)}
|
||||
active={false}
|
||||
title="Next Match"
|
||||
{...this.searchButtonColors}
|
||||
{...searchButtonColors}
|
||||
>
|
||||
<VscArrowDown size="14px" />
|
||||
</SearchButton>
|
||||
|
||||
<SearchButton onClick={() => close()} active={false} title="Close" {...this.searchButtonColors}>
|
||||
<SearchButton onClick={close} active={false} title="Close" {...searchButtonColors}>
|
||||
<VscClose size="14px" />
|
||||
</SearchButton>
|
||||
</div>
|
||||
|
|
@ -254,7 +228,6 @@ class SearchBox extends React.PureComponent<SearchBoxProps> {
|
|||
</style>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default SearchBox;
|
||||
|
|
|
|||
|
|
@ -1,55 +1,50 @@
|
|||
import React from 'react';
|
||||
import type {TabProps} from '../hyper';
|
||||
|
||||
export default class Tab extends React.PureComponent<TabProps> {
|
||||
constructor(props: TabProps) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
handleClick = (event: React.MouseEvent) => {
|
||||
const Tab = (props: TabProps) => {
|
||||
const handleClick = (event: React.MouseEvent) => {
|
||||
const isLeftClick = event.nativeEvent.which === 1;
|
||||
|
||||
if (isLeftClick && !this.props.isActive) {
|
||||
this.props.onSelect();
|
||||
if (isLeftClick && !props.isActive) {
|
||||
props.onSelect();
|
||||
}
|
||||
};
|
||||
|
||||
handleMouseUp = (event: React.MouseEvent) => {
|
||||
const handleMouseUp = (event: React.MouseEvent) => {
|
||||
const isMiddleClick = event.nativeEvent.which === 2;
|
||||
|
||||
if (isMiddleClick) {
|
||||
this.props.onClose();
|
||||
props.onClose();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {isActive, isFirst, isLast, borderColor, hasActivity} = this.props;
|
||||
const {isActive, isFirst, isLast, borderColor, hasActivity} = props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<li
|
||||
onClick={this.props.onClick}
|
||||
onClick={props.onClick}
|
||||
style={{borderColor}}
|
||||
className={`tab_tab ${isFirst ? 'tab_first' : ''} ${isActive ? 'tab_active' : ''} ${
|
||||
isFirst && isActive ? 'tab_firstActive' : ''
|
||||
} ${hasActivity ? 'tab_hasActivity' : ''}`}
|
||||
>
|
||||
{this.props.customChildrenBefore}
|
||||
{props.customChildrenBefore}
|
||||
<span
|
||||
className={`tab_text ${isLast ? 'tab_textLast' : ''} ${isActive ? 'tab_textActive' : ''}`}
|
||||
onClick={this.handleClick}
|
||||
onMouseUp={this.handleMouseUp}
|
||||
onClick={handleClick}
|
||||
onMouseUp={handleMouseUp}
|
||||
>
|
||||
<span title={this.props.text} className="tab_textInner">
|
||||
{this.props.text}
|
||||
<span title={props.text} className="tab_textInner">
|
||||
{props.text}
|
||||
</span>
|
||||
</span>
|
||||
<i className="tab_icon" onClick={this.props.onClose}>
|
||||
<i className="tab_icon" onClick={props.onClose}>
|
||||
<svg className="tab_shape">
|
||||
<use xlinkHref="./renderer/assets/icons.svg#close-tab" />
|
||||
</svg>
|
||||
</i>
|
||||
{this.props.customChildren}
|
||||
{props.customChildren}
|
||||
</li>
|
||||
|
||||
<style jsx>{`
|
||||
|
|
@ -158,7 +153,8 @@ export default class Tab extends React.PureComponent<TabProps> {
|
|||
shape-rendering: crispEdges;
|
||||
}
|
||||
`}</style>
|
||||
</React.Fragment>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default Tab;
|
||||
|
|
|
|||
|
|
@ -9,22 +9,21 @@ import DropdownButton from './new-tab';
|
|||
const Tab = decorate(Tab_, 'Tab');
|
||||
const isMac = /Mac/.test(navigator.userAgent);
|
||||
|
||||
export default class Tabs extends React.PureComponent<TabsProps> {
|
||||
render() {
|
||||
const {tabs = [], borderColor, onChange, onClose, fullScreen} = this.props;
|
||||
const Tabs = (props: TabsProps) => {
|
||||
const {tabs = [], borderColor, onChange, onClose, fullScreen} = props;
|
||||
|
||||
const hide = !isMac && tabs.length === 1;
|
||||
|
||||
return (
|
||||
<nav className={`tabs_nav ${hide ? 'tabs_hiddenNav' : ''}`}>
|
||||
{this.props.customChildrenBefore}
|
||||
{props.customChildrenBefore}
|
||||
{tabs.length === 1 && isMac ? <div className="tabs_title">{tabs[0].title}</div> : null}
|
||||
{tabs.length > 1
|
||||
? [
|
||||
{tabs.length > 1 ? (
|
||||
<>
|
||||
<ul key="list" className={`tabs_list ${fullScreen && isMac ? 'tabs_fullScreen' : ''}`}>
|
||||
{tabs.map((tab, i) => {
|
||||
const {uid, title, isActive, hasActivity} = tab;
|
||||
const props = getTabProps(tab, this.props, {
|
||||
const tabProps = getTabProps(tab, props, {
|
||||
text: title === '' ? 'Shell' : title,
|
||||
isFirst: i === 0,
|
||||
isLast: tabs.length - 1 === i,
|
||||
|
|
@ -34,20 +33,20 @@ export default class Tabs extends React.PureComponent<TabsProps> {
|
|||
onSelect: onChange.bind(null, uid),
|
||||
onClose: onClose.bind(null, uid)
|
||||
});
|
||||
return <Tab key={`tab-${uid}`} {...props} />;
|
||||
return <Tab key={`tab-${uid}`} {...tabProps} />;
|
||||
})}
|
||||
</ul>,
|
||||
isMac && (
|
||||
</ul>
|
||||
{isMac && (
|
||||
<div
|
||||
key="shim"
|
||||
style={{borderColor}}
|
||||
className={`tabs_borderShim ${fullScreen ? 'tabs_borderShimUndo' : ''}`}
|
||||
/>
|
||||
)
|
||||
]
|
||||
: null}
|
||||
<DropdownButton {...this.props} tabsVisible={tabs.length > 1} />
|
||||
{this.props.customChildren}
|
||||
)}
|
||||
</>
|
||||
) : null}
|
||||
<DropdownButton {...props} tabsVisible={tabs.length > 1} />
|
||||
{props.customChildren}
|
||||
|
||||
<style jsx>{`
|
||||
.tabs_nav {
|
||||
|
|
@ -107,5 +106,6 @@ export default class Tabs extends React.PureComponent<TabsProps> {
|
|||
`}</style>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default Tabs;
|
||||
|
|
|
|||
Loading…
Reference in a new issue