Skip to content

Commit f7774aa

Browse files
authored
fix: storybook 7 (#202)
* sb init * Autofocus story * chore: deploy storybook on gh pages * chore: cleaning unecessary files * chore: @storybook/react-vite * feat: CameraControls for Setup * fix: removing circular deps * good looking story * fix: talentlessguy review
1 parent 5d69491 commit f7774aa

File tree

13 files changed

+5515
-126
lines changed

13 files changed

+5515
-126
lines changed

.eslintrc.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"plugin:prettier/recommended",
1111
"plugin:react-hooks/recommended",
1212
"plugin:import/errors",
13-
"plugin:import/warnings"
13+
"plugin:import/warnings",
14+
"plugin:storybook/recommended"
1415
],
1516
"plugins": ["@typescript-eslint", "react", "prettier", "react-hooks", "import"],
1617
"parser": "@typescript-eslint/parser",

.github/workflows/release.yml

+20-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,28 @@ jobs:
1717
- uses: actions/setup-node@v3
1818
with:
1919
cache: 'yarn'
20-
- id: main
21-
run: |
20+
- run: |
2221
yarn install --frozen-lockfile
2322
yarn release
23+
yarn build-storybook
2424
env:
2525
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
2626
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
27+
- uses: actions/upload-pages-artifact@v1
28+
with:
29+
path: ./storybook-static
30+
31+
# See: https://github.com/actions/deploy-pages
32+
deploy-job:
33+
needs: release-job
34+
permissions:
35+
pages: write
36+
id-token: write
37+
environment:
38+
name: github-pages
39+
url: ${{ steps.deployment.outputs.page_url }}
40+
runs-on: ubuntu-latest
41+
steps:
42+
- name: Deploy to GitHub Pages
43+
id: deployment
44+
uses: actions/deploy-pages@v1

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ yarn-error.log
1616
.size-snapshot.json
1717
pnpm-debug.log
1818
.parcel-cache
19-
pnpm-lock.yaml
19+
pnpm-lock.yaml
20+
storybook-static

.storybook/Setup.tsx

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as React from 'react'
2+
import { Vector3 } from 'three'
3+
import { Canvas, Props as CanvasProps } from '@react-three/fiber'
4+
5+
import { CameraControls } from '@react-three/drei'
6+
7+
type Props = React.PropsWithChildren<
8+
CanvasProps & {
9+
cameraFov?: number
10+
cameraPosition?: Vector3
11+
controls?: boolean
12+
lights?: boolean
13+
}
14+
>
15+
16+
export const Setup = ({
17+
children,
18+
cameraFov = 75,
19+
cameraPosition = new Vector3(-5, 5, 5),
20+
controls = true,
21+
lights = true,
22+
...restProps
23+
}: Props) => (
24+
<div style={{ height: '100%' }}>
25+
<Canvas shadows camera={{ position: cameraPosition, fov: cameraFov }} {...restProps}>
26+
{children}
27+
{lights && (
28+
<>
29+
<ambientLight intensity={0.8} />
30+
<pointLight intensity={1} position={[0, 6, 0]} />
31+
</>
32+
)}
33+
{controls && <CameraControls makeDefault />}
34+
</Canvas>
35+
</div>
36+
)

.storybook/index.css

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
html,
2+
body,
3+
#storybook-root {
4+
height: 100%;
5+
}
6+
7+
.sbdocs canvas {
8+
min-height: 20rem;
9+
}

.storybook/main.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { StorybookConfig } from '@storybook/react-vite'
2+
3+
const config: StorybookConfig = {
4+
stories: ['./stories/**/*.mdx', './stories/**/*.stories.@(js|jsx|ts|tsx)'],
5+
addons: ['@storybook/addon-links', '@storybook/addon-essentials', '@storybook/addon-interactions'],
6+
framework: {
7+
name: '@storybook/react-vite',
8+
options: {},
9+
},
10+
async viteFinal(config, options) {
11+
// Add your configuration here
12+
return config
13+
},
14+
staticDirs: ['./public'],
15+
docs: {
16+
autodocs: 'tag',
17+
},
18+
}
19+
export default config

.storybook/preview.tsx

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react'
2+
import type { Preview } from '@storybook/react'
3+
4+
import './index.css'
5+
6+
const preview: Preview = {
7+
parameters: {
8+
// actions: { argTypesRegex: '^on[A-Z].*' },
9+
// controls: {
10+
// matchers: {
11+
// color: /(background|color)$/i,
12+
// date: /Date$/,
13+
// },
14+
// },
15+
layout: 'fullscreen',
16+
},
17+
decorators: [
18+
(Story) => (
19+
<React.Suspense fallback={null}>
20+
<Story />
21+
</React.Suspense>
22+
),
23+
],
24+
}
25+
26+
export default preview

.storybook/public/suzi.gltf

+112
Large diffs are not rendered by default.
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React, { memo } from 'react'
2+
import * as THREE from 'three'
3+
import type { Meta, StoryObj } from '@storybook/react'
4+
import { useGLTF, Center, Resize, AccumulativeShadows, RandomizedLight, Environment, Stats } from '@react-three/drei'
5+
6+
import { Setup } from '../Setup'
7+
import { EffectComposer, Autofocus } from '../../src'
8+
9+
// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction
10+
const meta = {
11+
title: 'Effect/Autofocus',
12+
component: Autofocus,
13+
decorators: [
14+
(Story) => (
15+
<Setup cameraPosition={new THREE.Vector3(-17, 1.5, 13)} cameraFov={20} lights={false}>
16+
{Story()}
17+
</Setup>
18+
),
19+
],
20+
tags: ['autodocs'],
21+
// argTypes: {
22+
// debug: {
23+
// control: { type: 'range', min: 0, max: 1, step: 0.01 },
24+
// },
25+
// },
26+
} satisfies Meta<typeof Autofocus>
27+
28+
export default meta
29+
type Story = StoryObj<typeof meta>
30+
31+
// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args
32+
export const Primary: Story = {
33+
render: (args) => (
34+
<>
35+
<color attach="background" args={['#303035']} />
36+
37+
<group position-y={-0.5} position-x={-1}>
38+
<Center top>
39+
<Resize scale={3.5}>
40+
<Suzi rotation={[-0.63, 0, 0]}>
41+
<meshStandardMaterial color="#9d4b4b" />
42+
</Suzi>
43+
</Resize>
44+
</Center>
45+
<Center top position={[-2, 0, 2]}>
46+
<mesh castShadow>
47+
<sphereGeometry args={[0.5, 64, 64]} />
48+
<meshStandardMaterial color="#9d4b4b" />
49+
</mesh>
50+
</Center>
51+
<Center top position={[2.5, 0, 1]}>
52+
<mesh castShadow rotation={[0, Math.PI / 4, 0]}>
53+
<boxGeometry args={[0.7, 0.7, 0.7]} />
54+
<meshStandardMaterial color="#9d4b4b" />
55+
</mesh>
56+
</Center>
57+
58+
<Shadows />
59+
<Environment preset="city" />
60+
<Stats />
61+
</group>
62+
63+
<EffectComposer>
64+
<Autofocus {...args} />
65+
</EffectComposer>
66+
</>
67+
),
68+
args: {
69+
mouse: true,
70+
debug: 0.04,
71+
bokehScale: 8,
72+
focusRange: 0.001,
73+
},
74+
}
75+
76+
const Suzi = ({ children, ...props }) => {
77+
console.log(import.meta.url)
78+
const { nodes } = useGLTF('/suzi.gltf') as any
79+
return (
80+
<>
81+
<mesh castShadow receiveShadow geometry={nodes.Suzanne.geometry} {...props}>
82+
{children}
83+
</mesh>
84+
</>
85+
)
86+
}
87+
88+
const Shadows = memo(() => (
89+
<AccumulativeShadows temporal frames={100} color="#9d4b4b" colorBlend={0.5} alphaTest={0.9} scale={20}>
90+
<RandomizedLight amount={8} radius={4} position={[5, 5, -10]} />
91+
</AccumulativeShadows>
92+
))

.storybook/stories/assets/repo.svg

+1
Loading

package.json

+16-2
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
"test": "echo no tests yet",
4343
"typecheck": "tsc --noEmit --emitDeclarationOnly false --strict --jsx react",
4444
"typegen": "tsc --emitDeclarationOnly || true",
45-
"release": "semantic-release"
45+
"release": "semantic-release",
46+
"storybook": "storybook dev -p 6006",
47+
"build-storybook": "storybook build"
4648
},
4749
"dependencies": {
4850
"maath": "^0.5.3",
@@ -51,10 +53,19 @@
5153
"three-stdlib": "^2.21.10"
5254
},
5355
"devDependencies": {
56+
"@react-three/drei": "^9.68.2",
5457
"@react-three/fiber": "^8.13.0",
58+
"@rollup/plugin-babel": "^6.0.3",
5559
"@rollup/plugin-commonjs": "^24.1.0",
5660
"@rollup/plugin-node-resolve": "^15.0.2",
5761
"@rollup/plugin-typescript": "^11.1.0",
62+
"@storybook/addon-essentials": "^7.0.10",
63+
"@storybook/addon-interactions": "^7.0.10",
64+
"@storybook/addon-links": "^7.0.10",
65+
"@storybook/blocks": "^7.0.10",
66+
"@storybook/react": "^7.0.10",
67+
"@storybook/react-vite": "^7.0.11",
68+
"@storybook/testing-library": "^0.0.14-next.2",
5869
"@types/react": "^18.2.0",
5970
"@types/react-dom": "^18.2.1",
6071
"@types/three": "^0.150.2",
@@ -67,6 +78,7 @@
6778
"eslint-plugin-prettier": "^4.2.1",
6879
"eslint-plugin-react": "^7.32.2",
6980
"eslint-plugin-react-hooks": "^4.6.0",
81+
"eslint-plugin-storybook": "^0.6.12",
7082
"husky": "^8.0.3",
7183
"lint-staged": "^13.2.2",
7284
"prettier": "^2.8.8",
@@ -76,8 +88,10 @@
7688
"rollup": "^3.21.0",
7789
"rollup-plugin-filesize": "^10.0.0",
7890
"semantic-release": "^21.0.2",
91+
"storybook": "^7.0.10",
7992
"three": "^0.151.3",
80-
"typescript": "^5.0.4"
93+
"typescript": "^5.0.4",
94+
"vite": "^4.3.5"
8195
},
8296
"peerDependencies": {
8397
"@react-three/fiber": ">=8.0",

src/effects/Autofocus.tsx

+12-6
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,22 @@ import React, {
1010
RefObject,
1111
useMemo,
1212
} from 'react'
13-
import { useThree, useFrame, createPortal } from '@react-three/fiber'
13+
import { useThree, useFrame, createPortal, Vector3 } from '@react-three/fiber'
1414
import { CopyPass, DepthPickingPass, DepthOfFieldEffect } from 'postprocessing'
15-
import { DepthOfField, EffectComposerContext } from '..'
1615
import { easing } from 'maath'
1716

18-
export type AutofocusProps = typeof DepthOfField & {
19-
target?: [number, number, number]
17+
import { DepthOfField } from './DepthOfField'
18+
import { EffectComposerContext } from '../EffectComposer'
19+
20+
export type AutofocusProps = React.ComponentProps<typeof DepthOfField> & {
21+
target?: Vector3
22+
/** should the target follow the pointer */
2023
mouse?: boolean
24+
/** size of the debug green point */
2125
debug?: number
26+
/** manual update */
2227
manual?: boolean
28+
/** approximate time to reach the target */
2329
smoothTime?: number
2430
}
2531

@@ -31,7 +37,7 @@ export type AutofocusApi = {
3137

3238
export const Autofocus = forwardRef<AutofocusApi, AutofocusProps>(
3339
(
34-
{ target = undefined, mouse: followMouse = false, debug = undefined, manual = false, smoothTime = 0, ...props },
40+
{ target = undefined, mouse: followMouse = false, debug = undefined, manual = false, smoothTime = 0.25, ...props },
3541
fref
3642
) => {
3743
const dofRef = useRef<DepthOfFieldEffect>(null)
@@ -80,7 +86,7 @@ export const Autofocus = forwardRef<AutofocusApi, AutofocusProps>(
8086
async (delta: number, updateTarget = true) => {
8187
// Update hitpoint
8288
if (target) {
83-
hitpoint.set(...target)
89+
hitpoint.set(...(target as [number, number, number]))
8490
} else {
8591
const { x, y } = followMouse ? pointer : { x: 0, y: 0 }
8692
const hit = await getHit(x, y)

0 commit comments

Comments
 (0)