Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 36 additions & 32 deletions src/components/shared/Autocomplete.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
// @flow

import { Component, DOM as dom, createFactory } from "react";
import React, { Component } from "react";
import { filter } from "fuzzaldrin-plus";
import classnames from "classnames";
import { scrollList } from "../../utils/result-list";
import "./Autocomplete.css";

import _SearchInput from "./SearchInput";
const SearchInput = createFactory(_SearchInput);

import _ResultList from "./ResultList";
const ResultList = createFactory(_ResultList);
import SearchInput from "./SearchInput";
import ResultList from "./ResultList";

type State = {
inputValue: string,
Expand Down Expand Up @@ -101,18 +98,21 @@ export default class Autocomplete extends Component {
const { size } = this.props;

if (results.length) {
return ResultList({
const props = {
items: results,
selected: this.state.selectedIndex,
selectItem: this.props.selectItem,
close: this.props.close,
size,
ref: "resultList"
});
};

return <ResultList {...props} />;
} else if (this.state.inputValue && !results.length) {
return dom.div(
{ className: "no-result-msg absolute-center" },
L10N.getStr("sourceSearch.noResults2")
return (
<div className="no-result-msg absolute-center">
{L10N.getStr("sourceSearch.noResults2")}
</div>
);
}
}
Expand All @@ -125,27 +125,31 @@ export default class Autocomplete extends Component {
"sourceSearch.resultsSummary1",
searchResults.length
);
return dom.div(
{ className: classnames("autocomplete", { focused }) },
SearchInput({
query: this.state.inputValue,
count: searchResults.length,
placeholder: this.props.placeholder,
size,
showErrorEmoji: true,
summaryMsg,
onChange: e =>
this.setState({
inputValue: e.target.value,
selectedIndex: 0
}),
onFocus: () => this.setState({ focused: true }),
onBlur: () => this.setState({ focused: false }),
onKeyDown: this.onKeyDown,
handleClose: this.props.close
}),
children,
this.renderResults(searchResults)

const searchProps = {
query: this.state.inputValue,
count: searchResults.length,
placeholder: this.props.placeholder,
size,
showErrorEmoji: true,
summaryMsg,
onChange: e =>
this.setState({
inputValue: e.target.value,
selectedIndex: 0
}),
onFocus: () => this.setState({ focused: true }),
onBlur: () => this.setState({ focused: false }),
onKeyDown: this.onKeyDown,
handleClose: this.props.close
};

return (
<div className={classnames("autocomplete", { focused })}>
<SearchInput {...searchProps} />
{children}
{this.renderResults(searchResults)}
</div>
);
}
}
Expand Down
44 changes: 25 additions & 19 deletions src/components/shared/ResultList.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import { DOM as dom, Component } from "react";
import React, { Component } from "react";
import classnames from "classnames";

import "./ResultList.css";
Expand Down Expand Up @@ -35,29 +35,35 @@ export default class ResultList extends Component {

renderListItem(item: ResultListItem, index: number) {
const { selectItem, selected } = this.props;
return dom.li(
{
onClick: event => selectItem(event, item, index),
key: `${item.id}${item.value}${index}`,
ref: index,
title: item.value,
className: classnames("result-item", {
selected: index === selected
})
},
dom.div({ className: "title" }, item.title),
dom.div({ className: "subtitle" }, item.subtitle)
const props = {
onClick: event => selectItem(event, item, index),
key: `${item.id}${item.value}${index}`,
ref: index,
title: item.value,
className: classnames("result-item", {
selected: index === selected
})
};

return (
<li {...props}>
<div className="title">
{item.title}
</div>
<div className="subtitle">
{item.subtitle}
</div>
</li>
);
}

render() {
let { size, items } = this.props;
size = size || "";
return dom.ul(
{
className: `result-list ${size}`
},
items.map(this.renderListItem)

return (
<ul className={classnames("result-list", size)}>
{items.map(this.renderListItem)}
</ul>
);
}
}
Expand Down
80 changes: 43 additions & 37 deletions src/components/shared/SearchInput.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
import { DOM as dom, Component } from "react";
import React, { Component } from "react";
import { isEnabled } from "devtools-config";
import Svg from "./Svg";
import classnames from "classnames";
import CloseButton from "./Button/Close";
import "./SearchInput.css";

const arrowBtn = (onClick, type, className, tooltip) => {
return dom.button(
{
onClick,
type,
className,
title: tooltip,
key: type
},
Svg(type)
var props = {
onClick,
type,
className,
title: tooltip,
key: type
};

return (
<button {...props}>
{Svg(type)}
</button>
);
};

arrowBtn.displayName = "ArrowButton";

class SearchInput extends Component {
displayName: "SearchInput";
props: {
Expand Down Expand Up @@ -85,9 +90,10 @@ class SearchInput extends Component {
return;
}

return dom.div(
{ className: "search-nav-buttons" },
this.renderArrowButtons()
return (
<div className="search-nav-buttons">
{this.renderArrowButtons()}
</div>
);
}

Expand All @@ -105,31 +111,31 @@ class SearchInput extends Component {
size
} = this.props;

return dom.div(
{
className: `search-field ${size}`
},
this.renderSvg(),
dom.input({
className: classnames({
empty: this.shouldShowErrorEmoji()
}),
onChange,
onKeyDown,
onKeyUp,
onFocus,
onBlur,
placeholder,
value: query,
spellCheck: false,
ref: c => (this.$input = c)
const inputProps = {
className: classnames({
empty: this.shouldShowErrorEmoji()
}),
dom.div({ className: "summary" }, summaryMsg || ""),
this.renderNav(),
CloseButton({
handleClick: handleClose,
buttonClass: size
})
onChange,
onKeyDown,
onKeyUp,
onFocus,
onBlur,
placeholder,
value: query,
spellCheck: false,
ref: c => (this.$input = c)
};

return (
<div className={classnames("search-field", size)}>
{this.renderSvg()}
<input {...inputProps} />
<div className="summary">
{summaryMsg || ""}
</div>
{this.renderNav()}
<CloseButton handleClick={handleClose} buttonClass={size} />
</div>
);
}
}
Expand Down
14 changes: 8 additions & 6 deletions src/components/tests/__snapshots__/SymbolModal.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports[`SymbolModal should render 1`] = `
<div className=\\"modal entering\\" onClick={[Function]}>
<div className=\\"input-wrapper\\">
<SearchInput query=\\"\\" count={2} placeholder=\\"Search functions…\\" summaryMsg=\\"1 of 2 results\\" onChange={[Function]} onKeyUp={[Function]} handleNext={[Function]} handlePrev={[Function]} handleClose={[Function]} size=\\"\\" showErrorEmoji={true}>
<div className=\\"search-field \\">
<div className=\\"search-field\\">
<InlineSVG className=\\"magnifying-glass\\" src=\\"<svg></svg>\\" element=\\"i\\" raw={false}>
<i className=\\"magnifying-glass\\" src={{...}} dangerouslySetInnerHTML={{...}} />
</InlineSVG>
Expand All @@ -29,11 +29,13 @@ exports[`SymbolModal should render 1`] = `
</InlineSVG>
</button>
</div>
<div className=\\"close-btn\\" onClick={[Function]} title={[undefined]}>
<InlineSVG className=\\"close\\" src=\\"<svg></svg>\\" element=\\"i\\" raw={false}>
<i className=\\"close\\" src={{...}} dangerouslySetInnerHTML={{...}} />
</InlineSVG>
</div>
<CloseButton handleClick={[Function]} buttonClass=\\"\\">
<div className=\\"close-btn\\" onClick={[Function]} title={[undefined]}>
<InlineSVG className=\\"close\\" src=\\"<svg></svg>\\" element=\\"i\\" raw={false}>
<i className=\\"close\\" src={{...}} dangerouslySetInnerHTML={{...}} />
</InlineSVG>
</div>
</CloseButton>
</div>
</SearchInput>
</div>
Expand Down