Update directory to use react-virtualized and update layout

fbshipit-source-id: d745d30
This commit is contained in:
Brent Vatne
2017-10-22 20:23:48 +00:00
committed by Exponent GitHub Bot
parent f6dff2bcdd
commit 50d19fde3e
6 changed files with 159 additions and 95 deletions
+2 -1
View File
@@ -11,7 +11,8 @@
"lodash": "^4.14.0",
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-native-vector-icons": "^4.0.0"
"react-native-vector-icons": "^4.0.0",
"react-virtualized": "^9.12.0"
},
"scripts": {
"start": "react-scripts start",
+32 -9
View File
@@ -58,13 +58,12 @@
}
.Header-Container {
background-color: #23527C;
background-color: #000;
padding: 10px 10px 10px 10px;
width: 100%;
}
.Header-Content {
margin: 0 auto;
width: 100%;
max-width: 1300px;
padding: 0px 10px;
@@ -78,13 +77,12 @@
}
.Search-Container {
background-color: #3E3E3E;
background-color: #3e3e3e;
padding: 10px 10px 10px 10px;
width: 100%;
}
.Search-Content {
margin: 0 auto;
width: 100%;
max-width: 1300px;
padding: 0px 10px;
@@ -92,7 +90,6 @@
}
.Search-Icon-Container {
}
.Search-Icon {
@@ -133,10 +130,8 @@
vertical-align: top;
width: 100px;
display: inline-block;
text-align: center;
background-color: rgba(0,0,0,0.02);
background-color: rgba(0, 0, 0, 0.02);
border-radius: 3px;
padding: 20px;
margin-right: 10px;
}
@@ -149,10 +144,38 @@
font-weight: normal;
opacity: 0.8;
margin: 10px 0 0 0;
display: inline-block;
}
.Result-Family-Name {
font-size: 14px;
font-weight: normal;
opacity: 0.6;
display: inline-block;
}
.Container {
max-width: 1300px;
margin: 0 auto;
padding: 10px 30px 30px 30px;
min-height: 100%;
min-width: 100%;
}
html,
body,
#root,
.App {
height: 100%;
overflow: hidden;
}
#root {
max-width: 800px;
margin: 0 auto;
box-shadow: 0px 10px 10px #ccc;
}
*:focus {
outline: none;
}
+21 -85
View File
@@ -2,29 +2,9 @@ import React, { Component } from 'react';
import './App.css';
import _ from 'lodash';
const IconFamilies = {
Entypo: require('react-native-vector-icons/glyphmaps/Entypo.json'),
EvilIcons: require('react-native-vector-icons/glyphmaps/EvilIcons.json'),
Feather: require('react-native-vector-icons/glyphmaps/Feather.json'),
FontAwesome: require('react-native-vector-icons/glyphmaps/FontAwesome.json'),
Foundation: require('react-native-vector-icons/glyphmaps/Foundation.json'),
Ionicons: require('react-native-vector-icons/glyphmaps/Ionicons.json'),
MaterialIcons: require('react-native-vector-icons/glyphmaps/MaterialIcons.json'),
MaterialCommunityIcons: require('react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json'),
SimpleLineIcons: require('react-native-vector-icons/glyphmaps/SimpleLineIcons.json'),
Octicons: require('react-native-vector-icons/glyphmaps/Octicons.json'),
Zocial: require('react-native-vector-icons/glyphmaps/Zocial.json'),
};
class Icon extends Component {
render() {
return (
<span style={{ fontFamily: this.props.family }} {...this.props}>
{String.fromCharCode(IconFamilies[this.props.family][this.props.name])}
</span>
);
}
}
import { IconsArray } from './IconConstants';
import Icon from './Icon';
import IconList from './IconList';
const HeaderBar = props => {
return (
@@ -45,6 +25,7 @@ class SearchBar extends Component {
<Icon family="FontAwesome" name="search" className="Search-Icon" />
<input
ref={input => (this._input = input)}
onChange={this._onChange}
placeholder="Search for an icon"
type="text"
className="Search-Input"
@@ -55,10 +36,14 @@ class SearchBar extends Component {
);
}
_onSubmit(e) {
_onChange = e => {
this.props.onSubmit(e.target.value);
};
_onSubmit = e => {
e.preventDefault();
this.props.onSubmit(this._input.value);
}
};
}
class App extends Component {
@@ -66,81 +51,32 @@ class App extends Component {
super(props);
this.state = {
matches: [],
searchText: '',
};
}
componentDidMount() {
this._onSubmit('');
}
render() {
const { searchText } = this.state;
const data = IconsArray.filter(icon => {
return (
icon.name.includes(searchText) ||
icon.family.toLowerCase().includes(searchText)
);
});
return (
<div className="App">
<HeaderBar />
<SearchBar onSubmit={this._onSubmit.bind(this)} />
<div className="Container">
{this.state.matches.map(this._renderMatch.bind(this))}
<IconList data={data} />
</div>
</div>
);
}
// {Object.keys(IconFamilies).map(familyName => this._renderFamily(familyName))}
_renderFamily(familyName) {
return (
<div>
{Object.keys(IconFamilies[familyName]).map(iconName =>
<Icon
key={iconName + familyName}
family={familyName}
name={iconName}
/>
)}
</div>
);
}
_onSubmit(text) {
const lcText = text.toLowerCase();
let matches = [];
_.forEach(IconFamilies, (icons, family) => {
let names = Object.keys(icons);
let results = names.filter(
name => name.toLowerCase().indexOf(lcText) >= 0
);
if (results.length) {
matches = [...matches, { family, names: results }];
}
});
this.setState({ matches });
}
_renderMatch(match) {
let { family, names } = match;
return (
<div className="Result-Row" key={family}>
<h2 className="Result-Title">
{family}
</h2>
<div className="Result-List">
{names.map(name => this._renderIcon(family, name))}
</div>
</div>
);
}
_renderIcon(family, name) {
return (
<div className="Result-Icon-Container" key={name}>
<Icon family={family} name={name} className="Result-Icon" />
<h4 className="Result-Icon-Name">
{name}
</h4>
</div>
);
this.setState({ searchText: text.toLowerCase() });
}
}
+14
View File
@@ -0,0 +1,14 @@
import React, { Component } from 'react';
import { IconFamilies } from './IconConstants';
export default class Icon extends Component {
render() {
return (
<span
style={{ fontFamily: this.props.family }}
className={this.props.className}>
{String.fromCharCode(IconFamilies[this.props.family][this.props.name])}
</span>
);
}
}
+31
View File
@@ -0,0 +1,31 @@
import _ from 'lodash';
export const IconFamilies = {
Entypo: require('react-native-vector-icons/glyphmaps/Entypo.json'),
EvilIcons: require('react-native-vector-icons/glyphmaps/EvilIcons.json'),
Feather: require('react-native-vector-icons/glyphmaps/Feather.json'),
FontAwesome: require('react-native-vector-icons/glyphmaps/FontAwesome.json'),
Foundation: require('react-native-vector-icons/glyphmaps/Foundation.json'),
Ionicons: require('react-native-vector-icons/glyphmaps/Ionicons.json'),
MaterialIcons: require('react-native-vector-icons/glyphmaps/MaterialIcons.json'),
MaterialCommunityIcons: require('react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json'),
SimpleLineIcons: require('react-native-vector-icons/glyphmaps/SimpleLineIcons.json'),
Octicons: require('react-native-vector-icons/glyphmaps/Octicons.json'),
Zocial: require('react-native-vector-icons/glyphmaps/Zocial.json'),
};
export const IconsArray = _.reduce(
Object.keys(IconFamilies),
(arr, family) => {
let icons = IconFamilies[family];
Object.keys(icons).forEach(iconName => {
arr.push({
name: iconName,
value: icons[iconName],
family,
});
});
return arr;
},
[]
);
+59
View File
@@ -0,0 +1,59 @@
import React from 'react';
import { AutoSizer, List } from 'react-virtualized';
import Icon from './Icon';
export default class IconList extends React.Component {
render() {
return (
<AutoSizer>
{({ height, width }) =>
<List
height={height}
width={width}
rowCount={this.props.data.length}
rowHeight={60}
rowRenderer={this._renderRow}
/>}
</AutoSizer>
);
}
_renderRow = ({
key, // Unique key within array of rows
index, // Index of row within collection
isScrolling, // The List is currently being scrolled
isVisible, // This row is visible within the List (eg it is not an overscanned row)
style, // Style object to be applied to row (to position it)
}) => {
const { family, name } = this.props.data[index];
return (
<div key={index} style={style} className="Result-Icon-Container">
<div
style={{
display: 'flex',
flex: 1,
flexDirection: 'row',
alignItems: 'center',
borderBottom: '1px solid #ccc',
paddingVertical: 5,
}}>
<div style={{ width: 80, textAlign: 'center' }}>
<Icon family={family} name={name} className="Result-Icon" />
</div>
<div style={{ flex: 1, maxWidth: 200 }}>
<h4 className="Result-Icon-Name">
{name}
</h4>
</div>
<div style={{ flex: 1 }}>
<h4 className="Result-Family-Name">
{family}
</h4>
</div>
</div>
</div>
);
};
}