diff --git a/examples/history-sync-transit/.eslintrc.json b/examples/history-sync-transit/.eslintrc.json new file mode 100644 index 00000000..a2569c2c --- /dev/null +++ b/examples/history-sync-transit/.eslintrc.json @@ -0,0 +1,4 @@ +{ + "root": true, + "extends": "next/core-web-vitals" +} diff --git a/examples/history-sync-transit/.gitignore b/examples/history-sync-transit/.gitignore new file mode 100755 index 00000000..c917155c --- /dev/null +++ b/examples/history-sync-transit/.gitignore @@ -0,0 +1,38 @@ +# 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* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo + +# yarn +yarn.lock diff --git a/examples/history-sync-transit/README.md b/examples/history-sync-transit/README.md new file mode 100755 index 00000000..92736a16 --- /dev/null +++ b/examples/history-sync-transit/README.md @@ -0,0 +1,8 @@ +## history-sync-json + +Example of `RecoilHistorySyncJSONNext`. + +```bash +# run example application +yarn dev +``` diff --git a/examples/history-sync-transit/next-env.d.ts b/examples/history-sync-transit/next-env.d.ts new file mode 100755 index 00000000..4f11a03d --- /dev/null +++ b/examples/history-sync-transit/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/examples/history-sync-transit/next.config.js b/examples/history-sync-transit/next.config.js new file mode 100755 index 00000000..e977df79 --- /dev/null +++ b/examples/history-sync-transit/next.config.js @@ -0,0 +1,11 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + swcMinify: true, + experimental: { + scrollRestoration: true, + newNextLinkBehavior: true, + }, +} + +module.exports = nextConfig diff --git a/examples/history-sync-transit/package-copy.sh b/examples/history-sync-transit/package-copy.sh new file mode 100755 index 00000000..bf0da2d0 --- /dev/null +++ b/examples/history-sync-transit/package-copy.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +echo "[recoil-sync-next] copy to current directory..." + +CURRENT=`pwd` +cd ../../ +yarn clean-build +yarn pack --filename recoil-sync-next-local.tgz + +cd $CURRENT/node_modules +rm -Rf recoil-sync-next/ +tar zxf ../../../recoil-sync-next-local.tgz +mv package/ recoil-sync-next/ + +cd .. +rm -Rf .next/ + +echo "[recoil-sync-next] copy success!" +exit $? diff --git a/examples/history-sync-transit/package.json b/examples/history-sync-transit/package.json new file mode 100644 index 00000000..c251f0d3 --- /dev/null +++ b/examples/history-sync-transit/package.json @@ -0,0 +1,34 @@ +{ + "name": "history-sync-json", + "version": "0.1.0", + "private": true, + "scripts": { + "inst": "yarn install", + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint:eslint": "next lint", + "lint:tsc": "tsc --noEmit -p tsconfig.json", + "lint-fix:eslint": "next lint --fix", + "lint-fix:prettier": "prettier \"{pages,src,styles}/**/*.{ts,tsx,css}\" --write", + "local-build": "yarn run local-copy && yarn run build", + "local-dev": "yarn run local-copy && yarn run dev", + "local-copy": "./package-copy.sh" + }, + "dependencies": { + "next": "^12.2.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "recoil": "^0.7.4", + "recoil-sync": "^0.1.0", + "recoil-sync-next": "latest" + }, + "devDependencies": { + "@types/node": "^18.0.3", + "@types/react": "^18.0.15", + "@types/react-dom": "^18.0.6", + "eslint": "^8.19.0", + "eslint-config-next": "^12.2.2", + "typescript": "^4.7.4" + } +} diff --git a/examples/history-sync-transit/pages/_app.tsx b/examples/history-sync-transit/pages/_app.tsx new file mode 100755 index 00000000..492ac27f --- /dev/null +++ b/examples/history-sync-transit/pages/_app.tsx @@ -0,0 +1,17 @@ +import '../styles/globals.css' +import { RecoilRoot } from 'recoil' +import { RecoilHistorySyncJSONNext } from 'recoil-sync-next' + +import type { AppProps } from 'next/app' + +function MyApp({ Component, pageProps }: AppProps) { + return ( + + + + + + ) +} + +export default MyApp diff --git a/examples/history-sync-transit/pages/index.tsx b/examples/history-sync-transit/pages/index.tsx new file mode 100755 index 00000000..61b302a8 --- /dev/null +++ b/examples/history-sync-transit/pages/index.tsx @@ -0,0 +1,31 @@ +import Head from 'next/head' +import Link from 'next/link' + +import { Counter } from '../src/components/Counter' +import { Links } from '../src/components/Links' +import { Textfield } from '../src/components/Textfield' +import styles from '../styles/Home.module.css' + +import type { NextPage } from 'next' + +const Home: NextPage = () => { + return ( +
+ + Top - Example of RecoilHistorySyncJSONNext + + + +
+

Top page (Static)

+ + + + + +
+
+ ) +} + +export default Home diff --git a/examples/history-sync-transit/pages/ssg/[id].tsx b/examples/history-sync-transit/pages/ssg/[id].tsx new file mode 100644 index 00000000..9d97d8bb --- /dev/null +++ b/examples/history-sync-transit/pages/ssg/[id].tsx @@ -0,0 +1,56 @@ +import Head from 'next/head' + +import { Counter } from '../../src/components/Counter' +import { Textfield } from '../../src/components/Textfield' +import { Links } from '../../src/components/Links' +import styles from '../../styles/Home.module.css' + +import type { GetStaticPaths, GetStaticProps, NextPage } from 'next' + +type Props = { + id: string +} + +const SSGPage: NextPage = ({ id }) => { + return ( +
+ + SSG - Example of RecoilHistorySyncJSONNext + + +
+

SSG Page {id}

+ + + + + +
+
+ ) +} + +export default SSGPage + +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: [ + { params: { id: '1' } }, + { params: { id: '2' } }, + { params: { id: '3' } }, + ], + fallback: false, + } +} + +export const getStaticProps: GetStaticProps = async ({ + params, +}) => { + if (params?.id === undefined) throw new Error('`params.id` is undefined.') + + return { + props: { + id: params?.id, + }, + } +} diff --git a/examples/history-sync-transit/pages/ssr/[id].tsx b/examples/history-sync-transit/pages/ssr/[id].tsx new file mode 100644 index 00000000..7872e464 --- /dev/null +++ b/examples/history-sync-transit/pages/ssr/[id].tsx @@ -0,0 +1,46 @@ +import Head from 'next/head' + +import { Counter } from '../../src/components/Counter' +import { Links } from '../../src/components/Links' +import { Textfield } from '../../src/components/Textfield' +import styles from '../../styles/Home.module.css' + +import type { GetServerSideProps, NextPage } from 'next' + +type Props = { + id: string +} + +const SSRPage: NextPage = ({ id }) => { + return ( +
+ + SSR - Example of RecoilHistorySyncJSONNext + + +
+

SSR Page {id}

+ + + + + +
+
+ ) +} + +export default SSRPage + +export const getServerSideProps: GetServerSideProps< + Props, + { id: string } +> = async ({ params }) => { + if (params?.id === undefined) throw new Error('`params.id` is undefined.') + + return { + props: { + id: params?.id, + }, + } +} diff --git a/examples/history-sync-transit/public/favicon.ico b/examples/history-sync-transit/public/favicon.ico new file mode 100755 index 00000000..718d6fea Binary files /dev/null and b/examples/history-sync-transit/public/favicon.ico differ diff --git a/examples/history-sync-transit/src/components/Counter/index.module.css b/examples/history-sync-transit/src/components/Counter/index.module.css new file mode 100644 index 00000000..17570eef --- /dev/null +++ b/examples/history-sync-transit/src/components/Counter/index.module.css @@ -0,0 +1,5 @@ +.wrapper { + display: flex; + justify-content: space-between; + width: 200px; +} diff --git a/examples/history-sync-transit/src/components/Counter/index.tsx b/examples/history-sync-transit/src/components/Counter/index.tsx new file mode 100644 index 00000000..65f62e7c --- /dev/null +++ b/examples/history-sync-transit/src/components/Counter/index.tsx @@ -0,0 +1,32 @@ +import { number } from '@recoiljs/refine' +import { useRecoilState } from 'recoil' +import { syncEffect } from 'recoil-sync' +import { atomFamilyWithInitialValue } from 'recoil-sync-next' + +import styles from './index.module.css' + +export const counter = atomFamilyWithInitialValue({ + key: 'counterState', + effects: [syncEffect({ refine: number() })], +}) + +export type Props = { + name: string + initialValue: number +} + +export const Counter: React.FC = ({ name, initialValue }) => { + const [count, setCount] = useRecoilState(counter(name, initialValue)) + + return ( +
+
+ count[{name}]: {count} +
+
+ + +
+
+ ) +} diff --git a/examples/history-sync-transit/src/components/Links/index.tsx b/examples/history-sync-transit/src/components/Links/index.tsx new file mode 100644 index 00000000..8b00cd31 --- /dev/null +++ b/examples/history-sync-transit/src/components/Links/index.tsx @@ -0,0 +1,44 @@ +import Link from 'next/link' + +export const Links: React.FC = () => { + return ( +
+
Top
+
+
    +
  • + Top +
  • +
+
+
SSR
+
+
    +
  • + SSR 1 +
  • +
  • + SSR 2 +
  • +
  • + SSR 3 +
  • +
+
+
SSG
+
+
    +
  • + SSG 1 +
  • +
  • + SSG 2 +
  • +
  • + SSG 3 +
  • +
+
+
+ ) +} diff --git a/examples/history-sync-transit/src/components/Textfield/index.module.css b/examples/history-sync-transit/src/components/Textfield/index.module.css new file mode 100644 index 00000000..0888644f --- /dev/null +++ b/examples/history-sync-transit/src/components/Textfield/index.module.css @@ -0,0 +1,3 @@ +.wrapper { + width: 200px; +} diff --git a/examples/history-sync-transit/src/components/Textfield/index.tsx b/examples/history-sync-transit/src/components/Textfield/index.tsx new file mode 100644 index 00000000..3c94c2ad --- /dev/null +++ b/examples/history-sync-transit/src/components/Textfield/index.tsx @@ -0,0 +1,21 @@ +import { string } from '@recoiljs/refine' +import { atom, useRecoilState } from 'recoil' +import { syncEffect } from 'recoil-sync' + +import styles from './index.module.css' + +export const textState = atom({ + key: 'textState', + default: '', + effects: [syncEffect({ refine: string() })], +}) + +export const Textfield: React.FC = () => { + const [text, setText] = useRecoilState(textState) + + return ( +
+ setText(e.currentTarget.value)} /> +
+ ) +} diff --git a/examples/history-sync-transit/styles/Home.module.css b/examples/history-sync-transit/styles/Home.module.css new file mode 100755 index 00000000..bb284bbf --- /dev/null +++ b/examples/history-sync-transit/styles/Home.module.css @@ -0,0 +1,17 @@ +.container { + padding: 0 2rem; +} + +.main { + min-height: 100vh; + min-width: 700px; + padding: 4rem 0; + flex: 1; + display: flex; + flex-direction: column; +} + +.link { + color: blue; + text-decoration: underline; +} diff --git a/examples/history-sync-transit/styles/globals.css b/examples/history-sync-transit/styles/globals.css new file mode 100755 index 00000000..83faa13c --- /dev/null +++ b/examples/history-sync-transit/styles/globals.css @@ -0,0 +1,16 @@ +html, +body { + padding: 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; +} + +a { + color: blue; + text-decoration: underline; +} + +* { + box-sizing: border-box; +} diff --git a/examples/history-sync-transit/tsconfig.json b/examples/history-sync-transit/tsconfig.json new file mode 100755 index 00000000..921df2f2 --- /dev/null +++ b/examples/history-sync-transit/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es2018", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +}