diff --git a/.gitignore b/.gitignore index fe74398..4e6ce44 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules build .DS_Store +examples/glamor/bundle.js diff --git a/examples/glamor/app.js b/examples/glamor/app.js new file mode 100644 index 0000000..451ef45 --- /dev/null +++ b/examples/glamor/app.js @@ -0,0 +1,57 @@ +import { createElement } from 'glamor/react' // eslint-disable-line no-unused-vars +/** @jsx createElement */ + +import React from 'react' + +import { insertRule, merge, media } from 'glamor' +import 'glamor/reset' + +import { vars } from 'glamor/react' + +import { Tweet } from './tweet' +import data from './data.json' + + +@vars({ + accent: '#1da1f2', + animation: '#e81c4f', + border: '#e1e8ed', + primary: '#292f33', + secondary: '#8899a6' +}) +export class App extends React.Component { + styles = { + throwaways: [ `html { + color: ${this.props.vars.primary}; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.3125; + }`,`a { + text-decoration: none; + }`, `svg { + fill: currentColor; + height: 1.25em; + }`, `@media screen and (min-width: 360px) { + html { + font-size: 15px; + } + }`, `@media screen and (min-width: 600px) { + html { + font-size: 16px; + } + }` ].forEach(x => insertRule(x)), + container: merge({ + margin: '0 auto', + width: '100%' + }, media('screen and (min-width: 360px)', { + maxWidth: '400px' + }), media('screen and (min-width: 600px)', { + maxWidth: '600px' + })) + } + render() { + return
+ +
+ } +} diff --git a/examples/glamor/content.js b/examples/glamor/content.js new file mode 100644 index 0000000..cef3a67 --- /dev/null +++ b/examples/glamor/content.js @@ -0,0 +1,47 @@ +import { createElement } from 'glamor/react' // eslint-disable-line no-unused-vars +/** @jsx createElement */ + +import React, { PropTypes } from 'react' //eslint-disable-line no-unused-vars +import { merge, select } from 'glamor' +import { vars } from 'glamor/react' + + +@vars() +export class Content extends React.Component { + static propTypes = { + media: PropTypes.object, + text: PropTypes.string + } + styles = { + text: merge({ + fontSize: '1.25rem', + fontWeight: 300, + lineHeight: '1.5em', + margin: 0, + padding: '.65625rem 0 .98438rem' + }, select(' a', { + color: this.props.vars.accent + })), + media: { + borderRadius: '.35rem', + border: `1px solid ${this.props.vars.border}`, + display: 'block', + margin: '.65625rem 0 1.3125rem' + }, + image: { + display: 'block', + maxWidth: '100%' + } + } + render() { + let { media, text } = this.props + let styles = this.styles + return
+

+ + + +

+ } +} + diff --git a/examples/glamor/data.json b/examples/glamor/data.json new file mode 100644 index 0000000..4acc2f5 --- /dev/null +++ b/examples/glamor/data.json @@ -0,0 +1,26 @@ +{ + "created_at": "Tue Jul 19 19:17:50 +0000 2016", + "text": "\ud83d\udc4f Love love love this article by @chantastic. CSS-in-JS isn\u2019t a campaign against CSS! https:\/\/t.co\/P3QdkX88rs https:\/\/t.co\/vV3dJ4fens", + "entities": { + "user_mentions": [{ + "screen_name": "chantastic" + }], + "urls": [{ + "url": "https:\/\/t.co\/P3QdkX88rs", + "display_url": "medium.com\/learnreact\/sca\u2026" + }], + "media": [{ + "media_url_https": "https:\/\/pbs.twimg.com\/media\/CnwCr-nW8AAcQeZ.jpg", + "url": "https:\/\/t.co\/vV3dJ4fens", + "expanded_url": "http:\/\/twitter.com\/mxstbr\/status\/755481795206971392\/photo\/1" + }] + }, + "user": { + "name": "Max Stoiber", + "screen_name": "mxstbr", + "url": "https:\/\/t.co\/uAtI6h0Zng", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/763033229993574400/6frGyDyA_reasonably_small.jpg" + }, + "retweet_count": 32, + "favorite_count": 79 +} \ No newline at end of file diff --git a/examples/glamor/footer.js b/examples/glamor/footer.js new file mode 100644 index 0000000..06d2f04 --- /dev/null +++ b/examples/glamor/footer.js @@ -0,0 +1,127 @@ +import { createElement } from 'glamor/react' // eslint-disable-line no-unused-vars +/** @jsx createElement */ + +import React, { Component, PropTypes } from 'react' // eslint-disable-line no-unused-vars + +import { reply, retweet, like, more } from './svgs' + +import { keyframes, style } from 'glamor' +import { vars } from 'glamor/react' + + +let liked = keyframes({ + '50%': { + transform: 'scale(1.2)' + }, + '100%': { + transform: 'scale(1)' + } +}) + +@vars() +export class Footer extends Component { + static propTypes = { + createdAt: PropTypes.string, + favoriteCount: PropTypes.number, + retweetCount: PropTypes.number + } + state = { liked: false } + styles = { + date: { + paddingBottom: '.98438rem', + color: this.props.vars.secondary + }, + counters: { + borderTop: `1px solid ${this.props.vars.border}`, + padding: '.98438rem 0', + textTransform: 'uppercase' + }, + value: { + fontWeight: 700 + }, + label: { + color: this.props.vars.secondary, + fontSize: '.85rem' + }, + favorite: { + display: 'inline-block', + marginLeft: '1.96875rem' + }, + actions: { + alignItems: 'center', + borderBottom: `1px solid ${this.props.vars.border}`, + borderTop: `1px solid ${this.props.vars.border}`, + color: this.props.vars.secondary, + display: 'flex', + fontSize: '1.5rem', + height: '3.28125rem', + width: '100%' + }, + icon: { + display: 'flex', + flexGrow: 1, + justifyContent: 'center', + textAlign: 'center' + }, + button: { + display: 'flex', + flexGrow: 1, + justifyContent: 'center', + textAlign: 'center', + background: 'none', + border: 'none', + color: 'inherit', + cursor: 'pointer', + fontSize: 'inherit', + outline: 'none' + }, + liked: { + animation: `${liked} .25s`, + color: this.props.vars.animation + } + } + + handleClick = () => { + this.setState({ + liked: !this.state.liked + }) + } + + render() { + const { createdAt, favoriteCount, retweetCount } = this.props + const { liked } = this.state + let { styles } = this + + return ( +
+
{createdAt}
+
+ + {retweetCount} + Retweets + + + + {liked ? favoriteCount + 1 : favoriteCount} + + Likes + +
+
+
+ {reply()} +
+
+ {retweet()} +
+ +
+ {more()} +
+
+
+ ) + } +} diff --git a/examples/glamor/header.js b/examples/glamor/header.js new file mode 100644 index 0000000..92e95dc --- /dev/null +++ b/examples/glamor/header.js @@ -0,0 +1,75 @@ +import { createElement } from 'glamor/react' // eslint-disable-line no-unused-vars +/** @jsx createElement */ + + +import React, { PropTypes } from 'react' +import { merge, select, before } from 'glamor' +import { vars } from 'glamor/react' + +@vars() +export class Header extends React.Component { + static propTypes = { + name: PropTypes.string, + profileImageUrl: PropTypes.string, + screenName: PropTypes.string, + url: PropTypes.string + } + styles = { + header: { + display: 'flex', + padding: '1rem 0 .65625rem' + }, + + profile: { + flex: '1 0 0', + margin: '0 .3rem' + }, + + image: { + borderRadius: '.35rem', + display: 'block', + width: '100%' + }, + + user: { + flex: '7 0 0', + margin: '0 .3rem' + }, + + url: merge({ + display: 'inline-block', + marginTop: '-.15rem' + }, select(':hover .name', { + textDecoration: 'underline' + }), select(' .name' , { + color: this.props.vars.primary, + fontWeight: 700 + })), + + screenName: merge({ + color: this.props.vars.secondary + }, before({ + content: '"\\a"', + whiteSpace: 'pre' + })) + + } + render() { + let styles = this.styles + let { url, profileImageUrl, screenName, name } = this.props + return
+
+ + {name} + +
+
+ + {name} + @{screenName} + +
+
+ } +} + diff --git a/examples/glamor/index.html b/examples/glamor/index.html new file mode 100644 index 0000000..d982dc8 --- /dev/null +++ b/examples/glamor/index.html @@ -0,0 +1,10 @@ + + + + glamor tweet + + +
+ + + \ No newline at end of file diff --git a/examples/glamor/index.js b/examples/glamor/index.js new file mode 100644 index 0000000..812decb --- /dev/null +++ b/examples/glamor/index.js @@ -0,0 +1,7 @@ +import React from 'react' +import { render } from 'react-dom' +import { App } from './app' + +render(, document.getElementById('root')) + + diff --git a/examples/glamor/package.json b/examples/glamor/package.json new file mode 100644 index 0000000..c28bf20 --- /dev/null +++ b/examples/glamor/package.json @@ -0,0 +1,29 @@ +{ + "name": "glamor-tweet", + "version": "1.0.0", + "description": "css-in-js comparison example in glamor", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "browserify index.js -o bundle.js -t babelify -d" + }, + "author": "", + "license": "ISC", + "dependencies": { + "glamor": "^2.13.0", + "react": "^15.3.1", + "react-dom": "^15.3.1" + }, + "devDependencies": { + "babel-plugin-transform-decorators-legacy": "^1.3.4", + "babel-preset-es2015": "^6.14.0", + "babel-preset-react": "^6.11.1", + "babel-preset-stage-0": "^6.5.0", + "babelify": "^7.3.0", + "browserify": "^13.1.0" + }, + "babel": { + "presets": ["es2015", "stage-0", "react"], + "plugins": ["transform-decorators-legacy"] + } +} diff --git a/examples/glamor/svgs.js b/examples/glamor/svgs.js new file mode 100644 index 0000000..c536e0f --- /dev/null +++ b/examples/glamor/svgs.js @@ -0,0 +1,20 @@ +import { createElement } from '../../src/react' // eslint-disable-line no-unused-vars +/** @jsx createElement */ + +import React from 'react' + +export const like = css => + + + +export const more = + + + +export const reply = + + + +export const retweet = + + diff --git a/examples/glamor/tweet.js b/examples/glamor/tweet.js new file mode 100644 index 0000000..86486a2 --- /dev/null +++ b/examples/glamor/tweet.js @@ -0,0 +1,69 @@ +import { createElement } from 'glamor/react' // eslint-disable-line no-unused-vars +/** @jsx createElement */ + + +import React, { PropTypes } from 'react' + +import { Header } from './header' +import { Content } from './content' +import { Footer } from './footer' + +const transform = data => { + let text = data.text + + data.entities.user_mentions.forEach(userMention => { + text = text.replace( + `@${userMention.screen_name}`, + `@${userMention.screen_name}` + ) + }) + + data.entities.urls.forEach(url => { + text = text.replace( + url.url, + `${url.display_url}` + ) + }) + + data.entities.media.forEach(media => { + text = text.replace( + media.url, + '' + ) + }) + + return text.trim() +} + + +const styles = { + container: { + padding: '0 .6rem' + } +} + +export const Tweet = ({ data }) => ( +
+
+ +
+) + +Tweet.propTypes = { + data: PropTypes.object +} + +// export default Tweet