mirror of
https://github.com/kremalicious/blowfish.git
synced 2024-12-27 23:27:52 +01:00
Merge pull request #19 from kremalicious/feature/css-modules
support for scss modules
This commit is contained in:
commit
a5337a5553
@ -9,5 +9,5 @@ insert_final_newline = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.css]
|
||||
[*.css,*.scss]
|
||||
indent_size = 4
|
||||
|
@ -1,6 +1,7 @@
|
||||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard",
|
||||
"stylelint-config-css-modules",
|
||||
"./node_modules/prettier-stylelint/config.js"
|
||||
],
|
||||
"rules": {
|
||||
|
@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"test": "eslint ./src/**/*.{js,jsx} && stylelint ./src/**/*.css",
|
||||
"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",
|
||||
"dist": "rm -rf {dist,build}/ && npm run build && npm run package",
|
||||
"release": "release-it --non-interactive"
|
||||
@ -38,6 +38,7 @@
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-loader": "^8.0.6",
|
||||
"copy-webpack-plugin": "^5.0.3",
|
||||
"cross-env": "^5.2.0",
|
||||
"css-loader": "^2.1.1",
|
||||
"electron": "^5.0.2",
|
||||
"electron-builder": "^20.43.0",
|
||||
@ -48,14 +49,18 @@
|
||||
"eslint-plugin-react": "^7.13.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"mini-css-extract-plugin": "^0.7.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"prettier": "^1.17.1",
|
||||
"prettier-stylelint": "^0.4.2",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-pose": "^4.0.8",
|
||||
"release-it": "^12.2.2",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"stylelint": "^10.0.1",
|
||||
"stylelint-config-css-modules": "^1.4.0",
|
||||
"stylelint-config-standard": "^18.3.0",
|
||||
"webpack": "^4.33.0",
|
||||
"webpack-cli": "^3.3.2",
|
||||
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
|
||||
import posed, { PoseGroup } from 'react-pose'
|
||||
import { AppContext } from '../store/createContext'
|
||||
import { cryptoFormatter } from '../../utils'
|
||||
import './Balance.css'
|
||||
import styles from './Balance.module.scss'
|
||||
import { fadeIn } from './Animations'
|
||||
|
||||
const Animation = posed.h1(fadeIn)
|
||||
@ -21,7 +21,7 @@ export default class Balance extends PureComponent {
|
||||
|
||||
return (
|
||||
<PoseGroup animateOnMount>
|
||||
<Animation key={currency} className="number">
|
||||
<Animation key={currency} className={styles.number}>
|
||||
{cryptoFormatter(balance[currency], currency)}
|
||||
</Animation>
|
||||
</PoseGroup>
|
||||
|
@ -6,6 +6,10 @@
|
||||
display: inline-block;
|
||||
padding: 0 .3rem;
|
||||
border-radius: 4px;
|
||||
|
||||
:global(.number-unit--main) & {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.updated {
|
@ -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);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import React from 'react'
|
||||
import './Spinner.css'
|
||||
const Spinner = () => <div className="spinner" />
|
||||
import styles from './Spinner.module.scss'
|
||||
|
||||
const Spinner = () => <div className={styles.spinner} />
|
||||
|
||||
export default Spinner
|
||||
|
28
src/renderer/components/Spinner.module.scss
Normal file
28
src/renderer/components/Spinner.module.scss
Normal 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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import './Titlebar.css'
|
||||
import React from 'react'
|
||||
import pkg from '../../../package.json'
|
||||
import styles from './Titlebar.module.scss'
|
||||
|
||||
const Titlebar = () => (
|
||||
<header className="titlebar">
|
||||
<span className="header-title">{pkg.productName}</span>
|
||||
<header className={styles.titlebar}>
|
||||
<span className={styles.titlebarTitle}>{pkg.productName}</span>
|
||||
</header>
|
||||
)
|
||||
|
||||
|
58
src/renderer/components/Titlebar.module.scss
Normal file
58
src/renderer/components/Titlebar.module.scss
Normal 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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import React from 'react'
|
||||
import { Link } from '@reach/router'
|
||||
import IconRocket from '../images/rocket.svg'
|
||||
import './Welcome.css'
|
||||
import styles from './Welcome.module.scss'
|
||||
import { AppContext } from '../store/createContext'
|
||||
|
||||
const Welcome = () => (
|
||||
<div className="welcome">
|
||||
<div className={styles.welcome}>
|
||||
<IconRocket />
|
||||
<AppContext.Consumer>
|
||||
{context => (
|
||||
|
18
src/renderer/components/Welcome.module.scss
Normal file
18
src/renderer/components/Welcome.module.scss
Normal 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;
|
||||
}
|
||||
}
|
@ -59,7 +59,3 @@
|
||||
.dark .number-unit--main {
|
||||
border-bottom-color: #303030;
|
||||
}
|
||||
|
||||
.number-unit--main .number {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
@ -1,27 +1,67 @@
|
||||
const path = require('path')
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
const CopyPlugin = require('copy-webpack-plugin')
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
|
||||
const defaultInclude = [path.resolve(__dirname, 'src', 'renderer')]
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production'
|
||||
|
||||
module.exports = {
|
||||
mode: isDevelopment ? 'development' : 'production',
|
||||
entry: path.resolve(__dirname, 'src', 'renderer', 'index.js'),
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'build'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: './'
|
||||
publicPath: isDevelopment ? '/' : './'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx)?$/,
|
||||
use: ['babel-loader'],
|
||||
include: defaultInclude
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader'],
|
||||
include: defaultInclude
|
||||
},
|
||||
{
|
||||
test: /\.(js|jsx)?$/,
|
||||
use: ['babel-loader'],
|
||||
include: defaultInclude
|
||||
test: /\.module\.(scss|sass)$/,
|
||||
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)$/,
|
||||
@ -36,11 +76,15 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['*', '.js', '.jsx']
|
||||
extensions: ['*', '.js', '.jsx', '.scss']
|
||||
},
|
||||
target: 'electron-renderer',
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin(),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: isDevelopment ? '[name].css' : '[name].[hash].css',
|
||||
chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css'
|
||||
}),
|
||||
new CopyPlugin([
|
||||
{ from: './src/renderer/images/icon.*', to: './', flatten: true }
|
||||
])
|
||||
|
@ -3,12 +3,6 @@ const common = require('./webpack.common.config')
|
||||
const { spawn } = require('child_process')
|
||||
|
||||
module.exports = Object.assign({}, common, {
|
||||
mode: 'development',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'build'),
|
||||
filename: 'bundle.js',
|
||||
publicPath: '/'
|
||||
},
|
||||
devtool: 'cheap-source-map',
|
||||
devServer: {
|
||||
contentBase: path.resolve(__dirname, 'build'),
|
||||
|
Loading…
Reference in New Issue
Block a user