Merge pull request #50 from desktop/sass

Sassy styles
This commit is contained in:
Josh Abernathy 2016-06-22 12:07:32 -04:00 committed by GitHub
commit 2cd3c321bf
19 changed files with 238 additions and 81 deletions

View file

@ -15,7 +15,7 @@
},
"description": "The People's Glorious GitHub Client",
"scripts": {
"test": "electron-mocha --renderer --require ts-node/register test/*.ts test/*.tsx",
"test": "cross-env TEST_ENV=1 electron-mocha --renderer --require ts-node/register test/*.ts test/*.tsx",
"postinstall": "typings install",
"start": "npm run build:dev && node script/start",
"compile:dev": "tsc && cross-env NODE_ENV=development webpack --config webpack.development.js",
@ -54,18 +54,24 @@
"babel-preset-stage-0": "^6.5.0",
"chai": "^3.5.0",
"cross-env": "^1.0.8",
"css-loader": "^0.23.1",
"electron-mocha": "2.1.0",
"electron-packager": "^7.0.1",
"electron-prebuilt": "1.1.3",
"electron-winstaller": "^2.3.0",
"express": "^4.13.4",
"extract-text-webpack-plugin": "^1.0.1",
"fs-extra": "^0.30.0",
"got": "^6.3.0",
"html-webpack-plugin": "^2.21.0",
"mocha": "^2.4.5",
"node-sass": "^3.7.0",
"react-addons-test-utils": "^15.0.2",
"react-transform-hmr": "^1.0.4",
"request": "^2.72.0",
"rimraf": "^2.5.2",
"sass-loader": "^3.2.0",
"style-loader": "^0.13.1",
"to-camel-case": "^1.0.0",
"ts-loader": "^0.8.2",
"ts-node": "^0.7.2",

View file

@ -1,4 +1,4 @@
#!/usr/bin/env node
#!/usr/bin/env node
'use strict'
@ -19,9 +19,6 @@ fs.removeSync(path.join(projectRoot, 'dist'))
console.log('Installing dependencies…')
installDependencies()
console.log('Copying `static`…')
fs.copySync(path.join(projectRoot, 'static'), path.join(buildRoot, 'static'), {clobber: true})
const options = {
platform: process.platform,
arch: 'x64',
@ -29,7 +26,7 @@ const options = {
'build-version': appPackage.version,
asar: false, // TODO: Probably wanna enable this down the road.
out: path.join(projectRoot, 'dist'),
icon: path.join(buildRoot, 'static', 'icon'),
icon: path.join(projectRoot, 'static', 'icon'),
dir: path.join(projectRoot, 'build'),
overwrite: true,
prune: false, // We only install production dependencies above.

View file

@ -18,18 +18,6 @@ interface AppProps {
usersStore: UsersStore
}
const AppStyle = {
display: 'flex',
flexDirection: 'column',
flexGrow: 1
}
const ContentStyle = {
display: 'flex',
flexDirection: 'row',
flexGrow: 1
}
export default class App extends React.Component<AppProps, AppState> {
private api: API
@ -76,19 +64,16 @@ export default class App extends React.Component<AppProps, AppState> {
}
return (
<div style={{
WebkitAppRegion: 'drag',
flexShrink: 0,
height: 20,
width: '100%'
}}/>
<div id='desktop-app-title-bar'>
<span className='app-title'>GitHub Desktop</span>
</div>
)
}
private renderApp() {
const selectedRepo = this.state.repos[this.state.selectedRow]
return (
<div style={ContentStyle}>
<div id='desktop-app-contents'>
<ReposList selectedRow={this.state.selectedRow}
onSelectionChanged={row => this.handleSelectionChanged(row)}
user={this.state.user}
@ -101,7 +86,7 @@ export default class App extends React.Component<AppProps, AppState> {
private renderNotLoggedIn() {
return (
<div style={ContentStyle}>
<div id='desktop-app-contents'>
<NotLoggedIn/>
</div>
)
@ -109,7 +94,7 @@ export default class App extends React.Component<AppProps, AppState> {
public render() {
return (
<div style={AppStyle}>
<div id='desktop-app-chrome'>
{this.renderTitlebar()}
{this.state.user ? this.renderApp() : this.renderNotLoggedIn()}
</div>

View file

@ -12,6 +12,12 @@ import tokenStore from './token-store'
const Octokat = require('octokat')
if (!process.env.TEST_ENV) {
/* This is the magic trigger for webpack to go compile
* our sass into css and inject it into the DOM. */
require('../styles/desktop.scss')
}
ipcRenderer.on('log', (event, msg) => {
console.log(msg)
})
@ -26,7 +32,9 @@ ipcRenderer.on('url-action', (event, msg) => {
const usersStore = new UsersStore(localStorage, tokenStore)
usersStore.loadFromStore()
ReactDOM.render(<App usersStore={usersStore}/>, document.getElementById('content'))
document.body.classList.add(`platform-${process.platform}`)
ReactDOM.render(<App usersStore={usersStore}/>, document.getElementById('desktop-app-container'))
async function addUserWithCode(code: string) {
try {

View file

@ -45,7 +45,7 @@ export default class AppWindow {
this.window.show()
})
this.window.loadURL(`file://${__dirname}/../../static/index.html`)
this.window.loadURL(`file://${__dirname}/../../index.html`)
}
public onClose(fn: () => void) {

View file

@ -2,19 +2,8 @@
<html>
<head>
<meta charset='UTF-8'>
<link rel='stylesheet' href='styles.css'>
</head>
<body>
<div id='content'></div>
<script>
var src = '../bundle.js'
if (process.env.NODE_ENV === 'development') {
src = 'http://localhost:3000/build/bundle.js'
}
var scriptTag = document.createElement('script')
scriptTag.src = src
document.head.appendChild(scriptTag)
</script>
<div id='desktop-app-container'></div>
</body>
</html>

View file

@ -1,40 +0,0 @@
* {
font-family: system, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Lucida Grande";
}
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
:not(input):not(textarea),
:not(input):not(textarea)::after,
:not(input):not(textarea)::before {
-webkit-user-select: none;
user-select: none;
cursor: default;
}
input, button, textarea, :focus {
outline: none;
}
img {
user-drag: none;
-webkit-user-drag: none;
user-select: none;
pointer-events: none;
}
#content {
display: flex;
height: 100%;
width: 100%;
}
/* https://css-tricks.com/cascading-svg-fill-color/ */
svg.octicon { fill: currentColor; }

79
styles/_globals.scss Normal file
View file

@ -0,0 +1,79 @@
// Globals
//
// This file is for things that have to apply globally, if your style
// doesn't fit into that description it probably belongs in ui/
// Reset the box-sizing, lifted from bootstrap reboot css, see:
// https://github.com/twbs/bootstrap/blob/bfc16c4a829ba596db28f5f42d7a3e429e6ea2e1/scss/_reboot.scss#L9
//
// Change from `box-sizing: content-box` to `border-box` so that when you add
// `padding` or `border`s to an element, the overall declared `width` does not
// change. For example, `width: 100px;` will always be `100px` despite the
// `border: 10px solid red;` and `padding: 20px;`.
//
// Credit: https://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
//
// Reset HTML, body, and more
//
// We never want the window to be scrollable, everything has to fit
// or be placed into a scrollable container.
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
html {
// Sets a specific default `font-size` for user with `rem` type scales.
font-size: $font-size-root;
}
body {
// Make the `body` use the `font-size-root`
font-family: $font-family-base;
font-size: $font-size-base;
line-height: $line-height-base;
// Go easy on the eyes and use something other than `#000` for text
color: $primary-text-color;
// By default, `<body>` has no `background-color` so we set one as a best practice.
background-color: $primary-background-color;
}
:not(input):not(textarea) {
&::after, &::before {
-webkit-user-select: none;
user-select: none;
cursor: default;
}
}
input, button, textarea, :focus {
outline: none;
}
img {
-webkit-user-drag: none;
user-select: none;
pointer-events: none;
}
#content {
display: flex;
height: 100%;
width: 100%;
}

1
styles/_mixins.scss Normal file
View file

@ -0,0 +1 @@
@import "mixins/platform";

3
styles/_type.scss Normal file
View file

@ -0,0 +1,3 @@
//
// Typography
//

2
styles/_ui.scss Normal file
View file

@ -0,0 +1,2 @@
@import "ui/app";
@import "ui/octicons";

24
styles/_variables.scss Normal file
View file

@ -0,0 +1,24 @@
// Variables
//
// This files contains variables accessible to all other scss files.
// Structure and naming copied largely from bootstrap, see
// https://github.com/twbs/bootstrap/blob/bfc16c4a829ba596db28f5f42d7a3e429e6ea2e1/scss/_variables.scss
// Colors
$primary-text-color: #5f717f;
$primary-background-color: #fff;
// Typography
//
// Font, line-height, and color for body text, headings, and more.
$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif !default;
$font-family-monospace: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
$font-family-base: $font-family-sans-serif;
// Pixel value used to responsively scale all typography. Applied to the `<html>` element.
$font-size-root: 16px;
$font-size-base: $font-size-root;
$line-height-base: 1.5;

6
styles/desktop.scss Normal file
View file

@ -0,0 +1,6 @@
@import "variables";
@import "mixins";
@import "globals";
@import "ui"

View file

@ -0,0 +1,27 @@
// A mixin which takes a content block that should only
// be applied when the current (real or emulated) operating
// system is windows
//
// This helper mixin is useful in so far that it allows us
// to keep platform specific styles next to cross-platform
// styles instead of splitting them out and possibly forgetting
// about them.
@mixin win32 {
body.platform-win32 & {
@content;
}
}
// A mixin which takes a content block that should only
// be applied when the current (real or emulated) operating
// system is macOS.
//
// This helper mixin is useful in so far that it allows us
// to keep platform specific styles next to cross-platform
// styles instead of splitting them out and possibly forgetting
// about them.
@mixin darwin {
body.platform-darwin & {
@content;
}
}

38
styles/ui/_app.scss Normal file
View file

@ -0,0 +1,38 @@
#desktop-app {
// This is just a dummy wrapper needed because react doesn't like
// being installed into <body>, see https://github.com/facebook/react/issues/3207
&-container {
width: 100%;
height: 100%;
overflow: hidden;
}
// The main react component div
&-chrome {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
// App title bar, currently only shown on macOS but will be used on
// Windows as well as soon as we enable frameless windows.
&-title-bar {
-webkit-app-region: drag;
-webkit-user-select: none;
flex-shrink: 0;
height: 20px;
width: 100%;
.app-title { display: none; }
}
// main non-window chrome wrapper
&-contents {
display: flex;
flex-direction: row;
flex-grow: 1
}
}

4
styles/ui/_octicons.scss Normal file
View file

@ -0,0 +1,4 @@
/* https://css-tricks.com/cascading-svg-fill-color/ */
svg.octicon {
fill: currentColor;
}

View file

@ -1,6 +1,7 @@
'use strict'
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: [
@ -17,6 +18,10 @@ module.exports = {
test: /\.tsx?$/,
loaders: ['babel', 'ts'],
include: path.join(__dirname, 'src')
},
{
test: /\.(jpe?g|png|gif|ico)$/,
loaders: ["file?name=[path][name].[ext]"]
}
]
},
@ -25,6 +30,7 @@ module.exports = {
packageMains: ['webpack', 'browser', 'web', 'browserify', ['jam', 'main'], 'main']
},
target: 'electron',
plugins: [new HtmlWebpackPlugin({ 'template': 'static/index.html' })],
externals: function (context, request, callback) {
try {
// Attempt to resolve the module via Node

View file

@ -18,6 +18,7 @@ const config = {
publicPath: 'http://localhost:3000/build/'
},
plugins: [
...common.plugins,
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
@ -30,6 +31,14 @@ const config = {
externals: common.externals
}
// This will cause the compiled CSS (and sourceMap) to be
// embedded within the compiled javascript bundle and added
// as a blob:// uri at runtime.
config.module.loaders.push({
test: /\.scss$/,
loaders: ["style", "css?sourceMap", "sass?sourceMap"]
});
config.target = webpackTargetElectronRenderer(config)
module.exports = config

View file

@ -4,12 +4,14 @@ const common = require('./webpack.common')
const webpack = require('webpack')
const webpackTargetElectronRenderer = require('webpack-target-electron-renderer')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = {
devtool: 'cheap-module-source-map',
entry: common.entry,
output: common.output,
plugins: [
...common.plugins,
new webpack.optimize.UglifyJsPlugin(),
new webpack.optimize.OccurrenceOrderPlugin(true),
new webpack.DefinePlugin({
@ -22,6 +24,17 @@ const config = {
externals: common.externals
}
// This will cause the compiled CSS to be output to a
// styles.css and a <link rel="stylesheet"> tag to be
// appended to the index.html HEAD at compile time
config.module.loaders.push({
test: /\.scss$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!sass-loader')
})
// Necessary to be able to use ExtractTextPlugin as a loader.
config.plugins.push(new ExtractTextPlugin('styles.css'))
config.target = webpackTargetElectronRenderer(config)
module.exports = config