Skip to content

Commit

Permalink
Merge pull request #86 from graphql/integrate-nav-stack
Browse files Browse the repository at this point in the history
Integrate search results into Documentation Explorer navigation stack
  • Loading branch information
leebyron committed Feb 26, 2016
2 parents 5d1b464 + c0ce47f commit f7c1b5f
Showing 1 changed file with 79 additions and 42 deletions.
121 changes: 79 additions & 42 deletions src/components/DocExplorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,35 +50,46 @@ export class DocExplorer extends React.Component {
if (!isCurrentlyShown) {
navStack = navStack.concat([ typeOrField ]);
}

this.setState({ navStack });
}

// Public API
showSearch(searchItem) {
let navStack = this.state.navStack;
let lastEntry = navStack.length > 0 && navStack[navStack.length - 1];
if (!lastEntry) {
navStack = navStack.concat([ searchItem ]);
} else if (lastEntry.searchValue !== searchItem.searchValue) {
navStack = navStack.slice(0, -1).concat([ searchItem ]);
}

this.setState({ navStack });
}

constructor() {
super();

this.state = {
navStack: [],
searchValue: null
};
this.state = { navStack: [] };
}

_onToggleBtnClick = () => {
this.setState({ expanded: !this.state.expanded });
}

_onNavBackClick = () => {
this.setState({
navStack: this.state.navStack.slice(0, -1),
searchValue: null
});
this.setState({ navStack: this.state.navStack.slice(0, -1) });
}

_onClickTypeOrField = typeOrField => {
this.showDoc(typeOrField);
}

_onSearch = event => {
this.setState({ searchValue: event.target.value });
this.showSearch({
name: 'Search Results',
searchValue: event.target.value
});
}

shouldComponentUpdate(nextProps, nextState) {
Expand All @@ -93,36 +104,38 @@ export class DocExplorer extends React.Component {
var schema = this.props.schema;
var navStack = this.state.navStack;

var typeOrField;
var navItem;
if (navStack.length > 0) {
typeOrField = navStack[navStack.length - 1];
navItem = navStack[navStack.length - 1];
}

var title;
var content;
if (typeOrField) {
title = typeOrField.name;
content = isType(typeOrField) ?
<TypeDoc
key={typeOrField.name}
type={typeOrField}
onClickType={this._onClickTypeOrField}
onClickField={this._onClickTypeOrField}
/> :
<FieldDoc
key={typeOrField.name}
field={typeOrField}
onClickType={this._onClickTypeOrField}
/>;
} else if (this.state.searchValue) {
title = 'Search Results';
content =
<SearchDoc
searchValue={this.state.searchValue}
schema={schema}
onClickType={this._onClickTypeOrField}
onClickField={this._onClickTypeOrField}
/>;
if (navItem) {
if (navItem.name === 'Search Results') {
title = navItem.name;
content =
<SearchDoc
searchValue={navItem.searchValue}
schema={schema}
onClickType={this._onClickTypeOrField}
onClickField={this._onClickTypeOrField}
/>;
} else {
title = navItem.name;
content = isType(navItem) ?
<TypeDoc
key={navItem.name}
type={navItem}
onClickType={this._onClickTypeOrField}
onClickField={this._onClickTypeOrField}
/> :
<FieldDoc
key={navItem.name}
field={navItem}
onClickType={this._onClickTypeOrField}
/>;
}
} else if (schema) {
title = 'Documentation Explorer';
content =
Expand All @@ -146,6 +159,10 @@ export class DocExplorer extends React.Component {
</div>
);

const shouldSearchBoxAppear = content && (
content.type === SearchDoc || content.type === SchemaDoc
);

return (
<div className="doc-explorer">
<div className="doc-explorer-title-bar">
Expand All @@ -162,21 +179,41 @@ export class DocExplorer extends React.Component {
</div>
</div>
<div className="doc-explorer-contents">
{!typeOrField &&
<label className="search-box-outer">
<input className="search-box-input"
onKeyUp={event => this._onSearch(event)}
type="text"
placeholder="Search the schema ..." />
</label>
}
<SearchBox
isShown={shouldSearchBoxAppear}
onSearch={this._onSearch}
searchValue={navItem ? navItem.searchValue : ''}
/>
{this.props.schema ? content : spinnerDiv}
</div>
</div>
);
}
}

class SearchBox extends React.Component {
shouldComponentUpdate(nextProps) {
return nextProps.isShown !== this.props.isShown ||
nextProps.searchValue !== this.props.searchValue;
}

render() {
return (
<div>
{this.props.isShown &&
<label className="search-box-outer">
<input className="search-box-input"
onChange={event => this.props.onSearch(event)}
type="text"
value={this.props.searchValue}
placeholder="Search the schema ..." />
</label>
}
</div>
);
}
}

// Render Search Results
class SearchDoc extends React.Component {
shouldComponentUpdate(nextProps) {
Expand Down

0 comments on commit f7c1b5f

Please sign in to comment.