Skip to content

feat: introduce CSS in JS via Linaria #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
node_modules
coverage
generator-tsx-*
generators/**/*.js
generators/**/*.d.ts
generators/*.js
generators/*.d.ts
generators/*/*.js
generators/*/*.d.ts
package
.yo-rc.json
6 changes: 4 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"generators/**/*.js": true,
"generators/**/*.d.ts": true
"generators/*.js": true,
"generators/*.d.ts": true,
"generators/*/*.js": true,
"generators/*/*.d.ts": true
},
"search.exclude": {
"**/coverge": true,
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ See [Design Goals](https://github.com/adobe/generator-tsx/wiki/Design-Goals).
- [Router](https://github.com/ReactTraining/react-router)
- [Testing Library](https://github.com/testing-library/react-testing-library#react-testing-library)
- [react-intl](https://github.com/formatjs/react-intl)
- CSS in JS via [Linaria](https://linaria.now.sh/)

## Installation

Expand Down
5 changes: 5 additions & 0 deletions generators/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export = class extends Generator {
'.gitignore',
'.markdownlint.json',
'.travis.yml',
'config',
'tsconfig.json',
].forEach(filename => {
this.fs.copy(
Expand Down Expand Up @@ -124,6 +125,7 @@ export = class extends Generator {
)
this.npmInstall(
[
'@craco/craco@5',
'@jedmao/tsconfig',
'@types/fetch-mock@^7',
'@types/jest@^24',
Expand All @@ -137,9 +139,12 @@ export = class extends Generator {
'@types/redux-logger@^3',
'@types/redux-mock-store@^1',
'@types/webpack-env@^1',
// TODO: https://github.com/callstack/linaria/issues/420
'core-js@2',
'fetch-mock@^7',
'husky@^2',
'jest-fetch-mock@^2',
'linaria@1',
'lint-staged@^8',
'prettier@^1',
'react-scripts@^3',
Expand Down
3 changes: 3 additions & 0 deletions generators/app/templates/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# linaria
src/.linaria_cache
3 changes: 2 additions & 1 deletion generators/app/templates/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"search.exclude": {
"**/build": true,
"**/coverge": true,
"**/node_modules": true
"**/node_modules": true,
"src/.linaria_cache": true
}
}
7 changes: 7 additions & 0 deletions generators/app/templates/config/babelTransform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const babelJest = require('babel-jest')

module.exports = babelJest.createTransformer({
presets: [require.resolve('babel-preset-react-app'), 'linaria/babel'],
babelrc: false,
configFile: false,
})
21 changes: 21 additions & 0 deletions generators/app/templates/config/craco.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { loaderByName, getLoader } = require('@craco/craco')
const transformBabelLoader = require('./transformBabelLoader')

module.exports = {
webpack: {
configure: webpackConfig => {
const lm = getLoader(webpackConfig, loaderByName('babel-loader'))
const loader = lm.match.loader
webpackConfig.module.rules[2].oneOf[1] = transformBabelLoader(loader)
return webpackConfig
},
},
jest: {
configure: jestConfig => {
jestConfig.transform['^.+\\.(js|jsx|ts|tsx)$'] = require.resolve(
'./babelTransform.js',
)
return jestConfig
},
},
}
22 changes: 22 additions & 0 deletions generators/app/templates/config/transformBabelLoader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = loader => ({
test: loader.test,
include: loader.include,
rules: [
{
loader: loader.loader,
options: {
presets: [loader.options.presets[0], 'linaria/babel'],
},
},
{
loader: 'linaria/loader',
options: {
cacheDirectory: 'src/.linaria_cache',
sourceMap: process.env.NODE_ENV !== 'production',
babelOptions: {
presets: loader.options.presets,
},
},
},
],
})
7 changes: 4 additions & 3 deletions generators/app/templates/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"homepage": "https://github.com/<%= githubUsername %>/<%= appname %>#readme",
"scripts": {
"clean": "rimraf coverage build *.log*",
"start": "react-scripts start",
"start": "craco start",
"prebuild": "rimraf build",
"build": "react-scripts build",
"test": "react-scripts test",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject",
"check-types": "tsc --noEmit",
"precover": "rimraf coverage",
Expand Down Expand Up @@ -65,6 +65,7 @@
"lcov"
]
},
"cracoConfig": "config/craco.config.js",
"eslintConfig": {
"extends": "react-app",
"globals": {
Expand Down
26 changes: 0 additions & 26 deletions generators/app/templates/src/components/Home/Home.module.css

This file was deleted.

38 changes: 32 additions & 6 deletions generators/app/templates/src/components/Home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { styled } from 'linaria/react'
import React, { useEffect } from 'react'
import Helmet from 'react-helmet'
import { FormattedMessage, FormattedHTMLMessage } from 'react-intl'
Expand All @@ -8,7 +9,6 @@ import useTheme from 'helpers/useTheme'
import Theme from 'models/Theme'
import RootState from 'store/RootState'

import styles from './Home.module.css'
import logo from './logo.svg'

interface StateProps extends Pick<RootState, 'cart'> {
Expand All @@ -31,12 +31,12 @@ const Home: React.FC<HomeProps & StateProps & DispatchProps> = ({
}, [getCart])
useTheme(theme)
return (
<div className={styles.root}>
<Root>
<Helmet>
<title>Home</title>
</Helmet>
<header className={styles.header}>
<img src={logo} className={styles.logo} alt="logo" />
<Header>
<Logo src={logo} alt="logo" />
<p>
<FormattedHTMLMessage id="home.instructions" />
</p>
Expand All @@ -48,8 +48,8 @@ const Home: React.FC<HomeProps & StateProps & DispatchProps> = ({
<FormattedMessage id="home.learn" />
</a>
{JSON.stringify(cart.subtotal.amount)}
</header>
</div>
</Header>
</Root>
)
}

Expand All @@ -62,3 +62,29 @@ export default connect<StateProps, DispatchProps, void, RootState>(
getCart: fetchCart,
},
)(Home)

const Root = styled.div`
text-align: center;
`

const Header = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
`

const Logo = styled.img`
animation: spin infinite 20s linear;
height: 40vmin;
pointer-events: none;
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
`
4 changes: 1 addition & 3 deletions generators/app/templates/src/helpers/resolveFetch.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/*eslint-disable no-throw-literal*/
import { Omit } from 'ts-essentials'

import ResponseError from 'models/ResponseError'
import ResponsePayload from 'models/ResponsePayload'

Expand Down Expand Up @@ -61,5 +59,5 @@ export default async function resolveFetch<TBody extends any>(
* Intentionally omit non-TBody props from the result type,
* because errors have already been dealt with.
*/
return (responsePayload as Omit<typeof responsePayload, 'errors'>) as TBody
return (responsePayload as unknown) as TBody
}
1 change: 1 addition & 0 deletions generators/app/templates/src/react-app-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="react-scripts" />
1 change: 0 additions & 1 deletion generators/app/templates/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"allowUnusedLabels": false,
"alwaysStrict": true,
"baseUrl": "src",
"declaration": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
Expand Down

This file was deleted.

9 changes: 6 additions & 3 deletions generators/component/expected/barBaz/QuxQuux/QuxQuux.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { styled } from 'linaria/react'
import React from 'react'
import { connect } from 'react-redux'

import RootState from 'store/RootState'

import styles from './QuxQuux.module.css'

interface StateProps {}

interface DispatchProps {}

export interface QuxQuuxProps {}

const QuxQuux: React.FC<QuxQuuxProps & StateProps & DispatchProps> = () => (
<div className={styles.root}>content</div>
<Root>content</Root>
)

export default connect<StateProps, DispatchProps, void, RootState>(null)(QuxQuux)

const Root = styled.div`
display: block;
`
1 change: 0 additions & 1 deletion generators/component/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ describe('tsx:component', () => {
'barBaz/QuxQuux/index.ts',
'barBaz/QuxQuux/QuxQuux.tsx',
'barBaz/QuxQuux/QuxQuux.test.tsx',
'barBaz/QuxQuux/QuxQuux.module.css',
]
for (const filename of expectedFiles) {
assert.fileContent(
Expand Down
28 changes: 13 additions & 15 deletions generators/component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,19 @@ export = class extends Generator {
const parts = this.options.name.split('/').map(camelCase)
const name = sentenceCase(parts[parts.length - 1])
parts.splice(-1, 1, name)
;['index.ts', 'Foo.tsx', 'Foo.test.tsx', 'Foo.module.css'].forEach(
filename => {
this.fs.copyTpl(
this.templatePath(filename),
this.destinationPath(
`src/components/${parts.join('/')}/${filename.replace(
/^Foo/,
name,
)}`,
),
{
;['index.ts', 'Foo.tsx', 'Foo.test.tsx'].forEach(filename => {
this.fs.copyTpl(
this.templatePath(filename),
this.destinationPath(
`src/components/${parts.join('/')}/${filename.replace(
/^Foo/,
name,
},
)
},
)
)}`,
),
{
name,
},
)
})
}
}
3 changes: 0 additions & 3 deletions generators/component/templates/Foo.module.css

This file was deleted.

9 changes: 6 additions & 3 deletions generators/component/templates/Foo.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import { styled } from 'linaria/react'
import React from 'react'
import { connect } from 'react-redux'

import RootState from 'store/RootState'

import styles from './<%= name %>.module.css'

interface StateProps {}

interface DispatchProps {}

export interface <%= name %>Props {}

const <%= name %>: React.FC<<%= name %>Props & StateProps & DispatchProps> = () => (
<div className={styles.root}>content</div>
<Root>content</Root>
)

export default connect<StateProps, DispatchProps, void, RootState>(null)(<%= name %>)

const Root = styled.div`
display: block;
`
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading