1
0
mirror of https://github.com/kremalicious/blowfish.git synced 2024-12-28 15:47:52 +01:00

Merge pull request #19 from kremalicious/feature/css-modules

support for scss modules
This commit is contained in:
Matthias Kretschmann 2019-06-05 00:17:55 +02:00 committed by GitHub
commit a5337a5553
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 175 additions and 120 deletions

View File

@ -9,5 +9,5 @@ insert_final_newline = true
charset = utf-8 charset = utf-8
trim_trailing_whitespace = true trim_trailing_whitespace = true
[*.css] [*.css,*.scss]
indent_size = 4 indent_size = 4

View File

@ -1,6 +1,7 @@
{ {
"extends": [ "extends": [
"stylelint-config-standard", "stylelint-config-standard",
"stylelint-config-css-modules",
"./node_modules/prettier-stylelint/config.js" "./node_modules/prettier-stylelint/config.js"
], ],
"rules": { "rules": {

View File

@ -7,7 +7,7 @@
"scripts": { "scripts": {
"test": "eslint ./src/**/*.{js,jsx} && stylelint ./src/**/*.css", "test": "eslint ./src/**/*.{js,jsx} && stylelint ./src/**/*.css",
"start": "webpack-dev-server --hot --host 0.0.0.0 --config=./webpack.dev.config.js", "start": "webpack-dev-server --hot --host 0.0.0.0 --config=./webpack.dev.config.js",
"build": "webpack --mode production --config webpack.common.config.js", "build": "cross-env NODE_ENV=production webpack --config webpack.common.config.js",
"package": "electron-builder build -mwl && open ./dist", "package": "electron-builder build -mwl && open ./dist",
"dist": "rm -rf {dist,build}/ && npm run build && npm run package", "dist": "rm -rf {dist,build}/ && npm run build && npm run package",
"release": "release-it --non-interactive" "release": "release-it --non-interactive"
@ -38,6 +38,7 @@
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
"copy-webpack-plugin": "^5.0.3", "copy-webpack-plugin": "^5.0.3",
"cross-env": "^5.2.0",
"css-loader": "^2.1.1", "css-loader": "^2.1.1",
"electron": "^5.0.2", "electron": "^5.0.2",
"electron-builder": "^20.43.0", "electron-builder": "^20.43.0",
@ -48,14 +49,18 @@
"eslint-plugin-react": "^7.13.0", "eslint-plugin-react": "^7.13.0",
"file-loader": "^3.0.1", "file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.7.0",
"node-sass": "^4.12.0",
"prettier": "^1.17.1", "prettier": "^1.17.1",
"prettier-stylelint": "^0.4.2", "prettier-stylelint": "^0.4.2",
"react": "^16.8.6", "react": "^16.8.6",
"react-dom": "^16.8.6", "react-dom": "^16.8.6",
"react-pose": "^4.0.8", "react-pose": "^4.0.8",
"release-it": "^12.2.2", "release-it": "^12.2.2",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1", "style-loader": "^0.23.1",
"stylelint": "^10.0.1", "stylelint": "^10.0.1",
"stylelint-config-css-modules": "^1.4.0",
"stylelint-config-standard": "^18.3.0", "stylelint-config-standard": "^18.3.0",
"webpack": "^4.33.0", "webpack": "^4.33.0",
"webpack-cli": "^3.3.2", "webpack-cli": "^3.3.2",

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import posed, { PoseGroup } from 'react-pose' import posed, { PoseGroup } from 'react-pose'
import { AppContext } from '../store/createContext' import { AppContext } from '../store/createContext'
import { cryptoFormatter } from '../../utils' import { cryptoFormatter } from '../../utils'
import './Balance.css' import styles from './Balance.module.scss'
import { fadeIn } from './Animations' import { fadeIn } from './Animations'
const Animation = posed.h1(fadeIn) const Animation = posed.h1(fadeIn)
@ -21,7 +21,7 @@ export default class Balance extends PureComponent {
return ( return (
<PoseGroup animateOnMount> <PoseGroup animateOnMount>
<Animation key={currency} className="number"> <Animation key={currency} className={styles.number}>
{cryptoFormatter(balance[currency], currency)} {cryptoFormatter(balance[currency], currency)}
</Animation> </Animation>
</PoseGroup> </PoseGroup>

View File

@ -6,6 +6,10 @@
display: inline-block; display: inline-block;
padding: 0 .3rem; padding: 0 .3rem;
border-radius: 4px; border-radius: 4px;
:global(.number-unit--main) & {
font-size: 2.5rem;
}
} }
.updated { .updated {

View File

@ -1,28 +0,0 @@
.spinner {
position: relative;
text-align: center;
margin: auto;
width: 100%;
}
.spinner::before {
content: '';
box-sizing: border-box;
position: absolute;
top: 0;
left: 50%;
width: 20px;
height: 20px;
margin-top: -20px;
margin-left: -10px;
border-radius: 50%;
border: 2px solid #7b1173;
border-top-color: #e000cf;
animation: spinner .6s linear infinite;
}
@keyframes spinner {
to {
transform: rotate(360deg);
}
}

View File

@ -1,5 +1,6 @@
import React from 'react' import React from 'react'
import './Spinner.css' import styles from './Spinner.module.scss'
const Spinner = () => <div className="spinner" />
const Spinner = () => <div className={styles.spinner} />
export default Spinner export default Spinner

View File

@ -0,0 +1,28 @@
.spinner {
position: relative;
text-align: center;
margin: auto;
width: 100%;
&::before {
content: '';
box-sizing: border-box;
position: absolute;
top: 0;
left: 50%;
width: 20px;
height: 20px;
margin-top: -20px;
margin-left: -10px;
border-radius: 50%;
border: 2px solid #7b1173;
border-top-color: #e000cf;
animation: spinner .6s linear infinite;
}
}
@keyframes spinner {
to {
transform: rotate(360deg);
}
}

View File

@ -1,48 +0,0 @@
.titlebar {
position: fixed;
width: 100%;
height: 35px;
line-height: 35px;
text-align: center;
user-select: none;
background: linear-gradient(to top, #ccc 0%, #d6d6d6 1px, #ebebeb 100%);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
transition: opacity .15s ease-out;
}
.dark .titlebar {
background: linear-gradient(to top, #141416 0%, #38383c 1px, #3f3f44 100%);
box-shadow: none;
}
.fullscreen .titlebar {
opacity: 0;
}
.blur .titlebar {
background: #f6f6f6;
}
.blur.dark .titlebar {
background: linear-gradient(to top, #141416 0%, #2d2a32 1px, #2d2a32 100%);
}
.header-title {
line-height: 35px;
height: 35px;
font-weight: 400;
font-size: 13px;
color: #555;
}
.dark .header-title {
color: #b6b3ba;
}
.blur .header-title {
color: #b6b6b6;
}
.blur.dark .header-title {
color: #67666e;
}

View File

@ -1,10 +1,10 @@
import './Titlebar.css'
import React from 'react' import React from 'react'
import pkg from '../../../package.json' import pkg from '../../../package.json'
import styles from './Titlebar.module.scss'
const Titlebar = () => ( const Titlebar = () => (
<header className="titlebar"> <header className={styles.titlebar}>
<span className="header-title">{pkg.productName}</span> <span className={styles.titlebarTitle}>{pkg.productName}</span>
</header> </header>
) )

View File

@ -0,0 +1,58 @@
.titlebar {
position: fixed;
width: 100%;
height: 35px;
line-height: 35px;
text-align: center;
user-select: none;
background: linear-gradient(to top, #ccc 0%, #d6d6d6 1px, #ebebeb 100%);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .5);
transition: opacity .15s ease-out;
:global(.dark) & {
background: linear-gradient(
to top,
#141416 0%,
#38383c 1px,
#3f3f44 100%
);
box-shadow: none;
}
:global(.fullscreen) & {
opacity: 0;
}
:global(.blur) & {
background: #f6f6f6;
}
:global(.blur.dark) & {
background: linear-gradient(
to top,
#141416 0%,
#2d2a32 1px,
#2d2a32 100%
);
}
}
.titlebarTitle {
line-height: 35px;
height: 35px;
font-weight: 400;
font-size: 13px;
color: #555;
:global(.dark) & {
color: #b6b3ba;
}
:global(.blur) & {
color: #b6b6b6;
}
:global(.blur.dark) & {
color: #67666e;
}
}

View File

@ -1,18 +0,0 @@
.welcome {
width: 100%;
height: 100%;
text-align: center;
margin-top: 2rem;
}
.welcome svg {
display: block;
width: 5rem;
height: 5rem;
margin: 0 auto 2rem auto;
fill: #e2e2e2;
}
.dark .welcome svg {
fill: #41474e;
}

View File

@ -1,11 +1,11 @@
import React from 'react' import React from 'react'
import { Link } from '@reach/router' import { Link } from '@reach/router'
import IconRocket from '../images/rocket.svg' import IconRocket from '../images/rocket.svg'
import './Welcome.css' import styles from './Welcome.module.scss'
import { AppContext } from '../store/createContext' import { AppContext } from '../store/createContext'
const Welcome = () => ( const Welcome = () => (
<div className="welcome"> <div className={styles.welcome}>
<IconRocket /> <IconRocket />
<AppContext.Consumer> <AppContext.Consumer>
{context => ( {context => (

View File

@ -0,0 +1,18 @@
.welcome {
width: 100%;
height: 100%;
text-align: center;
margin-top: 2rem;
svg {
display: block;
width: 5rem;
height: 5rem;
margin: 0 auto 2rem auto;
fill: #e2e2e2;
}
:global(.dark) & svg {
fill: #41474e;
}
}

View File

@ -59,7 +59,3 @@
.dark .number-unit--main { .dark .number-unit--main {
border-bottom-color: #303030; border-bottom-color: #303030;
} }
.number-unit--main .number {
font-size: 2.5rem;
}

View File

@ -1,27 +1,67 @@
const path = require('path') const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin') const CopyPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const defaultInclude = [path.resolve(__dirname, 'src', 'renderer')] const defaultInclude = [path.resolve(__dirname, 'src', 'renderer')]
const isDevelopment = process.env.NODE_ENV !== 'production'
module.exports = { module.exports = {
mode: isDevelopment ? 'development' : 'production',
entry: path.resolve(__dirname, 'src', 'renderer', 'index.js'), entry: path.resolve(__dirname, 'src', 'renderer', 'index.js'),
output: { output: {
path: path.resolve(__dirname, 'build'), path: path.resolve(__dirname, 'build'),
filename: 'bundle.js', filename: 'bundle.js',
publicPath: './' publicPath: isDevelopment ? '/' : './'
}, },
module: { module: {
rules: [ rules: [
{
test: /\.(js|jsx)?$/,
use: ['babel-loader'],
include: defaultInclude
},
{ {
test: /\.css$/, test: /\.css$/,
use: ['style-loader', 'css-loader'], use: ['style-loader', 'css-loader'],
include: defaultInclude include: defaultInclude
}, },
{ {
test: /\.(js|jsx)?$/, test: /\.module\.(scss|sass)$/,
use: ['babel-loader'], include: defaultInclude,
include: defaultInclude loader: [
isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]',
camelCase: true,
sourceMap: isDevelopment
}
},
{
loader: 'sass-loader',
options: {
sourceMap: isDevelopment
}
}
]
},
{
test: /\.(scss|sass)$/,
exclude: /\.module.(scss|sass)$/,
loader: [
isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
sourceMap: isDevelopment
}
}
]
}, },
{ {
test: /\.(jpe?g|png|gif)$/, test: /\.(jpe?g|png|gif)$/,
@ -36,11 +76,15 @@ module.exports = {
] ]
}, },
resolve: { resolve: {
extensions: ['*', '.js', '.jsx'] extensions: ['*', '.js', '.jsx', '.scss']
}, },
target: 'electron-renderer', target: 'electron-renderer',
plugins: [ plugins: [
new HtmlWebpackPlugin(), new HtmlWebpackPlugin(),
new MiniCssExtractPlugin({
filename: isDevelopment ? '[name].css' : '[name].[hash].css',
chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css'
}),
new CopyPlugin([ new CopyPlugin([
{ from: './src/renderer/images/icon.*', to: './', flatten: true } { from: './src/renderer/images/icon.*', to: './', flatten: true }
]) ])

View File

@ -3,12 +3,6 @@ const common = require('./webpack.common.config')
const { spawn } = require('child_process') const { spawn } = require('child_process')
module.exports = Object.assign({}, common, { module.exports = Object.assign({}, common, {
mode: 'development',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
publicPath: '/'
},
devtool: 'cheap-source-map', devtool: 'cheap-source-map',
devServer: { devServer: {
contentBase: path.resolve(__dirname, 'build'), contentBase: path.resolve(__dirname, 'build'),