initial React views

This commit is contained in:
Gil Barbara
2015-07-12 14:46:28 -03:00
parent 00de250bb0
commit 33eddbbf60
21 changed files with 413 additions and 295 deletions
+33 -24
View File
@@ -27,8 +27,12 @@
"Modernizr": false,
"module": false
},
"plugins": [
"react"
],
"rules": {
"strict": 0,
// Possible Errors
"comma-dangle": 2,
"no-cond-assign": 0,
@@ -60,14 +64,12 @@
}
],
"valid-typeof": 2,
// Best Practices
"block-scoped-var": 1,
"curly": 1,
"default-case": 1,
"dot-location": [
1,
"property"
],
"dot-location": [1, "property"],
"dot-notation": 1,
"eqeqeq": 1,
"guard-for-in": 1,
@@ -105,13 +107,8 @@
"radix": 2,
"vars-on-top": 0,
"wrap-iife": 2,
"yoda": [
2,
"never",
{
"exceptRange": true
}
],
"yoda": [2, "never", { "exceptRange": true }],
// Variables
"no-shadow": 1,
"no-undef": 1,
@@ -124,6 +121,7 @@
}
],
"no-use-before-define": 2,
// Stylistic Issues
"brace-style": [
1,
@@ -138,20 +136,11 @@
1,
"last"
],
"consistent-this": [
1,
"self"
],
"consistent-this": [1, "self"],
"eol-last": 1,
"key-spacing": 1,
"linebreak-style": [
1,
"unix"
],
"max-nested-callbacks": [
2,
4
],
"linebreak-style": [1, "unix"],
"max-nested-callbacks": [2, 4],
"new-cap": 2,
"new-parens": 2,
"newline-after-var": 0,
@@ -206,7 +195,27 @@
"space-infix-ops": 1,
"space-return-throw-case": 1,
"space-unary-ops": 1,
// Node
"no-mixed-requires": 0
"no-mixed-requires": 0,
// React
"react/jsx-quotes": [
1,
"double"
],
"react/jsx-no-undef": 1,
"react/jsx-sort-props": 0,
"react/jsx-sort-prop-types": 1,
"react/jsx-uses-react": 1,
"react/jsx-uses-vars": 1,
"react/no-did-mount-set-state": 0,
"react/no-did-update-set-state": 1,
"react/no-multi-comp": 1,
"react/no-unknown-property": 1,
"react/prop-types": 1,
"react/react-in-jsx-scope": 1,
"react/self-closing-comp": 1,
"react/wrap-multilines": 1
}
}
View File
@@ -4,38 +4,25 @@
<meta charset="UTF-8">
<title>SVG PORN</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0"/>
<meta name="description" content="A collection of svg logos for developers. {{meta}}"/>
<meta name="description" content="A collection of svg logos for developers."/>
<meta property="og:title" content="SVG Porn"/>
<meta property="og:url" content="http://svgporn.com/"/>
<meta property="og:description" content="A collection of svg logos for developers."/>
<meta property="og:image" content="http://svgporn.com/og-image.png"/>
<meta property="og:type" content="website"/>
<meta name="google-site-verification" content="hsF0-sA8sjC3wGoPZFBV8zHSJ4w8Suk7JYv-HSwE3B4" />
<!-- build:css(.tmp) main.css -->
<link rel="stylesheet" href=".tmp/main.css">
<!-- build:css(.tmp) assets/main.css -->
<link rel="stylesheet" href="assets/main.css">
<!-- endbuild -->
<!-- build:js(bower_components) assets/modernizr.min.js -->
<script src="/bower_components/modernizr/modernizr.js"></script>
<!-- endbuild -->
</head>
<body>
<div class="container">
<header>
<img src="svg-porn.svg" class="logo"/>
<h3>A collection of svg logos for developers.</h3>
</header>
<ul class="logos">
{{#each items}}
{{> item}}
{{/each}}
</ul>
<footer>
<iframe src="https://ghbtns.com/github-btn.html?user=gilbarbara&repo=logos&type=star&count=true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=gilbarbara&type=follow&count=true" frameborder="0" scrolling="0" width="160px" height="20px"></iframe>
</footer>
</div>
<!-- build:js(assets) main.js -->
<script src="scripts/main.js"></script>
<div id="react"></div>
<!-- build:js(.tmp) assets/main.min.js -->
<script src="assets/main.js"></script>
<!-- endbuild -->
<script>

Before

Width:  |  Height:  |  Size: 220 KiB

After

Width:  |  Height:  |  Size: 220 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

+48
View File
@@ -0,0 +1,48 @@
var React = require('react'),
Header = require('./components/Header'),
Footer = require('./components/Footer'),
Loader = require('./components/Loader'),
Logo = require('./components/Logo'),
json = require('../logos.json');
var App = React.createClass({
getInitialState () {
return {
logos: json.items
};
},
render () {
var state = this.state,
logos = [];
state.logos.forEach(function (d, i) {
d.files.forEach(function (f, j) {
logos.push(<Logo key={i + '-' + j} info={{
name: d.name,
shortname: d.shortname,
url: d.url,
image: f
}}/>);
});
});
return (
<div className="app">
<div className="container">
<Header logos={state.logos}/>
<main>
<ul className="logos">
{logos}
</ul>
</main>
<Footer />
</div>
</div>
);
}
});
module.exports = App;
+17
View File
@@ -0,0 +1,17 @@
var React = require('react/addons');
var Footer = React.createClass({
mixins: [React.addons.PureRenderMixin],
render: function () {
return (
<footer>
<iframe src="https://ghbtns.com/github-btn.html?user=gilbarbara&repo=logos&type=star&count=true" frameBorder="0" scrolling="0" width="110px" height="20px"></iframe>
<iframe src="https://ghbtns.com/github-btn.html?user=gilbarbara&type=follow&count=true" frameBorder="0" scrolling="0" width="160px" height="20px"></iframe>
</footer>
);
}
});
module.exports = Footer;
+24
View File
@@ -0,0 +1,24 @@
var React = require('react/addons');
var Header = React.createClass({
mixins: [React.addons.PureRenderMixin],
propTypes: {
logos: React.PropTypes.array.isRequired
},
render: function () {
var props = this.props;
return (
<header>
<img src="media/svg-porn.svg" className="logo"/>
<h3>A collection of svg logos for developers.</h3>
</header>
);
}
});
module.exports = Header;
+21
View File
@@ -0,0 +1,21 @@
var React = require('react');
var Loader = React.createClass({
render: function () {
return (
<div className="loader">
<svg className="loader__svg">
<circle className="loader__circle"
cx="50"
cy="50"
r="20"
fill="none"
strokeWidth="2"
/>
</svg>
</div>
);
}
});
module.exports = Loader;
+25
View File
@@ -0,0 +1,25 @@
var React = require('react/addons');
var Logo = React.createClass({
mixins: [React.addons.PureRenderMixin],
propTypes: {
info: React.PropTypes.object.isRequired
},
render: function () {
var info = this.props.info;
return (
<li>
<a href={info.url} target="_blank" className="logo-item">
<img src={'../logos/' + info.image} alt={info.name} className={info.shotname}/>
<span className="name">{info.name}</span>
</a>
</li>
);
}
});
module.exports = Logo;
+10 -6
View File
@@ -1,23 +1,27 @@
function showName (e) {
var React = require('react'),
App = require('./App');
var showName = (e) => {
var el = e.toElement;
el.parentNode.classList.add('visible');
}
};
function hideName (e) {
var hideName = (e) => {
var el = e.fromElement;
el.parentNode.classList.remove('visible');
}
};
function enableTips () {
var enableTips = () => {
var elems = document.querySelectorAll('.logo-item img');
for (var i = 0; i < elems.length; i++) {
elems[i].addEventListener("mouseenter", showName, false);
elems[i].addEventListener("mouseleave", hideName, false);
}
}
};
document.addEventListener('DOMContentLoaded', function () {
React.render(<App/>, document.getElementById('react'));
enableTips();
});
-172
View File
@@ -1,172 +0,0 @@
linters:
BangFormat:
enabled: true
space_before_bang: true
space_after_bang: false
BorderZero:
enabled: true
ColorKeyword:
enabled: true
ColorVariable:
enabled: false
Comment:
enabled: false
DebugStatement:
enabled: true
DeclarationOrder:
enabled: true
DuplicateProperty:
enabled: true
ElsePlacement:
enabled: true
style: new_line # or 'same_line'
EmptyLineBetweenBlocks:
enabled: true
ignore_single_line_blocks: false
EmptyRule:
enabled: true
FinalNewline:
enabled: true
present: true
HexLength:
enabled: true
style: short # or 'long'
HexNotation:
enabled: true
style: lowercase # or 'uppercase'
HexValidation:
enabled: true
IdSelector:
enabled: false
ImportantRule:
enabled: false
ImportPath:
enabled: true
leading_underscore: false
filename_extension: false
Indentation:
enabled: true
character: space # or 'tab'
width: 2
LeadingZero:
enabled: true
style: include_zero # or 'exclude_zero'
MergeableSelector:
enabled: true
force_nesting: true
NameFormat:
enabled: true
allow_leading_underscore: false
convention: hyphenated_lowercase # or 'BEM', or a regex pattern
NestingDepth:
enabled: true
max_depth: 6
PlaceholderInExtend:
enabled: true
PropertySortOrder:
enabled: true
ignore_unspecified: false
separate_groups: true
PropertySpelling:
enabled: true
extra_properties: []
QualifyingElement:
enabled: true
allow_element_with_attribute: false
allow_element_with_class: true
allow_element_with_id: false
SelectorDepth:
enabled: true
max_depth: 6
SelectorFormat:
enabled: true
convention: hyphenated_BEM # or 'hyphenated_lowercase', or 'snake_case', or 'camel_case', or a regex pattern
Shorthand:
enabled: true
SingleLinePerProperty:
enabled: true
allow_single_line_rule_sets: false
SingleLinePerSelector:
enabled: true
SpaceAfterComma:
enabled: true
SpaceAfterPropertyColon:
enabled: true
style: one_space # or 'no_space', or 'at_least_one_space', or 'aligned'
SpaceAfterPropertyName:
enabled: true
SpaceBeforeBrace:
enabled: true
style: space
allow_single_line_padding: false
SpaceBetweenParens:
enabled: true
spaces: 0
StringQuotes:
enabled: true
style: single_quotes # or double_quotes
TrailingSemicolon:
enabled: true
TrailingZero:
enabled: true
UnnecessaryMantissa:
enabled: true
UnnecessaryParentReference:
enabled: true
UrlFormat:
enabled: true
UrlQuotes:
enabled: true
VariableForProperty:
enabled: false
VendorPrefix:
enabled: true
identifier_list: base
ZeroUnit:
enabled: true
-6
View File
@@ -1,6 +0,0 @@
<li>
<a href="{{url}}" target="_blank" class="logo-item">
<img src="../logos/{{image}}" alt="{{name}}" class="{{shotname}}"/>
<span class="name">{{name}}</span>
</a>
</li>
+9
View File
@@ -0,0 +1,9 @@
{
"name": "logos",
"version": "0.2.0",
"dependencies": {
"jquery": "~2",
"modernizr": "~2",
"bootstrap-sass": "~3"
}
}
+184 -50
View File
@@ -1,12 +1,89 @@
var gulp = require('gulp'),
$ = require('gulp-load-plugins')(),
browserify = require('browserify'),
buffer = require('vinyl-buffer'),
browserSync = require('browser-sync'),
del = require('del'),
fs = require('fs'),
runSequence = require('run-sequence');
historyApiFallback = require('connect-history-api-fallback'),
merge = require('merge-stream'),
path = require('path'),
runSequence = require('run-sequence'),
source = require('vinyl-source-stream'),
watchify = require('watchify');
var isProduction = function () {
return process.env.NODE_ENV === 'production';
},
target = function () {
return (isProduction() ? 'dist' : '.tmp');
},
middleware = historyApiFallback({});
function watchifyTask (options) {
var bundler, rebundle, iteration = 0;
bundler = browserify({
entries: path.join(__dirname, '/app/scripts/main.js'),
insertGlobals: true,
cache: {},
//debug: options.watch,
packageCache: {},
fullPaths: options.watch, //options.watch
extensions: ['.jsx'],
transform: [
['babelify', { ignore: /bower_components/ }]
]
});
if (options.watch) {
bundler = watchify(bundler);
}
rebundle = function () {
var stream = bundler.bundle();
if (options.watch) {
stream.on('error', function (err) {
console.log(err);
});
}
stream
.pipe(source($.if(options.watch, 'main.js', 'main.min.js')))
.pipe(buffer())
.pipe($.if(!options.watch, $.uglify()))
.pipe(gulp.dest(target() + '/assets'))
.pipe($.tap(function () {
if (iteration === 0 && options.cb) {
options.cb();
}
iteration++;
}));
};
bundler.on('update', rebundle);
return rebundle();
}
// Scripts
gulp.task('scripts', function (cb) {
return watchifyTask({
watch: !isProduction(),
cb: cb
});
});
gulp.task('lint', function () {
return gulp.src('app/scripts/**/*')
.pipe($.eslint({
useEslintrc: true
}))
.pipe($.eslint.format())
.pipe($.eslint.failOnError());
});
gulp.task('styles', function () {
return gulp.src('assets/styles/main.scss')
return gulp.src('app/styles/main.scss')
.pipe($.plumber())
.pipe($.sass.sync({
precision: 4
@@ -15,103 +92,160 @@ gulp.task('styles', function () {
.pipe($.autoprefixer({
browsers: ['last 4 versions']
}))
.pipe(gulp.dest('.tmp'));
.pipe(gulp.dest('.tmp/assets'));
});
gulp.task('templates', function () {
var json = JSON.parse(fs.readFileSync('./assets/logos.json')),
templateData = {
items: []
},
meta = [];
json.items.forEach(function (d) {
meta.push(d.name);
d.files.forEach(function (f) {
templateData.items.push({
name: d.name,
shortname: d.shortname,
url: d.url,
image: f
});
});
});
templateData.meta = meta.join(', ');
templateData.count = json.items.length;
return gulp.src('assets/templates/index.handlebars')
.pipe($.compileHandlebars(templateData, {
batch: ['./assets/templates']
gulp.task('media', function () {
return gulp.src(['**/*.{jpg,gif,png}'], { cwd: 'app/media/' })
.pipe($.imagemin({
verbose: true
}, {
progressive: true,
interlaced: true
}))
.pipe($.rename('index.html'))
.pipe(gulp.dest('.tmp'));
.pipe(gulp.dest('dist/media'))
.pipe($.size({
title: 'Media'
}));
});
gulp.task('readme', function () {
var json = JSON.parse(fs.readFileSync('./assets/logos.json'));
var json = JSON.parse(fs.readFileSync('./app/logos.json'));
return gulp.src('assets/templates/README.handlebars')
return gulp.src('app/templates/README.handlebars')
.pipe($.compileHandlebars(json.items, {
batch: ['./assets/templates']
batch: ['./app/templates']
}))
.pipe($.rename('README.md'))
.pipe(gulp.dest('./'));
});
gulp.task('copy', function () {
return gulp.src('assets/media/**/*')
return gulp.src('app/media/**/*')
.pipe(gulp.dest('.tmp'));
});
gulp.task('bundle', function () {
var assets = $.useref.assets();
var html,
vendor,
extras,
media,
logos,
assets = $.useref.assets();
return gulp.src('.tmp/*.html')
html = gulp.src('app/*.html')
.pipe(assets)
.pipe($.if('*.css', $.cssmin()))
.pipe($.if('*.js', $.uglify()))
.pipe($.if('*.css', $.cssmin()))
.pipe(assets.restore())
.pipe($.useref())
.pipe($.replace('../logos/', ''))
.pipe(gulp.dest('.tmp'));
.pipe(gulp.dest('dist'))
.pipe($.size({
title: 'HTML'
}));
vendor = gulp.src('bower_components/modernizr/modernizr.js')
.pipe($.uglify())
.pipe($.rename('modernizr.min.js'))
.pipe(gulp.dest('dist/assets'))
.pipe($.size({
title: 'Vendor'
}));
extras = gulp.src([
'CNAME'
])
.pipe(gulp.dest('dist'))
.pipe($.size({
title: 'Extras'
}));
media = gulp.src([
'**/*.svg'
], { base: 'app/media' })
.pipe(gulp.dest('dist/media'))
.pipe($.size({
title: 'Media'
}));
logos = gulp.src([
'**/*.svg'
], { base: 'logos' })
.pipe(gulp.dest('dist/logos'))
.pipe($.size({
title: 'Logos'
}));
return merge(html, vendor, extras, media, logos);
});
gulp.task('sizer', function () {
return gulp.src(target() + '/**/*')
.pipe($.size({
title: 'Build',
gzip: true
}));
});
gulp.task('assets', function (cb) {
runSequence('styles', 'scripts', cb); //, 'fonts'
});
gulp.task('clean', function (cb) {
del(['.tmp/*'], cb);
del([target() + '/*'], cb);
});
gulp.task('serve', ['clean', 'templates', 'copy', 'styles'], function () {
gulp.task('gh-pages', function () {
return gulp.src(['dist/**/*'], {
dot: true
})
.pipe($.ghPages({
force: true
}));
});
gulp.task('serve', ['assets'], function () {
browserSync({
notify: false,
notify: true,
logPrefix: 'logos',
files: ['.tmp/*.html', '.tmp/*.css', 'logos', 'assets/scripts/*.js'],
files: ['app/*.html', '.tmp/assets/**/*.*', 'app/media/**/*', 'app/logos.json'],
server: {
baseDir: ['./', '.tmp', 'assets']
baseDir: ['.tmp', 'app', './'],
middleware: [middleware],
routes: {
'/bower_components': './bower_components'
}
}
});
gulp.watch('assets/styles/**/*.scss', function (e) {
gulp.watch('app/styles/**/*.scss', function (e) {
if (e.type === 'changed') {
gulp.start('styles');
}
});
gulp.watch(['assets/templates/**/*', 'assets/logos.json'], ['templates']);
gulp.watch('app/logos.json', ['readme']);
});
gulp.task('build', function (cb) {
runSequence('readme', 'templates', 'bundle', 'styles', cb);
process.env.NODE_ENV = 'production';
runSequence('clean', 'lint', 'readme', 'assets', ['media', 'bundle'], 'sizer', cb);
});
gulp.task('deploy', function (cb) {
runSequence('build', ['gh-pages'], cb);
});
gulp.task('deploy', ['build'], function () {
gulp.task('deploy-old', ['build'], function () {
return gulp.src([
'logos/*.svg',
'.tmp/*.html',
'.tmp/main.css',
'.tmp/main.js',
'assets/media/**/*',
'assets/CNAME',
'app/media/**/*',
'app/CNAME',
'*.md'
])
.pipe($.ghPages({
+26 -8
View File
@@ -1,6 +1,6 @@
{
"name": "logos",
"version": "0.1.0",
"version": "0.2.0",
"author": "Gil Barbara <gilbarbara@gmail.com>",
"repository": {
"type": "git",
@@ -9,23 +9,41 @@
"license": "CC0-1.0",
"homepage": "http://gilbarbara.github.io/logos/",
"devDependencies": {
"babelify": "^6.1.2",
"browser-sync": "^2.7",
"browserify": "^10.2.4",
"connect": "^3.4",
"connect-history-api-fallback": "^1.1.0",
"del": "^1.2",
"gulp": "^3.9",
"eslint": "^0.23.0",
"eslint-plugin-react": "^2.5.2",
"gulp": "^3.9.0",
"gulp-autoprefixer": "^2.3",
"gulp-cache": "^0.2",
"gulp-changed": "^1.2",
"gulp-compile-handlebars": "^0.5.0",
"gulp-cssmin": "^0.1",
"gulp-debug": "^2.0.1",
"gulp-gh-pages": "^0.5",
"gulp-eslint": "^0.14",
"gulp-filter": "^2.0",
"gulp-flatten": "0.0.4",
"gulp-gh-pages": "^0.5.2",
"gulp-if": "^1.2",
"gulp-imagemin": "^2.2",
"gulp-load-plugins": "^0.10",
"gulp-plumber": "^1.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5",
"gulp-rename": "^1.2",
"gulp-sass": "^2.0",
"gulp-uglify": "^1.2.0",
"gulp-size": "^1.2",
"gulp-tap": "^0.1.3",
"gulp-uglify": "^1.2",
"gulp-useref": "^1.2",
"run-sequence": "^1.1.1"
"gulp-util": "^3.0",
"merge-stream": "^0.1",
"react": "^0.13.3",
"run-sequence": "^1.1",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0",
"watchify": "^3.2.2"
},
"engines": {
"node": ">=0.10.0"