mirror of
https://github.com/quine-global/hyper.git
synced 2026-01-16 13:48:41 -09:00
port term-group component to ts
This commit is contained in:
parent
579d0877f0
commit
57fd125b5c
3 changed files with 83 additions and 25 deletions
|
|
@ -4,35 +4,42 @@ import {decorate, getTermProps, getTermGroupProps} from '../utils/plugins';
|
||||||
import {resizeTermGroup} from '../actions/term-groups';
|
import {resizeTermGroup} from '../actions/term-groups';
|
||||||
import Term_ from './term';
|
import Term_ from './term';
|
||||||
import SplitPane_ from './split-pane';
|
import SplitPane_ from './split-pane';
|
||||||
|
import {HyperState, HyperDispatch, TermGroupProps, TermGroupOwnProps} from '../hyper';
|
||||||
|
|
||||||
const Term = decorate(Term_, 'Term');
|
const Term = decorate(Term_, 'Term');
|
||||||
const SplitPane = decorate(SplitPane_, 'SplitPane');
|
const SplitPane = decorate(SplitPane_, 'SplitPane');
|
||||||
|
|
||||||
class TermGroup_ extends React.PureComponent {
|
// eslint-disable-next-line @typescript-eslint/class-name-casing
|
||||||
constructor(props, context) {
|
class TermGroup_ extends React.PureComponent<TermGroupProps> {
|
||||||
|
bound: WeakMap<(uid: string, ...args: any[]) => any, Record<string, (...args: any[]) => any>>;
|
||||||
|
term?: Term_;
|
||||||
|
constructor(props: TermGroupProps, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.bound = new WeakMap();
|
this.bound = new WeakMap();
|
||||||
this.termRefs = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(fn, thisObj, uid) {
|
bind<T extends (uid: string, ...args: any) => any>(
|
||||||
|
fn: T,
|
||||||
|
thisObj: any,
|
||||||
|
uid: string
|
||||||
|
): (...args: T extends (uid: string, ...args: infer I) => any ? I : never) => ReturnType<T> {
|
||||||
if (!this.bound.has(fn)) {
|
if (!this.bound.has(fn)) {
|
||||||
this.bound.set(fn, {});
|
this.bound.set(fn, {});
|
||||||
}
|
}
|
||||||
const map = this.bound.get(fn);
|
const map = this.bound.get(fn)!;
|
||||||
if (!map[uid]) {
|
if (!map[uid]) {
|
||||||
map[uid] = fn.bind(thisObj, uid);
|
map[uid] = fn.bind(thisObj, uid);
|
||||||
}
|
}
|
||||||
return map[uid];
|
return map[uid];
|
||||||
}
|
}
|
||||||
|
|
||||||
renderSplit(groups) {
|
renderSplit(groups: JSX.Element[]) {
|
||||||
const [first, ...rest] = groups;
|
const [first, ...rest] = groups;
|
||||||
if (rest.length === 0) {
|
if (rest.length === 0) {
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
const direction = this.props.termGroup.direction.toLowerCase();
|
const direction = this.props.termGroup.direction!.toLowerCase() as 'horizontal' | 'vertical';
|
||||||
return (
|
return (
|
||||||
<SplitPane
|
<SplitPane
|
||||||
direction={direction}
|
direction={direction}
|
||||||
|
|
@ -45,12 +52,12 @@ class TermGroup_ extends React.PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
onTermRef = (uid, term) => {
|
onTermRef = (uid: string, term: Term_) => {
|
||||||
this.term = term;
|
this.term = term;
|
||||||
this.props.ref_(uid, term);
|
this.props.ref_(uid, term);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderTerm(uid) {
|
renderTerm(uid: string) {
|
||||||
const session = this.props.sessions[uid];
|
const session = this.props.sessions[uid];
|
||||||
const termRef = this.props.terms[uid];
|
const termRef = this.props.terms[uid];
|
||||||
const props = getTermProps(uid, this.props, {
|
const props = getTermProps(uid, this.props, {
|
||||||
|
|
@ -112,7 +119,7 @@ class TermGroup_ extends React.PureComponent {
|
||||||
return this.renderTerm(termGroup.sessionUid);
|
return this.renderTerm(termGroup.sessionUid);
|
||||||
}
|
}
|
||||||
|
|
||||||
const groups = childGroups.map(child => {
|
const groups = childGroups.asMutable().map(child => {
|
||||||
const props = getTermGroupProps(
|
const props = getTermGroupProps(
|
||||||
child.uid,
|
child.uid,
|
||||||
this.props.parentProps,
|
this.props.parentProps,
|
||||||
|
|
@ -126,19 +133,20 @@ class TermGroup_ extends React.PureComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const TermGroup = connect(
|
const mapStateToProps = (state: HyperState, ownProps: TermGroupOwnProps) => ({
|
||||||
(state, ownProps) => ({
|
childGroups: ownProps.termGroup.children.map(uid => state.termGroups.termGroups[uid])
|
||||||
childGroups: ownProps.termGroup.children.map(uid => state.termGroups.termGroups[uid])
|
});
|
||||||
}),
|
|
||||||
(dispatch, ownProps) => ({
|
const mapDispatchToProps = (dispatch: HyperDispatch, ownProps: TermGroupOwnProps) => ({
|
||||||
onTermGroupResize(splitSizes) {
|
onTermGroupResize(splitSizes: number[]) {
|
||||||
dispatch(resizeTermGroup(ownProps.termGroup.uid, splitSizes));
|
dispatch(resizeTermGroup(ownProps.termGroup.uid, splitSizes));
|
||||||
}
|
}
|
||||||
}),
|
});
|
||||||
null,
|
|
||||||
{forwardRef: true}
|
const TermGroup = connect(mapStateToProps, mapDispatchToProps, null, {forwardRef: true})(TermGroup_);
|
||||||
)(TermGroup_);
|
|
||||||
|
|
||||||
const DecoratedTermGroup = decorate(TermGroup, 'TermGroup');
|
const DecoratedTermGroup = decorate(TermGroup, 'TermGroup');
|
||||||
|
|
||||||
export default TermGroup;
|
export default TermGroup;
|
||||||
|
|
||||||
|
export type TermGroupConnectedProps = ReturnType<typeof mapStateToProps> & ReturnType<typeof mapDispatchToProps>;
|
||||||
50
lib/hyper.d.ts
vendored
50
lib/hyper.d.ts
vendored
|
|
@ -262,3 +262,53 @@ export type SplitPaneProps = {
|
||||||
onResize: Function;
|
onResize: Function;
|
||||||
sizes?: Immutable<number[]> | null;
|
sizes?: Immutable<number[]> | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
import Term from './components/term';
|
||||||
|
|
||||||
|
export type TermGroupOwnProps = {
|
||||||
|
cursorAccentColor?: string;
|
||||||
|
fontSmoothing?: string;
|
||||||
|
parentProps: TermsProps;
|
||||||
|
ref_: (uid: string, term: Term) => void;
|
||||||
|
termGroup: Immutable<ITermGroup>;
|
||||||
|
terms: Record<string, Term | null>;
|
||||||
|
} & Pick<
|
||||||
|
TermsProps,
|
||||||
|
| 'activeSession'
|
||||||
|
| 'backgroundColor'
|
||||||
|
| 'bell'
|
||||||
|
| 'bellSound'
|
||||||
|
| 'bellSoundURL'
|
||||||
|
| 'borderColor'
|
||||||
|
| 'colors'
|
||||||
|
| 'copyOnSelect'
|
||||||
|
| 'cursorBlink'
|
||||||
|
| 'cursorColor'
|
||||||
|
| 'cursorShape'
|
||||||
|
| 'disableLigatures'
|
||||||
|
| 'fontFamily'
|
||||||
|
| 'fontSize'
|
||||||
|
| 'fontWeight'
|
||||||
|
| 'fontWeightBold'
|
||||||
|
| 'foregroundColor'
|
||||||
|
| 'letterSpacing'
|
||||||
|
| 'lineHeight'
|
||||||
|
| 'macOptionSelectionMode'
|
||||||
|
| 'modifierKeys'
|
||||||
|
| 'onActive'
|
||||||
|
| 'onContextMenu'
|
||||||
|
| 'onData'
|
||||||
|
| 'onResize'
|
||||||
|
| 'onTitle'
|
||||||
|
| 'padding'
|
||||||
|
| 'quickEdit'
|
||||||
|
| 'scrollback'
|
||||||
|
| 'selectionColor'
|
||||||
|
| 'sessions'
|
||||||
|
| 'toggleSearch'
|
||||||
|
| 'uiFontFamily'
|
||||||
|
| 'webGLRenderer'
|
||||||
|
>;
|
||||||
|
|
||||||
|
import {TermGroupConnectedProps} from './components/term-group';
|
||||||
|
export type TermGroupProps = TermGroupConnectedProps & TermGroupOwnProps;
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ let reducersDecorators: {
|
||||||
};
|
};
|
||||||
|
|
||||||
// expose decorated component instance to the higher-order components
|
// expose decorated component instance to the higher-order components
|
||||||
function exposeDecorated<P extends any>(Component_: React.ComponentClass<P>): React.ComponentClass<P, {}> {
|
function exposeDecorated<P extends any>(Component_: React.ComponentType<P>): React.ComponentClass<P, {}> {
|
||||||
return class DecoratedComponent extends React.Component<P> {
|
return class DecoratedComponent extends React.Component<P> {
|
||||||
constructor(props: P, context: any) {
|
constructor(props: P, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
@ -72,7 +72,7 @@ function exposeDecorated<P extends any>(Component_: React.ComponentClass<P>): Re
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDecorated<P>(parent: React.ComponentClass<P>, name: string): React.ComponentClass<P> {
|
function getDecorated<P>(parent: React.ComponentType<P>, name: string): React.ComponentClass<P> {
|
||||||
if (!decorated[name]) {
|
if (!decorated[name]) {
|
||||||
let class_ = exposeDecorated(parent);
|
let class_ = exposeDecorated(parent);
|
||||||
(class_ as any).displayName = `_exposeDecorated(${name})`;
|
(class_ as any).displayName = `_exposeDecorated(${name})`;
|
||||||
|
|
@ -118,7 +118,7 @@ function getDecorated<P>(parent: React.ComponentClass<P>, name: string): React.C
|
||||||
// that wraps with the higher-order components
|
// that wraps with the higher-order components
|
||||||
// exposed by plugins
|
// exposed by plugins
|
||||||
export function decorate<P>(
|
export function decorate<P>(
|
||||||
Component_: React.ComponentClass<P>,
|
Component_: React.ComponentType<P>,
|
||||||
name: string
|
name: string
|
||||||
): React.ComponentClass<P, {hasError: boolean}> {
|
): React.ComponentClass<P, {hasError: boolean}> {
|
||||||
return class DecoratedComponent extends React.Component<P, {hasError: boolean}> {
|
return class DecoratedComponent extends React.Component<P, {hasError: boolean}> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue