react-three-components 0.1.0 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +205 -61
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,75 +1,219 @@
|
|
|
1
|
-
#
|
|
1
|
+
# react-three-components
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/react-three-components)
|
|
4
|
+
[](https://github.com/juniorxsound/react-three-components/actions/workflows/ci.yml)
|
|
5
|
+
[](https://github.com/juniorxsound/react-three-components/blob/main/LICENSE)
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
3D carousel components for React Three Fiber with gesture support.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
|
9
|
+
## Installation
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
```bash
|
|
12
|
+
npm install react-three-components
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Peer Dependencies
|
|
16
|
+
|
|
17
|
+
This library requires the following peer dependencies:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install react react-dom three @react-three/fiber @react-spring/web @use-gesture/react
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Components
|
|
24
|
+
|
|
25
|
+
### CircularCarousel
|
|
26
|
+
|
|
27
|
+
A 3D carousel that arranges items in a circle and rotates around an axis.
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { Canvas } from "@react-three/fiber";
|
|
31
|
+
import { CircularCarousel, useCarouselContext } from "react-three-components";
|
|
32
|
+
|
|
33
|
+
function Item({ index }: { index: number }) {
|
|
34
|
+
const { activeIndex } = useCarouselContext();
|
|
35
|
+
const isActive = index === activeIndex;
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<mesh>
|
|
39
|
+
<boxGeometry args={[1, 1, 1]} />
|
|
40
|
+
<meshStandardMaterial color={isActive ? "hotpink" : "gray"} />
|
|
41
|
+
</mesh>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function App() {
|
|
46
|
+
return (
|
|
47
|
+
<Canvas>
|
|
48
|
+
<CircularCarousel radius={3} onIndexChange={(i) => console.log(i)}>
|
|
49
|
+
<Item index={0} />
|
|
50
|
+
<Item index={1} />
|
|
51
|
+
<Item index={2} />
|
|
52
|
+
<Item index={3} />
|
|
53
|
+
</CircularCarousel>
|
|
54
|
+
</Canvas>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### Props
|
|
60
|
+
|
|
61
|
+
| Prop | Type | Default | Description |
|
|
62
|
+
|------|------|---------|-------------|
|
|
63
|
+
| `children` | `ReactNode` | required | Carousel items |
|
|
64
|
+
| `radius` | `number` | `3` | Distance from center to items |
|
|
65
|
+
| `axis` | `"x" \| "y" \| "z"` | `"y"` | Rotation axis |
|
|
66
|
+
| `index` | `number` | - | Controlled active index |
|
|
67
|
+
| `defaultIndex` | `number` | `0` | Initial index (uncontrolled) |
|
|
68
|
+
| `onIndexChange` | `(index: number) => void` | - | Called when index changes |
|
|
69
|
+
| `dragEnabled` | `boolean` | `true` | Enable drag gestures |
|
|
70
|
+
| `dragSensitivity` | `number` | auto | Drag sensitivity |
|
|
71
|
+
| `dragAxis` | `"x" \| "y"` | `"x"` | Drag gesture axis |
|
|
72
|
+
| `dragConfig` | `DragConfig` | - | Additional drag options |
|
|
73
|
+
|
|
74
|
+
#### Ref Methods
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
const ref = useRef<CircularCarouselRef>(null);
|
|
78
|
+
|
|
79
|
+
ref.current.next(); // Go to next item
|
|
80
|
+
ref.current.prev(); // Go to previous item
|
|
81
|
+
ref.current.goTo(2); // Go to specific index
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
#### With Navigation Triggers
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
<CircularCarousel>
|
|
88
|
+
<Item index={0} />
|
|
89
|
+
<Item index={1} />
|
|
90
|
+
<Item index={2} />
|
|
91
|
+
|
|
92
|
+
<CircularCarousel.PrevTrigger position={[-2, 0, 0]}>
|
|
93
|
+
<mesh><boxGeometry /><meshBasicMaterial color="blue" /></mesh>
|
|
94
|
+
</CircularCarousel.PrevTrigger>
|
|
95
|
+
|
|
96
|
+
<CircularCarousel.NextTrigger position={[2, 0, 0]}>
|
|
97
|
+
<mesh><boxGeometry /><meshBasicMaterial color="red" /></mesh>
|
|
98
|
+
</CircularCarousel.NextTrigger>
|
|
99
|
+
</CircularCarousel>
|
|
100
|
+
```
|
|
11
101
|
|
|
12
|
-
|
|
102
|
+
---
|
|
13
103
|
|
|
14
|
-
|
|
104
|
+
### LinearCarousel
|
|
15
105
|
|
|
16
|
-
|
|
106
|
+
A carousel that slides items linearly (horizontally or vertically).
|
|
17
107
|
|
|
18
|
-
|
|
108
|
+
```tsx
|
|
109
|
+
import { Canvas } from "@react-three/fiber";
|
|
110
|
+
import { LinearCarousel, useLinearCarouselContext } from "react-three-components";
|
|
19
111
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
112
|
+
function Item({ index }: { index: number }) {
|
|
113
|
+
const { activeIndex } = useLinearCarouselContext();
|
|
114
|
+
const isActive = index === activeIndex;
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<mesh scale={isActive ? 1.2 : 1}>
|
|
118
|
+
<planeGeometry args={[2, 1.5]} />
|
|
119
|
+
<meshBasicMaterial color={isActive ? "hotpink" : "gray"} />
|
|
120
|
+
</mesh>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
27
123
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
124
|
+
function App() {
|
|
125
|
+
return (
|
|
126
|
+
<Canvas>
|
|
127
|
+
<LinearCarousel gap={0.5} direction="horizontal">
|
|
128
|
+
<Item index={0} />
|
|
129
|
+
<Item index={1} />
|
|
130
|
+
<Item index={2} />
|
|
131
|
+
<Item index={3} />
|
|
132
|
+
</LinearCarousel>
|
|
133
|
+
</Canvas>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### Props
|
|
139
|
+
|
|
140
|
+
| Prop | Type | Default | Description |
|
|
141
|
+
|------|------|---------|-------------|
|
|
142
|
+
| `children` | `ReactNode` | required | Carousel items |
|
|
143
|
+
| `gap` | `number` | `0.2` | Space between items |
|
|
144
|
+
| `direction` | `"horizontal" \| "vertical"` | `"horizontal"` | Slide direction |
|
|
145
|
+
| `index` | `number` | - | Controlled active index |
|
|
146
|
+
| `defaultIndex` | `number` | `0` | Initial index (uncontrolled) |
|
|
147
|
+
| `onIndexChange` | `(index: number) => void` | - | Called when index changes |
|
|
148
|
+
| `dragEnabled` | `boolean` | `true` | Enable drag gestures |
|
|
149
|
+
| `dragSensitivity` | `number` | `150` | Drag sensitivity |
|
|
150
|
+
| `dragAxis` | `"x" \| "y"` | auto | Drag axis (derived from direction) |
|
|
151
|
+
| `dragConfig` | `DragConfig` | - | Additional drag options |
|
|
34
152
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
])
|
|
153
|
+
#### Ref Methods
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
const ref = useRef<LinearCarouselRef>(null);
|
|
157
|
+
|
|
158
|
+
ref.current.next(); // Go to next item (bounded)
|
|
159
|
+
ref.current.prev(); // Go to previous item (bounded)
|
|
160
|
+
ref.current.goTo(2); // Go to specific index
|
|
46
161
|
```
|
|
47
162
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
languageOptions: {
|
|
67
|
-
parserOptions: {
|
|
68
|
-
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
|
69
|
-
tsconfigRootDir: import.meta.dirname,
|
|
70
|
-
},
|
|
71
|
-
// other options...
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
])
|
|
163
|
+
> Note: LinearCarousel is bounded (doesn't wrap around), unlike CircularCarousel which loops infinitely.
|
|
164
|
+
|
|
165
|
+
#### With Navigation Triggers
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<LinearCarousel>
|
|
169
|
+
<Item index={0} />
|
|
170
|
+
<Item index={1} />
|
|
171
|
+
<Item index={2} />
|
|
172
|
+
|
|
173
|
+
<LinearCarousel.PrevTrigger position={[-3, 0, 0]}>
|
|
174
|
+
<PrevButton />
|
|
175
|
+
</LinearCarousel.PrevTrigger>
|
|
176
|
+
|
|
177
|
+
<LinearCarousel.NextTrigger position={[3, 0, 0]}>
|
|
178
|
+
<NextButton />
|
|
179
|
+
</LinearCarousel.NextTrigger>
|
|
180
|
+
</LinearCarousel>
|
|
75
181
|
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Context Hooks
|
|
186
|
+
|
|
187
|
+
Access carousel state from any child component:
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
// For CircularCarousel
|
|
191
|
+
import { useCarouselContext } from "react-three-components";
|
|
192
|
+
|
|
193
|
+
const { activeIndex, count, next, prev, goTo } = useCarouselContext();
|
|
194
|
+
|
|
195
|
+
// For LinearCarousel
|
|
196
|
+
import { useLinearCarouselContext } from "react-three-components";
|
|
197
|
+
|
|
198
|
+
const { activeIndex, count, next, prev, goTo } = useLinearCarouselContext();
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## DragConfig
|
|
202
|
+
|
|
203
|
+
Fine-tune drag behavior:
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
<CircularCarousel
|
|
207
|
+
dragConfig={{
|
|
208
|
+
axis: "x", // Constrain to axis
|
|
209
|
+
threshold: 10, // Pixels before drag starts
|
|
210
|
+
rubberband: 0.2, // Elastic effect at bounds
|
|
211
|
+
touchAction: "pan-y", // CSS touch-action
|
|
212
|
+
pointer: { touch: true }, // Pointer options
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## License
|
|
218
|
+
|
|
219
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-three-components",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "3D carousel components for React Three Fiber",
|
|
5
5
|
"author": "juniorxsound",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/juniorxsound/react-three-components"
|
|
9
|
+
"url": "git+https://github.com/juniorxsound/react-three-components.git"
|
|
10
10
|
},
|
|
11
11
|
"keywords": [
|
|
12
12
|
"react",
|
|
@@ -38,7 +38,10 @@
|
|
|
38
38
|
"lint": "eslint .",
|
|
39
39
|
"storybook": "storybook dev -p 6006",
|
|
40
40
|
"test": "vitest",
|
|
41
|
-
"test:run": "vitest run"
|
|
41
|
+
"test:run": "vitest run",
|
|
42
|
+
"release:patch": "npm run lint && npm run test:run && npm run build && npm version patch -m 'Release %s' && git push && git push --tags",
|
|
43
|
+
"release:minor": "npm run lint && npm run test:run && npm run build && npm version minor -m 'Release %s' && git push && git push --tags",
|
|
44
|
+
"release:major": "npm run lint && npm run test:run && npm run build && npm version major -m 'Release %s' && git push && git push --tags"
|
|
42
45
|
},
|
|
43
46
|
"peerDependencies": {
|
|
44
47
|
"react": ">=18",
|