Skip to content
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

Feat: Example NextJS app with app router #DS-1393 #1578

Merged
merged 1 commit into from
Aug 20, 2024
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
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module.exports = {
'exporters/scss',
'exporters/js',
'exporters/variables-scss',
'examples/*'
],

extends: ['@lmc-eu/eslint-config-react/base', '@lmc-eu/eslint-config-react/optional', 'prettier', 'plugin:prettier/recommended', 'plugin:storybook/recommended'],
Expand Down
18 changes: 18 additions & 0 deletions examples/next-with-app-router/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# .eslintignore

node_modules

# NOTE:
# The following directives are only relevant when linting the whole
# project directory, ie. running `eslint .` ⚠️

# If you compile JavaScript into some output folder, exclude it here
dist
build

# Highly recommended to re-include JavaScript dotfiles to lint them
# (This will cause .eslintrc.js to be linted by ESLint 🤘)
!.*.js

# Some tools use this pattern for their configuration files. Lint them!
!*.config.js
109 changes: 109 additions & 0 deletions examples/next-with-app-router/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
module.exports = {
extends: [
'../../.eslintrc',
'@lmc-eu/eslint-config-react',
'@lmc-eu/eslint-config-typescript',
'@lmc-eu/eslint-config-typescript/react',
'prettier',
'plugin:prettier/recommended',
'@lmc-eu/eslint-config-jest',
'plugin:@next/next/recommended',
],
env: {
jest: true,
},
plugins: ['promise', 'react', '@typescript-eslint', 'prettier', 'react-refresh'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
project: './tsconfig.eslint.json',
},
rules: {
// @see: https://github.com/ArnaudBarre/eslint-plugin-react-refresh
'react-refresh/only-export-components': 'warn',
// @TODO: add to typescript config
'react/jsx-filename-extension': ['error', { extensions: ['.js', '.jsx', '.ts', '.tsx'] }],
// we like to use props spreading for additional props in this case
'react/jsx-props-no-spreading': 'off', // Used inside HOC, that is fine.
// prefer arrow function over function expression
'react/function-component-definition': [
'warn',
{ namedComponents: 'arrow-function', unnamedComponents: 'arrow-function' },
],
// we have missing displayName attribute in our components
// it is good for debugging
// @see: https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md
'react/display-name': 'off',
// ignore UNSTABLE_ prefix in component names
'react/jsx-pascal-case': [
'error',
{
allowAllCaps: true,
ignore: ['UNSTABLE_*'],
},
],
// ignore UNSAFE and UNSTABLE_ prefixes
camelcase: [
'error',
{
properties: 'never',
ignoreDestructuring: false,
allow: ['^UNSAFE_', '^UNSTABLE_'],
},
],
// allow ++ in for loops
'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
// allow reassign in properties
'no-param-reassign': ['warn', { props: false }],
// support monorepos
'import/no-extraneous-dependencies': [
'error',
{
packageDir: ['./', '../../'],
peerDependencies: true,
},
],
'import/order': [
'error',
{
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
pathGroups: [
{
pattern: '**',
group: 'internal',
},
{
pattern: '..',
group: 'parent',
position: 'after',
},
],
pathGroupsExcludedImportTypes: ['builtin'],
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
'newlines-between': 'never',
},
],
// disable double quotes
quotes: ['warn', 'single'],
// use useIsomorphicLayoutEffect instead of useLayoutEffect
// @see: https://medium.com/@alexandereardon/uselayouteffect-and-ssr-192986cdcf7a
'no-restricted-imports': [
'error',
// Disabling using of useLayoutEffect from react
{
name: 'react',
importNames: ['useLayoutEffect'],
message: '`useLayoutEffect` causes a warning in SSR. Use `useIsomorphicLayoutEffect`',
},
],
// allow empty interfaces with single extends (e.g. interface Foo extends SpiritBar {})
// interface which extends some other interface is not considered as meaningful interface
// we need this for meeting our component API conventions
// @see: https://typescript-eslint.io/rules/no-empty-interface/
'@typescript-eslint/no-empty-interface': ['error', { allowSingleExtends: true }],
'react/react-in-jsx-scope': 'off',
},
};
10 changes: 10 additions & 0 deletions examples/next-with-app-router/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# production
/build

# vercel
.vercel

# typescript
next-env.d.ts
19 changes: 19 additions & 0 deletions examples/next-with-app-router/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Example Next.js application with app router

This application is used to demonstrate the configuration of a Next.js application with an App router for use with the Spirit Design System.

## Getting Started

First, run the development server:

```bash
yarn dev
```

In case of error `npm error ERR! code ENOWORKSPACES`, please use `npx another telemetry disable`. For more information see [NPM error code ENOWORKSPACES with NextJS][npm-error-enoworkspaces].

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `src/app/page.tsx`. The page auto-updates as you edit the file.

[npm-error-enoworkspaces]: https://github.com/vercel/turborepo/issues/4183
19 changes: 19 additions & 0 deletions examples/next-with-app-router/next.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import path, { dirname } from 'path';
import { fileURLToPath } from 'url';

const pathDir = dirname(fileURLToPath(import.meta.url));

/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['@lmc-eu/spirit-web-react'],
reactStrictMode: true,
sassOptions: {
fiber: false,
includePaths: [
path.join(pathDir, '../../node_modules'),
path.join(pathDir, '../../node_modules/@lmc-eu/spirit-design-tokens/scss'),
],
},
};

export default nextConfig;
28 changes: 28 additions & 0 deletions examples/next-with-app-router/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "@almacareer/spirit-example-next-with-app-router",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@lmc-eu/spirit-design-tokens": "workspace:^",
"@lmc-eu/spirit-web": "workspace:^",
"@lmc-eu/spirit-web-react": "workspace:^",
"next": "14.2.3",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@next/eslint-plugin-next": "^14.2.5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.5",
"typescript": "4.7.4"
}
}
Binary file not shown.
1 change: 1 addition & 0 deletions examples/next-with-app-router/src/app/globals.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import '@lmc-eu/spirit-web/src/scss';
12 changes: 12 additions & 0 deletions examples/next-with-app-router/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ReactNode } from 'react';
import './globals.scss';

const RootLayout = ({ children }: Readonly<{ children: ReactNode }>) => {
return (
<html lang="en">
<body>{children}</body>
</html>
);
};

export default RootLayout;
6 changes: 6 additions & 0 deletions examples/next-with-app-router/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Heading } from '@lmc-eu/spirit-web-react';
import { NextPage } from 'next';

const Home: NextPage = () => <Heading size="large">Spirit App Router</Heading>;

export default Home;
4 changes: 4 additions & 0 deletions examples/next-with-app-router/tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"include": ["./", "./.eslintrc.js"]
}
29 changes: 29 additions & 0 deletions examples/next-with-app-router/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"compilerOptions": {
"useUnknownInCatchVariables": false,
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"],
"@lmc-eu/spirit-web-react": ["../../node_modules/@lmc-eu/spirit-web-react/src"]
},
"forceConsistentCasingInFileNames": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
"workspaces": [
"configs/*",
"packages/*",
"examples/*",
"exporters/*",
"apps/demo",
"apps/storybook"
],
"scripts": {
"start": "yarn packages:start",
"start": "yarn packages:start --ignore '@almacareer/spirit-example*'",
"build": "npm-run-all --serial packages:build:libs packages:build:web",
"es:lint": "eslint ./",
"es:lint:fix": "yarn es:lint --fix",
Expand All @@ -44,7 +45,7 @@
"packages:start": "lerna run start --parallel",
"packages:test": "lerna run test",
"packages:types": "lerna run types --no-sort",
"packages:build:libs": "lerna run build --ignore '@lmc-eu/spirit-web*' --ignore=@lmc-eu/spirit-demo-app --ignore=@lmc-eu/spirit-storybook",
"packages:build:libs": "lerna run build --ignore '@lmc-eu/spirit-web*' --ignore=@lmc-eu/spirit-demo-app --ignore=@lmc-eu/spirit-storybook --ignore '@almacareer/spirit-example*'",
"packages:build:web": "lerna run build --scope '@lmc-eu/spirit-web*' --ignore=@lmc-eu/spirit-demo-app",
"packages:publish": "lerna publish",
"packages:diff": "lerna diff",
Expand Down
Loading
Loading