Skip to content

Instantly share code, notes, and snippets.

@adrianmcli
Created January 9, 2017 03:22
Show Gist options
  • Save adrianmcli/c75a8a548828813e6865a4a813c37d84 to your computer and use it in GitHub Desktop.
Save adrianmcli/c75a8a548828813e6865a4a813c37d84 to your computer and use it in GitHub Desktop.
A React component that tracks how long you've been typing in the textarea. There is also an indicator to show when you are typing.
import React from 'react';
import Rx from 'rxjs/Rx';
import { observeComponent, fromComponent } from 'observe-component/rxjs';
// Create the component with the listeners we want
const TextArea = observeComponent('onInput')('textarea');
export default class MyComponent extends React.Component {
constructor() {
super();
this.state = {
typing: false,
timer: 0,
};
}
componentDidMount() {
// Create stream for when user is typing
this.inputEvents$ = fromComponent(TextArea, 'onInput').share();
// Create stream for when user has been idle for 1 second
this.idle$ = this.inputEvents$.debounceTime(1000).share();
// helper stream for the clock stream
const countUntilIdle$ = Rx.Observable
.interval(1000)
.startWith('start counter')
.takeUntil(this.idle$);
// build clock stream
this.clock$ = this.inputEvents$
.exhaustMap(() => countUntilIdle$)
.scan(acc => acc + 1, 0);
// Subscribe to invoke the streams and handle the events
this.inputEvents$.subscribe(() => this.setState({ typing: true }));
this.idle$.subscribe(() => this.setState({ typing: false }));
this.clock$.subscribe(x => this.setState({ timer: x }));
}
render() {
return (
<div>
<div>User has been typing for: {this.state.timer} seconds</div>
<TextArea cols="30" rows="10" />
<div>{this.state.typing ? 'User is typing...' : 'User is idle'}</div>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment