Added Next.js with TS and Storybook with Boilerplate

This commit is contained in:
Niklas Schrötler 2021-04-04 16:46:47 +02:00
commit 899acea719
35 changed files with 14349 additions and 0 deletions

3
.babelrc Normal file
View file

@ -0,0 +1,3 @@
{
"presets": ["next/babel"]
}

36
.gitignore vendored Normal file
View file

@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
src/tailwind.output.css

8
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

9
.idea/UPI Website.iml Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/misc.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_15" project-jdk-name="15" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/nwex.de.iml" filepath="$PROJECT_DIR$/.idea/nwex.de.iml" />
</modules>
</component>
</project>

9
.idea/nwex.de.iml Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

4
.storybook/.babelrc Normal file
View file

@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": []
}

82
.storybook/main.js Normal file
View file

@ -0,0 +1,82 @@
const path = require("path")
const toPath = (_path) => path.join(process.cwd(), _path)
module.exports = {
stories: ["../src/**/*.stories.@(js|jsx|ts|tsx)"],
addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.
// Added to support PostCSS v8.X
/**
* CSS handling, specifically overriding postcss loader
*/
// Find the only Storybook webpack rule that tests for css
const cssRule = config.module.rules.find((rule) =>
"test.css".match(rule.test)
)
// Which loader in this rule mentions the custom Storybook postcss-loader?
const loaderIndex = cssRule.use.findIndex((loader) => {
// Loaders can be strings or objects
const loaderString = typeof loader === "string" ? loader : loader.loader
// Find the first mention of "postcss-loader", it may be in a string like:
// "@storybook/core/node_modules/postcss-loader"
return loaderString.includes("postcss-loader")
})
// Simple loader string form, removes the obsolete "options" key
cssRule.use[loaderIndex] = "postcss-loader"
// ignore *.po files
config.module.rules.push({
test: /\.(po)$/,
use: [
{
loader: require.resolve("ignore-loader")
}
]
})
// SVG
// Needed for SVG importing using svgr
const indexOfRuleToRemove = config.module.rules.findIndex((rule) =>
rule.test?.toString().includes("svg")
)
config.module.rules.splice(indexOfRuleToRemove, 1, {
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/,
loader: require.resolve("file-loader"),
options: {
name: "static/media/[name].[hash:8].[ext]",
esModule: false
}
})
config.module.rules.push({
test: /\.svg$/,
use: [
{
loader: "@svgr/webpack",
options: {
svgo: false
}
}
]
})
return {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias
// "@emotion/core": toPath("node_modules/@emotion/react"),
// "@emotion/styled": toPath("node_modules/@emotion/styled"),
// "emotion-theming": toPath("node_modules/@emotion/react")
}
}
}
}
}

213
.storybook/preview.js Normal file
View file

@ -0,0 +1,213 @@
// .storybook/preview.js
import { themes } from "@storybook/theming"
import "../src/styles/tailwind.css"
import * as nextImage from "next/image"
// or global addParameters
export const parameters = {
docs: {
theme: themes.normal
},
actions: { argTypesRegex: "^on[A-Z].*" },
viewport: {
viewports: {
mobile1: {
name: "Small mobile",
styles: {
height: "568px",
width: "320px"
},
type: "mobile"
},
mobile2: {
name: "Large mobile",
styles: {
height: "896px",
width: "414px"
},
type: "mobile"
},
tablet: {
name: "Tablet",
styles: {
height: "1112px",
width: "834px"
},
type: "tablet"
},
iphone5: {
name: "iPhone 5",
styles: {
height: "568px",
width: "320px"
},
type: "mobile"
},
iphone6: {
name: "iPhone 6",
styles: {
height: "667px",
width: "375px"
},
type: "mobile"
},
iphone6p: {
name: "iPhone 6 Plus",
styles: {
height: "736px",
width: "414px"
},
type: "mobile"
},
iphone8p: {
name: "iPhone 8 Plus",
styles: {
height: "736px",
width: "414px"
},
type: "mobile"
},
iphonex: {
name: "iPhone X",
styles: {
height: "812px",
width: "375px"
},
type: "mobile"
},
iphonexr: {
name: "iPhone XR",
styles: {
height: "896px",
width: "414px"
},
type: "mobile"
},
iphonexsmax: {
name: "iPhone XS Max",
styles: {
height: "896px",
width: "414px"
},
type: "mobile"
},
ipad: {
name: "iPad",
styles: {
height: "1024px",
width: "768px"
},
type: "tablet"
},
ipad10p: {
name: "iPad Pro 10.5-in",
styles: {
height: "1112px",
width: "834px"
},
type: "tablet"
},
ipad12p: {
name: "iPad Pro 12.9-in",
styles: {
height: "1366px",
width: "1024px"
},
type: "tablet"
},
galaxys5: {
name: "Galaxy S5",
styles: {
height: "640px",
width: "360px"
},
type: "mobile"
},
galaxys9: {
name: "Galaxy S9",
styles: {
height: "740px",
width: "360px"
},
type: "mobile"
},
nexus5x: {
name: "Nexus 5X",
styles: {
height: "660px",
width: "412px"
},
type: "mobile"
},
nexus6p: {
name: "Nexus 6P",
styles: {
height: "732px",
width: "412px"
},
type: "mobile"
},
pixel: {
name: "Pixel",
styles: {
height: "960px",
width: "540px"
},
type: "mobile"
},
pixelxl: {
name: "Pixel XL",
styles: {
height: "1280px",
width: "720px"
},
type: "mobile"
}
}
}
}
// Replace next/image for Storybook
Object.defineProperty(nextImage, "default", {
configurable: true,
value: (props) => {
const { width, height, layout } = props
if (layout === "fill") {
return (
<img
style={{
objectFit: "cover",
position: "absolute",
width: "100%",
height: "100%"
}}
{...props}
/>
)
}
const ratio = (height / width) * 100
return (
<div
style={{
paddingBottom: `${ratio}%`,
position: "relative"
}}
>
<img
style={{
objectFit: "cover",
position: "absolute",
width: "100%",
height: "100%"
}}
{...props}
/>
</div>
)
}
})

5
.vscode/extensions.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"recommendations": [
"bradlc.vscode-tailwindcss"
]
}

4
@types/index.d.ts vendored Normal file
View file

@ -0,0 +1,4 @@
declare module "*.svg" {
const content: any
export default content
}

76
CODE_OF_CONDUCT.md Normal file
View file

@ -0,0 +1,76 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at contact@elitizon.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq

92
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,92 @@
# Contributing
When contributing to this repository, please first discuss the change you wish to make via issue,
email, or any other method with the owners of this repository before making a change.
Please note we have a code of conduct, please follow it in all your interactions with the project.
## Pull Request Process
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
build.
2. Update the README.md with details of changes to the interface, this includes new environment
variables, exposed ports, useful file locations and container parameters.
3. Increase the version numbers in any examples files and the README.md to the new version that this
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
do not have permission to do that, you may request the second reviewer to merge it for you.
## Code of Conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at [contact@elitizon.com]. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Elitizon Ltd
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

189
README.md Normal file
View file

@ -0,0 +1,189 @@
# A [NextJS](https://nextjs.org/) template with typescript, tailwindcss and storybook support
> The configuration of NextJS, TailwindCSS and Storybook can be **complex** 😰 🤪
> 👉 So we have decided to make this template public 🎉
This project was bootstrapped with [npx create-next-app](https://nextjs.org/learn/basics/create-nextjs-app/setup) and we have added support for:
- ✅ [Typescript](https://www.typescriptlang.org/)
- ✅ [Taillwindcss](https://www.tailwindcss.com)
- ✅ [Storybook](https://storybook.js.org/)
- ✅ [Jest](https://jestjs.io/)
- ✅ [Import SVG as React Component (SVGR)](https://react-svgr.com/) (Thanks to [@neoziro](https://twitter.com/neoziro))
You are welcome to contribute to this project to make it better. Contact us at [contact@elitizon.com](contact@elitizon.com)
Created with ❤️ by [Elitizon](https://www.elitizon.com)
This template is available at [https://github.com/elitizon/nextjs-tailwind-storybook](https://github.com/elitizon/nextjs-tailwind-storybook)
## To use this template:
- clone it
- remove the .git folder
- git init .
- git add .
- git commit -m "First commit"
## Structure of the template
```bash
.
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── build.toml
├── next-env.d.ts
├── nextjs.config.js
├── out
│   ├── 404.html
│   ├── _next
│   ├── favicon.ico
│   ├── index.html
│   └── vercel.svg
├── package.json
├── postcss.config.js
├── public
│   ├── favicon.ico
│   └── vercel.svg
├── src
│   ├── assets
│   ├── components
│   ├── pages
│   └── styles
├── tailwind.config.js
├── tsconfig.json
└── yarn.lock
```
Pages and components are developed in `src` directory.
## Install all the dependencies
### 👉 `yarn install`
## Available Scripts
In the project directory, you can run:
### 👉 `yarn dev`
**Results:**
```bash
ready - started server on http://localhost:3000
✅ purgeEnabled=false
event - compiled successfully
event - build page: /next/dist/pages/_error
wait - compiling...
event - compiled successfully
event - build page: /
wait - compiling...```
Run the project in the dev mode.
````
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.
### 👉 `yarn storybook`
Runs storybook.
Open [http://localhost:6006](http://localhost:6006) to view it in the browser.
### 👉 `yarn test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
> If you get an error that contained this line:
Use this command:
`brew install watchman`
### 👉`yarn build`
Builds the app for production to the `.next` folder.\
It correctly bundles NextJS in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
👉 **Result of execution**
```bash
yarn run v1.22.10
$ cross-env NODE_ENV=production next build
info - Creating an optimized production build...
TailwindCSS
-----------
✅ purgeEnabled=true
info - Compiled successfully
info - Collecting page data...
info - Generating static pages (0/2)
info - Generating static pages (2/2)
info - Finalizing page optimization...
Page Size First Load JS
┌ ○ / 1.55 kB 64.3 kB
├ /_app 0 B 62.7 kB
├ ○ /404 3.46 kB 66.2 kB
└ λ /api/hello 0 B 62.7 kB
+ First Load JS shared by all 62.7 kB
├ chunks/f6078781a05fe1bcb0902d23dbbb2662c8d200b3.d4f570.js 13.1 kB
├ chunks/framework.abffcf.js 41.8 kB
├ chunks/main.1fee81.js 6.62 kB
├ chunks/pages/_app.1315ea.js 523 B
├ chunks/webpack.50bee0.js 751 B
└ css/ff7ad52a1259dc7bd680.css 1.88 kB
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
○ (Static) automatically rendered as static HTML (uses no initial props)
● (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
(ISR) incremental static regeneration (uses revalidate in getStaticProps)
Done in 9.00s.
```
See the section about [deployment](https://nextjs.org/docs/deployment) for more information.
### 👉`yarn start`
Starts a server with the output for the `yarn build` command.
`yarn build` must be executed before to use this command.
### 👉`yarn export`
Export the output of the `yarn build` command execution to the `./out` directory.
`yarn build` must be executed before to use this command.
### 👉`npx serve ./out`
To launch a **static server** from the `./out` directory. This command can be useful to control the outcome of `yarn export`.
`yarn build` and `yarn export` must be executed before to use this command.
## Learn More
You can learn more in the [NextJS documentation](https://nextjs.org/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
To learn how to develop UIs with component and design systems with Storybook, check out the [Learn Storybook documentation](https://www.learnstorybook.com/)

10
SECURITY.md Normal file
View file

@ -0,0 +1,10 @@
# Security Policy
## Supported Versions
| Version | Supported |
| ------- | ------------------ |
| 1.0.x | :white_check_mark: |

3
build.toml Normal file
View file

@ -0,0 +1,3 @@
[build]
command = "yarn build && yarn export"
publish = "out"

2
next-env.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

48
next.config.js Normal file
View file

@ -0,0 +1,48 @@
module.exports = {
/* config options here */
webpack(config, { isServer, dev: isDevelopmentMode }) {
config.module.rules.push({
test: /\.svg$/,
issuer: {
test: /\.(js|ts)x?$/
},
use: [
{
loader: "@svgr/webpack"
// https://react-svgr.com/docs/options/
}
]
})
config.module.rules.push({
test: /\.po$/,
use: [
{
loader: "ignore-loader"
}
]
})
// Fixes npm packages that depend on `fs` module
if (!isServer) {
config.node = {
fs: "empty"
}
}
// Attempt to ignore storybook files when doing a production build,
// see also: https://github.com/vercel/next.js/issues/1914
if (!isDevelopmentMode) {
config.module.rules.push({
test: /\.stories.(js|tsx?)/,
loader: "ignore-loader"
})
}
return config
},
poweredByHeader: false,
images: {
domains: ["unsplash.com"]
}
}

88
package.json Normal file
View file

@ -0,0 +1,88 @@
{
"name": "nwex-de",
"version": "1.0.0",
"keywords": [
"react",
"nextjs",
"tailwind",
"storybook",
"jest"
],
"scripts": {
"dev": "next dev",
"build": "cross-env NODE_ENV=production next build",
"start": "next start",
"export": "next export",
"test": "jest --watch",
"storybook": "start-storybook -p 6006 -s public",
"build-storybook": "build-storybook -s public"
},
"dependencies": {
"next": "10.0.5",
"react": "17.0.1",
"react-dom": "17.0.1"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@next/plugin-storybook": "^10.0.5",
"@storybook/addon-actions": "^6.1.14",
"@storybook/addon-essentials": "^6.1.14",
"@storybook/addon-links": "^6.1.14",
"@storybook/addon-viewport": "^6.1.14",
"@storybook/addons": "^6.1.14",
"@storybook/node-logger": "^6.1.14",
"@storybook/react": "^6.1.14",
"@storybook/theming": "^6.1.14",
"@svgr/webpack": "^5.5.0",
"@testing-library/dom": "^7.29.4",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.3",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.20",
"@types/node": "^14.14.21",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"autoprefixer": "^10.2.1",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^26.6.3",
"chokidar": "^3.5.1",
"chokidar-cli": "^2.1.0",
"cross-env": "^7.0.3",
"ignore-loader": "^0.1.2",
"jest": "^26.6.3",
"npm-run-all": "^4.1.5",
"postcss": "^8.2.4",
"postcss-cli": "^8.3.1",
"postcss-loader": "^4.1.0",
"react-test-renderer": "^17.0.1",
"sharp": "^0.27.0",
"storybook": "^6.1.14",
"storybook-addon-next-router": "^2.0.3",
"tailwindcss": "^2.0.2",
"typescript": "^4.1.3"
},
"resolutions": {
"react": "17.0.1"
},
"browserslist": [
">0.3%",
"not ie 11",
"not dead",
"not op_mini all"
],
"jest": {
"testPathIgnorePatterns": [
"./.next/",
"./node_modules/",
"./.storybook/"
],
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest"
},
"moduleNameMapper": {
"\\.svg": "<rootDir>/__mocks__/svgrMock.js"
}
}
}

3
postcss.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
plugins: { tailwindcss: {}, autoprefixer: {} }
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

4
public/vercel.svg Normal file
View file

@ -0,0 +1,4 @@
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="84px" height="84px" viewBox="0 0 84 84" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 64 (93537) - https://sketch.com -->
<title>favicon</title>
<desc>Created with Sketch.</desc>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="ElitizonFavicon" transform="translate(-187.000000, -109.000000)">
<g id="favicon" transform="translate(189.000000, 111.000000)">
<rect id="background" stroke="#FA3366" stroke-width="3" fill="#F6F6F6" x="0" y="0" width="80"
height="80" rx="40"></rect>
<g id="icon" transform="translate(17.000000, 19.000000)">
<path
d="M21.3702857,41.5489524 C27.2845714,41.5489524 31.3020181,42.0024879 36.3033202,37.9894671 L32.3828171,31.0938095 C30.1748171,33.3806667 25.0765714,32.7958095 21.528,32.7958095 C14.7462857,32.7958095 10.5668571,29.3260952 9.936,24.5158095 L40.296,24.5158095 C41.7942857,8.50780952 33.672,0.464380952 20.6605714,0.464380952 C8.04342857,0.464380952 -6.22570778e-14,8.98095238 -6.22570778e-14,20.8095238 C-6.22570778e-14,33.2689524 7.96457143,41.5489524 21.3702857,41.5489524 Z M31.0697143,16.5512381 L10.0937143,16.5512381 C11.5131429,11.504381 15.7714286,8.98095238 20.976,8.98095238 C26.496,8.98095238 30.4388571,11.504381 31.0697143,16.5512381 Z"
id="elitizon" fill="#2A3045" fill-rule="nonzero"></path>
<rect id="Rectangle" fill="#FA3366" x="35.4024762" y="27.3809524" width="9.61619048"
height="9.61619048" rx="4.80809524"></rect>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,23 @@
import React from "react"
import { Story, Meta } from "@storybook/react/types-6-0"
import { Hero, HeroProps } from "."
export default {
title: "Component/Hero",
component: Hero,
argTypes: {
title: { control: "string" }
}
} as Meta
const Template: Story<HeroProps> = (args) => <Hero {...args} />
// Default scenario
export const Default = Template.bind({})
Default.args = {}
// Title = "Hello World"
export const TitleHelloWorld = Template.bind({})
TitleHelloWorld.args = {
title: "Hello World"
}

View file

@ -0,0 +1,14 @@
import React from "react"
import Logo from "../../assets/square-logo.svg"
export interface HeroProps {
title?: string
}
export const Hero: React.FC<HeroProps> = () => {
return (
<div>
<h1 className="bg-red-100 dark:bg-red-900">Hallo Jakob</h1>
</div>
)
}

6
src/pages/_app.tsx Normal file
View file

@ -0,0 +1,6 @@
import "../styles/tailwind.css"
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp

6
src/pages/api/hello.js Normal file
View file

@ -0,0 +1,6 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default (req, res) => {
res.statusCode = 200
res.json({ name: 'John Doe' })
}

14
src/pages/index.tsx Normal file
View file

@ -0,0 +1,14 @@
import Head from "next/head"
import "../components/Hero"
import { Hero } from "../components/Hero"
export default function Home() {
return (
<>
<Head>
<title>nwex.de</title>
</Head>
<Hero />
</>
)
}

3
src/styles/tailwind.css Normal file
View file

@ -0,0 +1,3 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

25
tailwind.config.js Normal file
View file

@ -0,0 +1,25 @@
const purgeEnabled = process.env.NODE_ENV === "production"
console.log("\n")
console.log(` TailwindCSS \n`)
console.log(` ----------- \n`)
console.log(` ✅ purgeEnabled=${purgeEnabled}\n`)
module.exports = {
purge: {
enabled: purgeEnabled,
content: ["./src/**/*.html", "./src/**/*.tsx", "./src/**/*.jsx"]
},
darkMode: 'class', // or 'media' or 'class'
theme: {
extend: {
screens: {
'3xl': '1900px',
},
}
},
variants: {
extend: {}
},
plugins: []
}

19
tsconfig.json Normal file
View file

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["**/node_modules"]
}

13288
yarn.lock Normal file

File diff suppressed because it is too large Load diff