react-magazine 1.0.0 → 1.0.1
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/LICENSE +21 -21
- package/README.md +238 -205
- package/dist/styles.css +164 -164
- package/package.json +80 -80
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Gnanaprakash
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Gnanaprakash
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,205 +1,238 @@
|
|
|
1
|
-
# react-magazine
|
|
2
|
-
|
|
3
|
-
React component for creating realistic magazine-style page flip animations with built-in controls and full TypeScript support.
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
|
112
|
-
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
|
139
|
-
|
|
140
|
-
| `
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
|
145
|
-
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
1
|
+
# react-magazine
|
|
2
|
+
|
|
3
|
+
React component for creating realistic magazine-style page flip animations with built-in controls and full TypeScript support.
|
|
4
|
+
|
|
5
|
+
## Demo
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install react-magazine
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { MagazineBook, Page } from 'react-magazine';
|
|
19
|
+
import 'react-magazine/styles.css';
|
|
20
|
+
|
|
21
|
+
const images = [
|
|
22
|
+
"https://picsum.photos/id/1/400/500",
|
|
23
|
+
"https://picsum.photos/id/2/400/500",
|
|
24
|
+
"https://picsum.photos/id/3/400/500",
|
|
25
|
+
"https://picsum.photos/id/4/400/500",
|
|
26
|
+
"https://picsum.photos/id/5/400/500",
|
|
27
|
+
"https://picsum.photos/id/6/400/500",
|
|
28
|
+
"https://picsum.photos/id/7/400/500",
|
|
29
|
+
"https://picsum.photos/id/8/400/500",
|
|
30
|
+
"https://picsum.photos/id/9/400/500",
|
|
31
|
+
"https://picsum.photos/id/10/400/500",
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
function App() {
|
|
35
|
+
return (
|
|
36
|
+
<MagazineBook width={400} height={500} showCover={true} showControls={true}>
|
|
37
|
+
{images.map((img, index) => (
|
|
38
|
+
<Page key={index} number={index + 1}>
|
|
39
|
+
<img
|
|
40
|
+
src={img}
|
|
41
|
+
alt={`Page ${index + 1}`}
|
|
42
|
+
style={{
|
|
43
|
+
width: "100%",
|
|
44
|
+
height: "100%",
|
|
45
|
+
objectFit: "cover",
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
</Page>
|
|
49
|
+
))}
|
|
50
|
+
</MagazineBook>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Features
|
|
56
|
+
|
|
57
|
+
- Realistic page flip animation
|
|
58
|
+
- Built-in navigation controls
|
|
59
|
+
- Hard/soft page density support
|
|
60
|
+
- Responsive design (fixed/stretch modes)
|
|
61
|
+
- Portrait and landscape orientation
|
|
62
|
+
- Touch and mouse support
|
|
63
|
+
- TypeScript support
|
|
64
|
+
- SSR compatible (with dynamic import)
|
|
65
|
+
|
|
66
|
+
## Using the useFlipBook Hook
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { MagazineBook, Page, useFlipBook } from 'react-magazine';
|
|
70
|
+
import 'react-magazine/styles.css';
|
|
71
|
+
|
|
72
|
+
const images = [
|
|
73
|
+
"https://picsum.photos/id/1/400/500",
|
|
74
|
+
"https://picsum.photos/id/2/400/500",
|
|
75
|
+
"https://picsum.photos/id/3/400/500",
|
|
76
|
+
"https://picsum.photos/id/4/400/500",
|
|
77
|
+
"https://picsum.photos/id/5/400/500",
|
|
78
|
+
"https://picsum.photos/id/6/400/500",
|
|
79
|
+
"https://picsum.photos/id/7/400/500",
|
|
80
|
+
"https://picsum.photos/id/8/400/500",
|
|
81
|
+
"https://picsum.photos/id/9/400/500",
|
|
82
|
+
"https://picsum.photos/id/10/400/500",
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
function App() {
|
|
86
|
+
const { bookRef, state, flipNext, flipPrev, handlers } = useFlipBook();
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<div>
|
|
90
|
+
<MagazineBook ref={bookRef} width={400} height={500} {...handlers}>
|
|
91
|
+
<Page number={1}>Page 1</Page>
|
|
92
|
+
<Page number={2}>Page 2</Page>
|
|
93
|
+
<Page number={3}>Page 3</Page>
|
|
94
|
+
<Page number={4}>Page 4</Page>
|
|
95
|
+
</MagazineBook>
|
|
96
|
+
<button onClick={() => flipPrev()}>Previous</button>
|
|
97
|
+
<span>Page {state.currentPage + 1} of {state.pageCount}</span>
|
|
98
|
+
<button onClick={() => flipNext()}>Next</button>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Props
|
|
105
|
+
|
|
106
|
+
### MagazineBook Props
|
|
107
|
+
|
|
108
|
+
| Prop | Type | Default | Description |
|
|
109
|
+
|------|------|---------|-------------|
|
|
110
|
+
| `width` | `number` | `400` | Page width in pixels |
|
|
111
|
+
| `height` | `number` | `300` | Page height in pixels |
|
|
112
|
+
| `size` | `'fixed' \| 'stretch'` | `'fixed'` | Size mode |
|
|
113
|
+
| `startPage` | `number` | `0` | Starting page index |
|
|
114
|
+
| `showCover` | `boolean` | `false` | Makes first & last pages hard (like book covers) |
|
|
115
|
+
| `showControls` | `boolean` | `false` | Show built-in navigation controls |
|
|
116
|
+
| `drawShadow` | `boolean` | `true` | Draw shadow when flipping |
|
|
117
|
+
| `flippingTime` | `number` | `1000` | Flip animation duration (ms) |
|
|
118
|
+
| `usePortrait` | `boolean` | `false` | Use portrait mode |
|
|
119
|
+
| `mobileScrollSupport` | `boolean` | `true` | Enable mobile scroll |
|
|
120
|
+
| `swipeDistance` | `number` | `30` | Swipe distance threshold |
|
|
121
|
+
| `showPageCorners` | `boolean` | `true` | Show page corner fold on hover |
|
|
122
|
+
| `disableFlipByClick` | `boolean` | `false` | Disable click to flip |
|
|
123
|
+
| `clickEventForward` | `boolean` | `true` | Forward click events to children |
|
|
124
|
+
| `useMouseEvents` | `boolean` | `true` | Enable mouse/touch events |
|
|
125
|
+
| `maxShadowOpacity` | `number` | `1` | Shadow intensity (0-1) |
|
|
126
|
+
| `autoSize` | `boolean` | `true` | Auto-resize based on container |
|
|
127
|
+
| `isLoading` | `boolean` | `false` | Show loading state |
|
|
128
|
+
| `disabled` | `boolean` | `false` | Disable all interactions |
|
|
129
|
+
| `controlsClassName` | `string` | `''` | Custom class for controls |
|
|
130
|
+
| `controlsStyle` | `CSSProperties` | `{}` | Custom style for controls |
|
|
131
|
+
|
|
132
|
+
### Event Props
|
|
133
|
+
|
|
134
|
+
| Prop | Type | Description |
|
|
135
|
+
|------|------|-------------|
|
|
136
|
+
| `onFlip` | `(e: FlipEvent) => void` | Called when page flips |
|
|
137
|
+
| `onChangeState` | `(e: StateEvent) => void` | Called when state changes |
|
|
138
|
+
| `onChangeOrientation` | `(e: OrientationEvent) => void` | Called when orientation changes |
|
|
139
|
+
| `onInit` | `(e: FlipEvent) => void` | Called when initialized |
|
|
140
|
+
| `onUpdate` | `(e: FlipEvent) => void` | Called when updated |
|
|
141
|
+
|
|
142
|
+
### Page Props
|
|
143
|
+
|
|
144
|
+
| Prop | Type | Default | Description |
|
|
145
|
+
|------|------|---------|-------------|
|
|
146
|
+
| `number` | `number` | - | Page number (for display) |
|
|
147
|
+
| `density` | `'soft' \| 'hard'` | `'soft'` | Page density (soft bends, hard doesn't) |
|
|
148
|
+
| `className` | `string` | `''` | Custom class |
|
|
149
|
+
| `style` | `CSSProperties` | `{}` | Custom style |
|
|
150
|
+
|
|
151
|
+
## showCover Behavior
|
|
152
|
+
|
|
153
|
+
When `showCover={true}`:
|
|
154
|
+
- First page automatically becomes **hard** (doesn't bend)
|
|
155
|
+
- Last page automatically becomes **hard** (doesn't bend)
|
|
156
|
+
- All inner pages remain **soft** (paper flip effect)
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
<MagazineBook showCover={true}>
|
|
160
|
+
<Page>Front Cover (auto hard)</Page>
|
|
161
|
+
<Page>Page 2 (soft - bends)</Page>
|
|
162
|
+
<Page>Page 3 (soft - bends)</Page>
|
|
163
|
+
<Page>Back Cover (auto hard)</Page>
|
|
164
|
+
</MagazineBook>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Ref API Methods
|
|
168
|
+
|
|
169
|
+
Access via `bookRef.current`:
|
|
170
|
+
|
|
171
|
+
| Method | Description |
|
|
172
|
+
|--------|-------------|
|
|
173
|
+
| `flipNext(corner?)` | Flip to next page |
|
|
174
|
+
| `flipPrev(corner?)` | Flip to previous page |
|
|
175
|
+
| `flip(pageNum, corner?)` | Flip to specific page with animation |
|
|
176
|
+
| `turnToPage(pageNum)` | Jump to page without animation |
|
|
177
|
+
| `getCurrentPageIndex()` | Get current page index (0-based) |
|
|
178
|
+
| `getPageCount()` | Get total page count |
|
|
179
|
+
| `getOrientation()` | Get current orientation |
|
|
180
|
+
| `getState()` | Get current state |
|
|
181
|
+
| `pageFlip()` | Get underlying PageFlip instance |
|
|
182
|
+
|
|
183
|
+
## useFlipBook Hook
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
|
|
187
|
+
| Property | Type | Description |
|
|
188
|
+
|----------|------|-------------|
|
|
189
|
+
| `bookRef` | `RefObject` | Ref to attach to MagazineBook |
|
|
190
|
+
| `state` | `object` | `{ currentPage, pageCount, orientation, pageState, isFlipping }` |
|
|
191
|
+
| `flipNext` | `function` | Flip to next page |
|
|
192
|
+
| `flipPrev` | `function` | Flip to previous page |
|
|
193
|
+
| `flipTo` | `function` | Flip to specific page |
|
|
194
|
+
| `turnTo` | `function` | Jump without animation |
|
|
195
|
+
| `canFlipNext` | `function` | Check if can flip next |
|
|
196
|
+
| `canFlipPrev` | `function` | Check if can flip prev |
|
|
197
|
+
| `handlers` | `object` | Event handlers to spread on MagazineBook |
|
|
198
|
+
|
|
199
|
+
## Next.js Usage
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import dynamic from 'next/dynamic';
|
|
203
|
+
|
|
204
|
+
const MagazineBook = dynamic(
|
|
205
|
+
() => import('react-magazine').then((mod) => mod.MagazineBook),
|
|
206
|
+
{ ssr: false }
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const Page = dynamic(
|
|
210
|
+
() => import('react-magazine').then((mod) => mod.Page),
|
|
211
|
+
{ ssr: false }
|
|
212
|
+
);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## TypeScript
|
|
216
|
+
|
|
217
|
+
All types are exported:
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import type {
|
|
221
|
+
PageFlipInstance,
|
|
222
|
+
IFlipSetting,
|
|
223
|
+
IEventProps,
|
|
224
|
+
PageProps,
|
|
225
|
+
FlipEvent,
|
|
226
|
+
OrientationEvent,
|
|
227
|
+
StateEvent,
|
|
228
|
+
PageDensity,
|
|
229
|
+
PageOrientation,
|
|
230
|
+
PageState,
|
|
231
|
+
FlipCorner,
|
|
232
|
+
SizeType,
|
|
233
|
+
} from 'react-magazine';
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## License
|
|
237
|
+
|
|
238
|
+
MIT
|
package/dist/styles.css
CHANGED
|
@@ -1,164 +1,164 @@
|
|
|
1
|
-
/* React Magazine Styles */
|
|
2
|
-
|
|
3
|
-
.react-magazine {
|
|
4
|
-
display: block;
|
|
5
|
-
position: relative;
|
|
6
|
-
user-select: none;
|
|
7
|
-
-webkit-user-select: none;
|
|
8
|
-
-moz-user-select: none;
|
|
9
|
-
-ms-user-select: none;
|
|
10
|
-
touch-action: pan-y;
|
|
11
|
-
box-sizing: border-box;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
.react-magazine canvas {
|
|
15
|
-
display: block;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.react-magazine-page {
|
|
19
|
-
position: relative;
|
|
20
|
-
box-sizing: border-box;
|
|
21
|
-
overflow: hidden;
|
|
22
|
-
background-color: #fff;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/* Page content wrapper */
|
|
26
|
-
.react-magazine-page-content {
|
|
27
|
-
width: 100%;
|
|
28
|
-
height: 100%;
|
|
29
|
-
display: flex;
|
|
30
|
-
flex-direction: column;
|
|
31
|
-
align-items: center;
|
|
32
|
-
justify-content: flex-start;
|
|
33
|
-
padding: 20px;
|
|
34
|
-
box-sizing: border-box;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* Hard page styling */
|
|
38
|
-
.react-magazine-page[data-density="hard"] {
|
|
39
|
-
background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%);
|
|
40
|
-
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/* Page number styling */
|
|
44
|
-
.react-magazine-page-number {
|
|
45
|
-
position: absolute;
|
|
46
|
-
bottom: 10px;
|
|
47
|
-
left: 50%;
|
|
48
|
-
transform: translateX(-50%);
|
|
49
|
-
font-size: 12px;
|
|
50
|
-
color: #666;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/* Cover page styling */
|
|
54
|
-
.react-magazine-cover {
|
|
55
|
-
background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
|
|
56
|
-
color: white;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/* Front cover */
|
|
60
|
-
.react-magazine-cover--front {
|
|
61
|
-
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/* Back cover */
|
|
65
|
-
.react-magazine-cover--back {
|
|
66
|
-
background: linear-gradient(135deg, #0f3460 0%, #16213e 50%, #1a1a2e 100%);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/* Loading state */
|
|
70
|
-
.react-magazine--loading {
|
|
71
|
-
opacity: 0.5;
|
|
72
|
-
pointer-events: none;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/* Disabled state */
|
|
76
|
-
.react-magazine--disabled {
|
|
77
|
-
pointer-events: none;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/* Portrait mode adjustments */
|
|
81
|
-
.react-magazine--portrait .react-magazine-page {
|
|
82
|
-
width: 100%;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/* Landscape mode adjustments */
|
|
86
|
-
.react-magazine--landscape .react-magazine-page {
|
|
87
|
-
width: 50%;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/* Animation classes */
|
|
91
|
-
@keyframes magazine-enter {
|
|
92
|
-
from {
|
|
93
|
-
opacity: 0;
|
|
94
|
-
transform: scale(0.95);
|
|
95
|
-
}
|
|
96
|
-
to {
|
|
97
|
-
opacity: 1;
|
|
98
|
-
transform: scale(1);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.react-magazine--animated {
|
|
103
|
-
animation: magazine-enter 0.3s ease-out;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/* Controls */
|
|
107
|
-
.react-magazine-wrapper {
|
|
108
|
-
display: flex;
|
|
109
|
-
flex-direction: column;
|
|
110
|
-
align-items: center;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.react-magazine-controls {
|
|
114
|
-
display: flex;
|
|
115
|
-
justify-content: center;
|
|
116
|
-
align-items: center;
|
|
117
|
-
gap: 15px;
|
|
118
|
-
margin-top: 8px;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.react-magazine-controls__btn {
|
|
122
|
-
display: flex;
|
|
123
|
-
align-items: center;
|
|
124
|
-
gap: 6px;
|
|
125
|
-
padding: 8px 16px;
|
|
126
|
-
font-size: 13px;
|
|
127
|
-
font-weight: 500;
|
|
128
|
-
border: none;
|
|
129
|
-
border-radius: 6px;
|
|
130
|
-
background: #2196F3;
|
|
131
|
-
color: white;
|
|
132
|
-
cursor: pointer;
|
|
133
|
-
transition: all 0.2s ease;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.react-magazine-controls__btn:hover {
|
|
137
|
-
background: #1976D2;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
.react-magazine-controls__btn:active {
|
|
141
|
-
background: #1565C0;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
.react-magazine-controls__btn:disabled {
|
|
145
|
-
opacity: 0.5;
|
|
146
|
-
cursor: not-allowed;
|
|
147
|
-
background: #90CAF9;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
.react-magazine-controls__btn:disabled:hover {
|
|
151
|
-
background: #90CAF9;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
.react-magazine-controls__btn svg {
|
|
155
|
-
flex-shrink: 0;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.react-magazine-controls__page-info {
|
|
159
|
-
font-size: 13px;
|
|
160
|
-
color: #666;
|
|
161
|
-
padding: 6px 12px;
|
|
162
|
-
background: #f5f5f5;
|
|
163
|
-
border-radius: 4px;
|
|
164
|
-
}
|
|
1
|
+
/* React Magazine Styles */
|
|
2
|
+
|
|
3
|
+
.react-magazine {
|
|
4
|
+
display: block;
|
|
5
|
+
position: relative;
|
|
6
|
+
user-select: none;
|
|
7
|
+
-webkit-user-select: none;
|
|
8
|
+
-moz-user-select: none;
|
|
9
|
+
-ms-user-select: none;
|
|
10
|
+
touch-action: pan-y;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.react-magazine canvas {
|
|
15
|
+
display: block;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.react-magazine-page {
|
|
19
|
+
position: relative;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
background-color: #fff;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Page content wrapper */
|
|
26
|
+
.react-magazine-page-content {
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: 100%;
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
align-items: center;
|
|
32
|
+
justify-content: flex-start;
|
|
33
|
+
padding: 20px;
|
|
34
|
+
box-sizing: border-box;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Hard page styling */
|
|
38
|
+
.react-magazine-page[data-density="hard"] {
|
|
39
|
+
background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%);
|
|
40
|
+
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Page number styling */
|
|
44
|
+
.react-magazine-page-number {
|
|
45
|
+
position: absolute;
|
|
46
|
+
bottom: 10px;
|
|
47
|
+
left: 50%;
|
|
48
|
+
transform: translateX(-50%);
|
|
49
|
+
font-size: 12px;
|
|
50
|
+
color: #666;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* Cover page styling */
|
|
54
|
+
.react-magazine-cover {
|
|
55
|
+
background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
|
|
56
|
+
color: white;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* Front cover */
|
|
60
|
+
.react-magazine-cover--front {
|
|
61
|
+
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* Back cover */
|
|
65
|
+
.react-magazine-cover--back {
|
|
66
|
+
background: linear-gradient(135deg, #0f3460 0%, #16213e 50%, #1a1a2e 100%);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Loading state */
|
|
70
|
+
.react-magazine--loading {
|
|
71
|
+
opacity: 0.5;
|
|
72
|
+
pointer-events: none;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Disabled state */
|
|
76
|
+
.react-magazine--disabled {
|
|
77
|
+
pointer-events: none;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Portrait mode adjustments */
|
|
81
|
+
.react-magazine--portrait .react-magazine-page {
|
|
82
|
+
width: 100%;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Landscape mode adjustments */
|
|
86
|
+
.react-magazine--landscape .react-magazine-page {
|
|
87
|
+
width: 50%;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Animation classes */
|
|
91
|
+
@keyframes magazine-enter {
|
|
92
|
+
from {
|
|
93
|
+
opacity: 0;
|
|
94
|
+
transform: scale(0.95);
|
|
95
|
+
}
|
|
96
|
+
to {
|
|
97
|
+
opacity: 1;
|
|
98
|
+
transform: scale(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.react-magazine--animated {
|
|
103
|
+
animation: magazine-enter 0.3s ease-out;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Controls */
|
|
107
|
+
.react-magazine-wrapper {
|
|
108
|
+
display: flex;
|
|
109
|
+
flex-direction: column;
|
|
110
|
+
align-items: center;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.react-magazine-controls {
|
|
114
|
+
display: flex;
|
|
115
|
+
justify-content: center;
|
|
116
|
+
align-items: center;
|
|
117
|
+
gap: 15px;
|
|
118
|
+
margin-top: 8px;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.react-magazine-controls__btn {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: 6px;
|
|
125
|
+
padding: 8px 16px;
|
|
126
|
+
font-size: 13px;
|
|
127
|
+
font-weight: 500;
|
|
128
|
+
border: none;
|
|
129
|
+
border-radius: 6px;
|
|
130
|
+
background: #2196F3;
|
|
131
|
+
color: white;
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
transition: all 0.2s ease;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.react-magazine-controls__btn:hover {
|
|
137
|
+
background: #1976D2;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.react-magazine-controls__btn:active {
|
|
141
|
+
background: #1565C0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.react-magazine-controls__btn:disabled {
|
|
145
|
+
opacity: 0.5;
|
|
146
|
+
cursor: not-allowed;
|
|
147
|
+
background: #90CAF9;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.react-magazine-controls__btn:disabled:hover {
|
|
151
|
+
background: #90CAF9;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.react-magazine-controls__btn svg {
|
|
155
|
+
flex-shrink: 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.react-magazine-controls__page-info {
|
|
159
|
+
font-size: 13px;
|
|
160
|
+
color: #666;
|
|
161
|
+
padding: 6px 12px;
|
|
162
|
+
background: #f5f5f5;
|
|
163
|
+
border-radius: 4px;
|
|
164
|
+
}
|
package/package.json
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "react-magazine",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "A lightweight React component for realistic page-flip animations, featuring built-in navigation controls, full TypeScript support, and easy style customization.",
|
|
5
|
-
"main": "dist/cjs/index.js",
|
|
6
|
-
"module": "dist/esm/index.js",
|
|
7
|
-
"types": "dist/types/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"import": {
|
|
11
|
-
"types": "./dist/types/index.d.ts",
|
|
12
|
-
"default": "./dist/esm/index.js"
|
|
13
|
-
},
|
|
14
|
-
"require": {
|
|
15
|
-
"types": "./dist/types/index.d.ts",
|
|
16
|
-
"default": "./dist/cjs/index.js"
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
"./styles.css": "./dist/styles.css"
|
|
20
|
-
},
|
|
21
|
-
"files": [
|
|
22
|
-
"dist",
|
|
23
|
-
"README.md",
|
|
24
|
-
"LICENSE"
|
|
25
|
-
],
|
|
26
|
-
"sideEffects": [
|
|
27
|
-
"*.css"
|
|
28
|
-
],
|
|
29
|
-
"scripts": {
|
|
30
|
-
"build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:types && npm run build:css",
|
|
31
|
-
"build:esm": "rollup -c rollup.config.mjs --environment FORMAT:esm",
|
|
32
|
-
"build:cjs": "rollup -c rollup.config.mjs --environment FORMAT:cjs",
|
|
33
|
-
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist/types",
|
|
34
|
-
"build:css": "node -e \"require('fs').mkdirSync('dist', {recursive: true}); require('fs').copyFileSync('src/styles.css', 'dist/styles.css')\"",
|
|
35
|
-
"clean": "node -e \"require('fs').rmSync('dist', {recursive: true, force: true})\"",
|
|
36
|
-
"prepublishOnly": "npm run build"
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"page-flip": "^2.0.7"
|
|
40
|
-
},
|
|
41
|
-
"peerDependencies": {
|
|
42
|
-
"react": "^18.0.0 || ^19.0.0",
|
|
43
|
-
"react-dom": "^18.0.0 || ^19.0.0"
|
|
44
|
-
},
|
|
45
|
-
"devDependencies": {
|
|
46
|
-
"@rollup/plugin-commonjs": "^25.0.7",
|
|
47
|
-
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
48
|
-
"@rollup/plugin-typescript": "^11.1.5",
|
|
49
|
-
"@types/react": "^19.0.0",
|
|
50
|
-
"@types/react-dom": "^19.0.0",
|
|
51
|
-
"react": "^19.0.0",
|
|
52
|
-
"react-dom": "^19.0.0",
|
|
53
|
-
"rollup": "^4.9.0",
|
|
54
|
-
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
55
|
-
"tslib": "^2.6.2",
|
|
56
|
-
"typescript": "^5.3.0"
|
|
57
|
-
},
|
|
58
|
-
"keywords": [
|
|
59
|
-
"react",
|
|
60
|
-
"pageflip",
|
|
61
|
-
"flipbook",
|
|
62
|
-
"magazine",
|
|
63
|
-
"book",
|
|
64
|
-
"page-turn",
|
|
65
|
-
"page-flip",
|
|
66
|
-
"flip-book",
|
|
67
|
-
"typescript",
|
|
68
|
-
"react-component"
|
|
69
|
-
],
|
|
70
|
-
"author": "Gnanaprakash",
|
|
71
|
-
"license": "MIT",
|
|
72
|
-
"homepage": "https://github.com/Gnanaprakash-Dev/react-magazine#readme",
|
|
73
|
-
"bugs": {
|
|
74
|
-
"url": "https://github.com/Gnanaprakash-Dev/react-magazine/issues"
|
|
75
|
-
},
|
|
76
|
-
"repository": {
|
|
77
|
-
"type": "git",
|
|
78
|
-
"url": "git+https://github.com/Gnanaprakash-Dev/react-magazine.git"
|
|
79
|
-
}
|
|
80
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "react-magazine",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "A lightweight React component for realistic page-flip animations, featuring built-in navigation controls, full TypeScript support, and easy style customization.",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
12
|
+
"default": "./dist/esm/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/types/index.d.ts",
|
|
16
|
+
"default": "./dist/cjs/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"./styles.css": "./dist/styles.css"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"sideEffects": [
|
|
27
|
+
"*.css"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "npm run clean && npm run build:esm && npm run build:cjs && npm run build:types && npm run build:css",
|
|
31
|
+
"build:esm": "rollup -c rollup.config.mjs --environment FORMAT:esm",
|
|
32
|
+
"build:cjs": "rollup -c rollup.config.mjs --environment FORMAT:cjs",
|
|
33
|
+
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir dist/types",
|
|
34
|
+
"build:css": "node -e \"require('fs').mkdirSync('dist', {recursive: true}); require('fs').copyFileSync('src/styles.css', 'dist/styles.css')\"",
|
|
35
|
+
"clean": "node -e \"require('fs').rmSync('dist', {recursive: true, force: true})\"",
|
|
36
|
+
"prepublishOnly": "npm run build"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"page-flip": "^2.0.7"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
43
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
47
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
48
|
+
"@rollup/plugin-typescript": "^11.1.5",
|
|
49
|
+
"@types/react": "^19.0.0",
|
|
50
|
+
"@types/react-dom": "^19.0.0",
|
|
51
|
+
"react": "^19.0.0",
|
|
52
|
+
"react-dom": "^19.0.0",
|
|
53
|
+
"rollup": "^4.9.0",
|
|
54
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
55
|
+
"tslib": "^2.6.2",
|
|
56
|
+
"typescript": "^5.3.0"
|
|
57
|
+
},
|
|
58
|
+
"keywords": [
|
|
59
|
+
"react",
|
|
60
|
+
"pageflip",
|
|
61
|
+
"flipbook",
|
|
62
|
+
"magazine",
|
|
63
|
+
"book",
|
|
64
|
+
"page-turn",
|
|
65
|
+
"page-flip",
|
|
66
|
+
"flip-book",
|
|
67
|
+
"typescript",
|
|
68
|
+
"react-component"
|
|
69
|
+
],
|
|
70
|
+
"author": "Gnanaprakash",
|
|
71
|
+
"license": "MIT",
|
|
72
|
+
"homepage": "https://github.com/Gnanaprakash-Dev/react-magazine#readme",
|
|
73
|
+
"bugs": {
|
|
74
|
+
"url": "https://github.com/Gnanaprakash-Dev/react-magazine/issues"
|
|
75
|
+
},
|
|
76
|
+
"repository": {
|
|
77
|
+
"type": "git",
|
|
78
|
+
"url": "git+https://github.com/Gnanaprakash-Dev/react-magazine.git"
|
|
79
|
+
}
|
|
80
|
+
}
|