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.
Files changed (4) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +238 -205
  3. package/dist/styles.css +164 -164
  4. 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
- ## Installation
6
-
7
- ```bash
8
- npm install react-magazine
9
- ```
10
-
11
- ## Quick Start
12
-
13
- ```tsx
14
- import { MagazineBook, Page } from 'react-magazine';
15
- import 'react-magazine/styles.css';
16
-
17
- function App() {
18
- return (
19
- <MagazineBook
20
- width={400}
21
- height={500}
22
- showCover={true}
23
- showControls={true}
24
- >
25
- <Page number={1}>Front Cover</Page>
26
- <Page number={2}>Page 2</Page>
27
- <Page number={3}>Page 3</Page>
28
- <Page number={4}>Back Cover</Page>
29
- </MagazineBook>
30
- );
31
- }
32
- ```
33
-
34
- ## Features
35
-
36
- - Realistic page flip animation
37
- - Built-in navigation controls
38
- - Hard/soft page density support
39
- - Responsive design (fixed/stretch modes)
40
- - Portrait and landscape orientation
41
- - Touch and mouse support
42
- - TypeScript support
43
- - SSR compatible (with dynamic import)
44
-
45
- ## Using the useFlipBook Hook
46
-
47
- ```tsx
48
- import { MagazineBook, Page, useFlipBook } from 'react-magazine';
49
- import 'react-magazine/styles.css';
50
-
51
- function App() {
52
- const { bookRef, state, flipNext, flipPrev, handlers } = useFlipBook();
53
-
54
- return (
55
- <div>
56
- <MagazineBook ref={bookRef} width={400} height={500} {...handlers}>
57
- <Page number={1}>Page 1</Page>
58
- <Page number={2}>Page 2</Page>
59
- <Page number={3}>Page 3</Page>
60
- <Page number={4}>Page 4</Page>
61
- </MagazineBook>
62
-
63
- <p>Page {state.currentPage + 1} of {state.pageCount}</p>
64
- <button onClick={() => flipPrev()}>Previous</button>
65
- <button onClick={() => flipNext()}>Next</button>
66
- </div>
67
- );
68
- }
69
- ```
70
-
71
- ## Props
72
-
73
- ### MagazineBook Props
74
-
75
- | Prop | Type | Default | Description |
76
- |------|------|---------|-------------|
77
- | `width` | `number` | `400` | Page width in pixels |
78
- | `height` | `number` | `300` | Page height in pixels |
79
- | `size` | `'fixed' \| 'stretch'` | `'fixed'` | Size mode |
80
- | `startPage` | `number` | `0` | Starting page index |
81
- | `showCover` | `boolean` | `false` | Makes first & last pages hard (like book covers) |
82
- | `showControls` | `boolean` | `false` | Show built-in navigation controls |
83
- | `drawShadow` | `boolean` | `true` | Draw shadow when flipping |
84
- | `flippingTime` | `number` | `1000` | Flip animation duration (ms) |
85
- | `usePortrait` | `boolean` | `false` | Use portrait mode |
86
- | `mobileScrollSupport` | `boolean` | `true` | Enable mobile scroll |
87
- | `swipeDistance` | `number` | `30` | Swipe distance threshold |
88
- | `showPageCorners` | `boolean` | `true` | Show page corner fold on hover |
89
- | `disableFlipByClick` | `boolean` | `false` | Disable click to flip |
90
- | `clickEventForward` | `boolean` | `true` | Forward click events to children |
91
- | `useMouseEvents` | `boolean` | `true` | Enable mouse/touch events |
92
- | `maxShadowOpacity` | `number` | `1` | Shadow intensity (0-1) |
93
- | `autoSize` | `boolean` | `true` | Auto-resize based on container |
94
- | `isLoading` | `boolean` | `false` | Show loading state |
95
- | `disabled` | `boolean` | `false` | Disable all interactions |
96
- | `controlsClassName` | `string` | `''` | Custom class for controls |
97
- | `controlsStyle` | `CSSProperties` | `{}` | Custom style for controls |
98
-
99
- ### Event Props
100
-
101
- | Prop | Type | Description |
102
- |------|------|-------------|
103
- | `onFlip` | `(e: FlipEvent) => void` | Called when page flips |
104
- | `onChangeState` | `(e: StateEvent) => void` | Called when state changes |
105
- | `onChangeOrientation` | `(e: OrientationEvent) => void` | Called when orientation changes |
106
- | `onInit` | `(e: FlipEvent) => void` | Called when initialized |
107
- | `onUpdate` | `(e: FlipEvent) => void` | Called when updated |
108
-
109
- ### Page Props
110
-
111
- | Prop | Type | Default | Description |
112
- |------|------|---------|-------------|
113
- | `number` | `number` | - | Page number (for display) |
114
- | `density` | `'soft' \| 'hard'` | `'soft'` | Page density (soft bends, hard doesn't) |
115
- | `className` | `string` | `''` | Custom class |
116
- | `style` | `CSSProperties` | `{}` | Custom style |
117
-
118
- ## showCover Behavior
119
-
120
- When `showCover={true}`:
121
- - First page automatically becomes **hard** (doesn't bend)
122
- - Last page automatically becomes **hard** (doesn't bend)
123
- - All inner pages remain **soft** (paper flip effect)
124
-
125
- ```tsx
126
- <MagazineBook showCover={true}>
127
- <Page>Front Cover (auto hard)</Page>
128
- <Page>Page 2 (soft - bends)</Page>
129
- <Page>Page 3 (soft - bends)</Page>
130
- <Page>Back Cover (auto hard)</Page>
131
- </MagazineBook>
132
- ```
133
-
134
- ## Ref API Methods
135
-
136
- Access via `bookRef.current`:
137
-
138
- | Method | Description |
139
- |--------|-------------|
140
- | `flipNext(corner?)` | Flip to next page |
141
- | `flipPrev(corner?)` | Flip to previous page |
142
- | `flip(pageNum, corner?)` | Flip to specific page with animation |
143
- | `turnToPage(pageNum)` | Jump to page without animation |
144
- | `getCurrentPageIndex()` | Get current page index (0-based) |
145
- | `getPageCount()` | Get total page count |
146
- | `getOrientation()` | Get current orientation |
147
- | `getState()` | Get current state |
148
- | `pageFlip()` | Get underlying PageFlip instance |
149
-
150
- ## useFlipBook Hook
151
-
152
- Returns:
153
-
154
- | Property | Type | Description |
155
- |----------|------|-------------|
156
- | `bookRef` | `RefObject` | Ref to attach to MagazineBook |
157
- | `state` | `object` | `{ currentPage, pageCount, orientation, pageState, isFlipping }` |
158
- | `flipNext` | `function` | Flip to next page |
159
- | `flipPrev` | `function` | Flip to previous page |
160
- | `flipTo` | `function` | Flip to specific page |
161
- | `turnTo` | `function` | Jump without animation |
162
- | `canFlipNext` | `function` | Check if can flip next |
163
- | `canFlipPrev` | `function` | Check if can flip prev |
164
- | `handlers` | `object` | Event handlers to spread on MagazineBook |
165
-
166
- ## Next.js Usage
167
-
168
- ```tsx
169
- import dynamic from 'next/dynamic';
170
-
171
- const MagazineBook = dynamic(
172
- () => import('react-magazine').then((mod) => mod.MagazineBook),
173
- { ssr: false }
174
- );
175
-
176
- const Page = dynamic(
177
- () => import('react-magazine').then((mod) => mod.Page),
178
- { ssr: false }
179
- );
180
- ```
181
-
182
- ## TypeScript
183
-
184
- All types are exported:
185
-
186
- ```tsx
187
- import type {
188
- PageFlipInstance,
189
- IFlipSetting,
190
- IEventProps,
191
- PageProps,
192
- FlipEvent,
193
- OrientationEvent,
194
- StateEvent,
195
- PageDensity,
196
- PageOrientation,
197
- PageState,
198
- FlipCorner,
199
- SizeType,
200
- } from 'react-magazine';
201
- ```
202
-
203
- ## License
204
-
205
- MIT
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
+ ![react-magazine demo](video.gif)
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.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
+ }