diff --git a/.codesandbox/ci.json b/.codesandbox/ci.json
new file mode 100644
index 0000000000..8692f3a107
--- /dev/null
+++ b/.codesandbox/ci.json
@@ -0,0 +1,5 @@
+{
+ "packages": ["packages/*", "targets/*"],
+ "sandboxes": ["/demo/src/sandboxes/card", "/demo/src/sandboxes/gooBlobs"],
+ "node": "14"
+}
diff --git a/.vscode/react-spring.code-workspace b/.vscode/react-spring.code-workspace
index 713ac00e18..f3952db213 100644
--- a/.vscode/react-spring.code-workspace
+++ b/.vscode/react-spring.code-workspace
@@ -21,8 +21,7 @@
"typescript.tsdk": "node_modules/typescript/lib",
"files.exclude": {
"**/.bic_cache": true,
- "**/.rpt2_cache": true,
- "**/node_modules": true
+ "**/.rpt2_cache": true
}
}
}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 499e33450a..b008494a2f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,7 +2,6 @@
"typescript.tsdk": "node_modules/typescript/lib",
"files.exclude": {
"**/.bic_cache": true,
- "**/.rpt2_cache": true,
- "**/node_modules": true
+ "**/.rpt2_cache": true
}
}
diff --git a/demo/package.json b/demo/package.json
index 1f51b649a9..d288d7f9ea 100644
--- a/demo/package.json
+++ b/demo/package.json
@@ -1,5 +1,5 @@
{
- "name": "react-spring-sandbox",
+ "name": "demo-react-spring-sandbox",
"version": "1.0.0",
"description": "a sandbox for react-spring (probably will be replaced with something in the future)",
"main": "null",
@@ -12,7 +12,8 @@
},
"dependencies": {
"react": "^17.0.1",
- "react-dom": "^17.0.1"
+ "react-dom": "^17.0.1",
+ "wouter": "^2.7.4"
},
"devDependencies": {
"@types/react": "^17.0.3",
@@ -20,5 +21,6 @@
"@vitejs/plugin-react-refresh": "^1.3.1",
"typescript": "^4.2.3",
"vite": "^2.1.2"
- }
+ },
+ "bic": false
}
diff --git a/demo/src/App.tsx b/demo/src/App.tsx
index d70ba3a04d..5ebea413ef 100644
--- a/demo/src/App.tsx
+++ b/demo/src/App.tsx
@@ -1,18 +1,43 @@
import * as React from 'react'
-import { useSpring, animated } from '@react-spring/web'
+import { Link, Route } from 'wouter'
-const App = () => {
- const [open, toggle] = React.useState(false)
- const props = useSpring({ width: open ? 100 : 0 })
+import GooBlobs from './sandboxes/gooBlobs/src/App'
+import Card from './sandboxes/card/src/App'
+const links: {
+ [key: string]: () => JSX.Element
+} = {
+ 'goo-blobs': GooBlobs,
+ card: Card,
+}
+
+const Example = ({ link }: { link: string }) => {
+ const Component = links[link]
return (
-
toggle(!open)}>
-
-
- {props.width.interpolate(x => x.toFixed(0))}
-
+
)
}
-export default App
+export default function App() {
+ return (
+ <>
+
+ Spring demos
+ Sandboxes
+
+ {Object.keys(links).map(link => (
+
+
{link}
+
+ ))}
+
+
+
{params => }
+ >
+ )
+}
diff --git a/demo/src/sandboxes/card/package.json b/demo/src/sandboxes/card/package.json
new file mode 100644
index 0000000000..4765527706
--- /dev/null
+++ b/demo/src/sandboxes/card/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "spring-card",
+ "version": "1.0.0",
+ "main": "src/index.tsx",
+ "dependencies": {
+ "@react-spring/web": "*",
+ "react": "^17.0.1",
+ "react-dom": "^17.0.1",
+ "react-scripts": "4.0.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ],
+ "bic": false,
+ "devDependencies": {}
+}
diff --git a/demo/src/sandboxes/card/public/index.html b/demo/src/sandboxes/card/public/index.html
new file mode 100644
index 0000000000..2a1959d610
--- /dev/null
+++ b/demo/src/sandboxes/card/public/index.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
React Spring Sandbox
+
+
+
+
+
+
+
+
diff --git a/demo/src/sandboxes/card/src/App.tsx b/demo/src/sandboxes/card/src/App.tsx
new file mode 100644
index 0000000000..09929a3fb9
--- /dev/null
+++ b/demo/src/sandboxes/card/src/App.tsx
@@ -0,0 +1,27 @@
+import React from 'react'
+import { useSpring, animated } from '@react-spring/web'
+
+import './index.css'
+
+const calc = (x: number, y: number) => [
+ -(y - window.innerHeight / 2) / 20,
+ (x - window.innerWidth / 2) / 20,
+ 1.1,
+]
+const trans = (x: number, y: number, s: number) =>
+ `perspective(600px) rotateX(${x}deg) rotateY(${y}deg) scale(${s})`
+
+export default function App() {
+ const [props, set] = useSpring(() => ({
+ xys: [0, 0, 1],
+ config: { mass: 5, tension: 350, friction: 40 },
+ }))
+ return (
+
set({ xys: calc(x, y) })}
+ onMouseLeave={() => set({ xys: [0, 0, 1] })}
+ style={{ transform: props.xys.to(trans) }}
+ />
+ )
+}
diff --git a/demo/src/sandboxes/card/src/index.css b/demo/src/sandboxes/card/src/index.css
new file mode 100644
index 0000000000..1a2702a6a5
--- /dev/null
+++ b/demo/src/sandboxes/card/src/index.css
@@ -0,0 +1,48 @@
+html,
+body,
+#root {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ background-color: white;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir,
+ helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif;
+ background: transparent;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: default;
+}
+
+#root {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ overflow: hidden;
+ background: #f0f0f0;
+}
+
+.card {
+ width: 45ch;
+ height: 45ch;
+ background: grey;
+ border-radius: 5px;
+ background-image: url(https://drscdn.500px.org/photo/435236/q%3D80_m%3D1500/v2?webp=true&sig=67031bdff6f582f3e027311e2074be452203ab637c0bd21d89128844becf8e40);
+ background-size: cover;
+ background-position: center center;
+ box-shadow: 0px 10px 30px -5px rgba(0, 0, 0, 0.3);
+ transition: box-shadow 0.5s;
+ will-change: transform;
+ border: 15px solid white;
+}
+
+.card:hover {
+ box-shadow: 0px 30px 100px -10px rgba(0, 0, 0, 0.4);
+}
diff --git a/demo/src/sandboxes/card/src/index.tsx b/demo/src/sandboxes/card/src/index.tsx
new file mode 100644
index 0000000000..32680e24e6
--- /dev/null
+++ b/demo/src/sandboxes/card/src/index.tsx
@@ -0,0 +1,11 @@
+import React from 'react'
+import ReactDOM from 'react-dom'
+import App from './App'
+
+const rootElement = document.getElementById('root')
+ReactDOM.render(
+
+
+ ,
+ rootElement
+)
diff --git a/demo/src/sandboxes/gooBlobs/package.json b/demo/src/sandboxes/gooBlobs/package.json
new file mode 100644
index 0000000000..71582c69c5
--- /dev/null
+++ b/demo/src/sandboxes/gooBlobs/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "spring-goo-blobs",
+ "version": "1.0.0",
+ "main": "src/index.tsx",
+ "dependencies": {
+ "@react-spring/web": "*",
+ "react": "^17.0.1",
+ "react-dom": "^17.0.1",
+ "react-scripts": "4.0.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ],
+ "bic": false,
+ "devDependencies": {}
+}
diff --git a/demo/src/sandboxes/gooBlobs/public/index.html b/demo/src/sandboxes/gooBlobs/public/index.html
new file mode 100644
index 0000000000..2a1959d610
--- /dev/null
+++ b/demo/src/sandboxes/gooBlobs/public/index.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+ React Spring Sandbox
+
+
+
+
+
+
+
+
diff --git a/demo/src/sandboxes/gooBlobs/src/App.tsx b/demo/src/sandboxes/gooBlobs/src/App.tsx
new file mode 100644
index 0000000000..c12649fbca
--- /dev/null
+++ b/demo/src/sandboxes/gooBlobs/src/App.tsx
@@ -0,0 +1,36 @@
+import React from 'react'
+import { useTrail, animated } from '@react-spring/web'
+
+import './index.css'
+
+const fast = { tension: 1200, friction: 40 }
+const slow = { mass: 10, tension: 200, friction: 50 }
+const trans = (x: number, y: number) =>
+ `translate3d(${x}px,${y}px,0) translate3d(-50%,-50%,0)`
+
+export default function App() {
+ const [trail, set] = useTrail(3, () => ({
+ xy: [0, 0],
+ config: i => (i === 0 ? fast : slow),
+ }))
+ return (
+ <>
+
+ set({ xy: [e.clientX, e.clientY] })}>
+ {trail.map((props, index) => (
+
+ ))}
+
+ >
+ )
+}
diff --git a/demo/src/sandboxes/gooBlobs/src/index.css b/demo/src/sandboxes/gooBlobs/src/index.css
new file mode 100644
index 0000000000..67124f5b87
--- /dev/null
+++ b/demo/src/sandboxes/gooBlobs/src/index.css
@@ -0,0 +1,94 @@
+body {
+ font-family: system-ui;
+ margin: 0;
+}
+
+*,
+*:after,
+*:before {
+ box-sizing: border-box;
+}
+
+html,
+body,
+#root {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ background-color: white;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir,
+ helvetica neue, helvetica, ubuntu, roboto, noto, segoe ui, arial, sans-serif;
+ background: transparent;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ cursor: default;
+}
+
+.hooks-main > svg {
+ display: none;
+}
+
+.hooks-main > div {
+ position: absolute;
+ will-change: transform;
+ border-radius: 50%;
+ background: lightcoral;
+ box-shadow: 10px 10px 5px 0px rgba(0, 0, 0, 0.75);
+ opacity: 0.6;
+}
+
+.hooks-main > div:nth-child(1) {
+ width: 120px;
+ height: 120px;
+}
+
+.hooks-main > div:nth-child(2) {
+ width: 250px;
+ height: 250px;
+}
+
+.hooks-main > div:nth-child(3) {
+ width: 150px;
+ height: 150px;
+}
+
+.hooks-main > div::after {
+ content: '';
+ position: absolute;
+ top: 20px;
+ left: 20px;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: rgba(255, 255, 255, 0.8);
+}
+
+.hooks-main > div:nth-child(2)::after {
+ top: 70px;
+ left: 70px;
+ width: 70px;
+ height: 70px;
+}
+
+.hooks-main > div:nth-child(3)::after {
+ top: 50px;
+ left: 50px;
+ width: 50px;
+ height: 50px;
+}
+
+.hooks-main {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ filter: url('#goo');
+ overflow: hidden;
+}
diff --git a/demo/src/sandboxes/gooBlobs/src/index.tsx b/demo/src/sandboxes/gooBlobs/src/index.tsx
new file mode 100644
index 0000000000..32680e24e6
--- /dev/null
+++ b/demo/src/sandboxes/gooBlobs/src/index.tsx
@@ -0,0 +1,11 @@
+import React from 'react'
+import ReactDOM from 'react-dom'
+import App from './App'
+
+const rootElement = document.getElementById('root')
+ReactDOM.render(
+
+
+ ,
+ rootElement
+)
diff --git a/demo/yarn.lock b/demo/yarn.lock
index fa2ee826e3..e9435209af 100644
--- a/demo/yarn.lock
+++ b/demo/yarn.lock
@@ -540,3 +540,8 @@ vite@^2.1.2:
rollup "^2.38.5"
optionalDependencies:
fsevents "~2.3.1"
+
+wouter@^2.7.4:
+ version "2.7.4"
+ resolved "https://registry.yarnpkg.com/wouter/-/wouter-2.7.4.tgz#d528122cacf6e9805d7b953bbddfb90226850977"
+ integrity sha512-shJIsHR+gcn69L2zR+0eKquOvAcjfIEdhzf8iAP502DlrAwg5lO2Q90DqIvXryNz/mk1fe2crTB40ZHXjoF1Bg==
diff --git a/package.json b/package.json
index d3c0931a3c..90d687f20d 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,7 @@
"scripts": {
"build": "bic",
"clean": "lerna exec --parallel --no-bail -- rimraf node_modules dist .rpt2_cache .bic_cache",
- "prepare": "cd ./demo && yarn && cd ../ && yarn build && node ./scripts/prepare.js",
+ "prepare": "yarn build && node ./scripts/prepare.js",
"release": "node ./scripts/release.js",
"test": "jest",
"test:cov": "jest --coverage",