@fmarlats/react-like-button 1.1.4

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 ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 fmarlats
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.
22
+
package/README.md ADDED
@@ -0,0 +1,482 @@
1
+ # React Like Button
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@fmarlats/react-like-button.svg)](https://www.npmjs.com/package/@fmarlats/react-like-button)
4
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@fmarlats/react-like-button)](https://bundlephobia.com/package/@fmarlats/react-like-button)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ | Custom heart with on complete state | Classic button | Like shaped cursor | Gold stars particle |
9
+ |--------|--------|--------|--------|
10
+ | ![Full heart SVG](docs/header_demos/like_button_heart_svg.gif) | ![Round with sparks](docs/header_demos/like_button_round_sparks.gif) | ![Square with emeralds](docs/header_demos/like_button_square_emerald.gif) | ![Square with stars](docs/header_demos/like_button_square_star.gif) |
11
+
12
+ | Dislike button round | Dislike button square |
13
+ |--------|--------|
14
+ | ![Dislike button round](docs/header_demos/dislike_button_round.gif) | ![Dislike button square](docs/header_demos/dislike_button_square.gif) |
15
+
16
+ _(You can make any kind of reaction buttons really)_
17
+
18
+ _(The gifs are accelerated and chopped, the effects would render better in real life)_
19
+
20
+ Test it yourself: [StackBlitz Playground](https://stackblitz.com/edit/react-like-button-component?file=src%2FApp.tsx)
21
+
22
+ An animated React like button component with configurable multi clicks to fill the button, particle animations on click, all customizable. Supports Tailwind CSS and vanilla CSS. TypeScript-ready and accessible.
23
+
24
+ ## Features
25
+
26
+ - 🎯 **Multi like Fill Animation** - You can click and like multiple times until full (configurable)
27
+ - ✨ **Particle Effects** - 5 built-in presets + full customization when you click
28
+ - 🎭 **Custom Shapes** - Circle, rounded, or custom
29
+ - 🖱️ **Custom Cursors** - Built-in presets (heart, star, thumbs-up) or custom
30
+ - 🎨 **Fully Customizable** - Colors, sizes, styles, and more
31
+ - 📦 **Two Versions** - Tailwind CSS or vanilla CSS
32
+ - ♿ **Accessible** - ARIA labels and keyboard support
33
+ - 📱 **Responsive** - Works on all screen sizes
34
+ - 🔒 **TypeScript** - Full type safety
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ npm install @fmarlats/react-like-button
40
+ # or
41
+ yarn add @fmarlats/react-like-button
42
+ # or
43
+ pnpm add @fmarlats/react-like-button
44
+ ```
45
+
46
+ ## Quick Start
47
+
48
+ ### Tailwind CSS Version
49
+
50
+ ```tsx
51
+ import { LikeButton } from '@fmarlats/react-like-button';
52
+ import '@fmarlats/react-like-button/like-button.css'; // Required for animations
53
+
54
+ function App() {
55
+ return (
56
+ <LikeButton
57
+ onClick={(clicks) => console.log('Total clicks:', clicks)}
58
+ particlePreset="burst"
59
+ />
60
+ );
61
+ }
62
+ ```
63
+
64
+ ### Vanilla CSS Version
65
+
66
+ ```tsx
67
+ import { LikeButtonVanilla } from '@fmarlats/react-like-button';
68
+ import '@fmarlats/react-like-button/styles.css';
69
+
70
+ function App() {
71
+ return (
72
+ <LikeButtonVanilla
73
+ onClick={(clicks) => console.log('Total clicks:', clicks)}
74
+ particlePreset="confetti"
75
+ />
76
+ );
77
+ }
78
+ ```
79
+
80
+ ## Particle Effects
81
+
82
+ ### Disable Particles
83
+
84
+ ```tsx
85
+ // Disable particle effects entirely
86
+ <LikeButton showParticles={false} />
87
+ ```
88
+
89
+ ### Disable Wave Animation
90
+
91
+ ```tsx
92
+ // Disable wave animation (flat fill color)
93
+ <LikeButton showWaves={false} />
94
+
95
+ // Disable both waves and particles for a minimal look
96
+ <LikeButton showWaves={false} showParticles={false} />
97
+ ```
98
+
99
+ ### Built-in Presets
100
+
101
+ Choose from 5 designed particle effects:
102
+
103
+ ```tsx
104
+ // Quick explosion of hearts (12 particles)
105
+ <LikeButton particlePreset="burst" />
106
+
107
+ // Upward spray effect (10 particles)
108
+ <LikeButton particlePreset="fountain" />
109
+
110
+ // Colorful celebration (15 particles)
111
+ <LikeButton particlePreset="confetti" />
112
+
113
+ // Subtle floating effect (6 particles)
114
+ <LikeButton particlePreset="gentle" />
115
+
116
+ // Explosive sparkles (16 particles)
117
+ <LikeButton particlePreset="fireworks" />
118
+ ```
119
+
120
+ ### Custom Particle Configuration
121
+
122
+ Or fully customize particle behavior:
123
+
124
+ ```tsx
125
+ <LikeButton particleConfig={{
126
+ shape: 'star', // 'heart' | 'star' | 'circle' | 'square' | 'sparkle'
127
+ colors: ['#FFD700', '#FFA500'], // Array of colors
128
+ count: 15, // Number of particles
129
+ speed: 600, // Animation duration (ms)
130
+ distance: { min: 80, max: 120 }, // Travel distance (px)
131
+ spread: 180, // Spread angle (degrees)
132
+ spreadOffset: -90, // Starting angle (0=right, 90=down, 180=left, 270=up)
133
+ size: { min: 1.2, max: 2.0 }, // Size range (scale multiplier)
134
+ easing: 'cubic-bezier(0.22, 1, 0.36, 1)', // CSS easing function
135
+ fadeOut: true // Fade out during animation
136
+ }} />
137
+ ```
138
+
139
+ ### Combine Preset with Custom Config
140
+
141
+ Start with a preset and override specific properties:
142
+
143
+ ```tsx
144
+ <LikeButton
145
+ particlePreset="burst"
146
+ particleConfig={{
147
+ count: 20,
148
+ colors: ['#ff0000', '#00ff00', '#0000ff']
149
+ }}
150
+ />
151
+ ```
152
+
153
+ ## Basic Usage
154
+
155
+ ### Click Tracking
156
+
157
+ ```tsx
158
+ <LikeButton
159
+ maxClicks={10}
160
+ onClick={(clicks) => console.log('Clicks:', clicks)}
161
+ onRightClick={(clicks) => console.log('Right click at:', clicks)}
162
+ />
163
+ ```
164
+
165
+ ### Uncontrolled with Initial Value
166
+
167
+ ```tsx
168
+ // Start with 3 clicks already filled
169
+ <LikeButton defaultClicks={3} maxClicks={10} />
170
+ ```
171
+
172
+ ### Controlled Mode
173
+
174
+ ```tsx
175
+ const [clicks, setClicks] = useState(0);
176
+
177
+ // Using onChange (simpler, ideal for state setters)
178
+ <LikeButton
179
+ clicks={clicks}
180
+ onChange={setClicks}
181
+ maxClicks={5}
182
+ />
183
+
184
+ // Using onClick (when you need the event)
185
+ <LikeButton
186
+ clicks={clicks}
187
+ onClick={(newClicks, event) => {
188
+ setClicks(newClicks);
189
+ event.stopPropagation();
190
+ }}
191
+ maxClicks={5}
192
+ />
193
+ ```
194
+
195
+ ### Custom Colors
196
+
197
+ ```tsx
198
+ <LikeButton
199
+ fillColor="#ff0000"
200
+ waveColor="#ff6666"
201
+ size={120}
202
+ />
203
+ ```
204
+
205
+ ### Custom Shapes
206
+
207
+ ```tsx
208
+ // Built-in shapes
209
+ <LikeButton shape="circle" />
210
+ <LikeButton shape="rounded" />
211
+
212
+ // Custom clip-path
213
+ <LikeButton shape={{
214
+ clipPath: "polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)"
215
+ }} />
216
+ ```
217
+
218
+ ### Custom Cursors
219
+
220
+ ```tsx
221
+ // Built-in cursor presets
222
+ <LikeButton cursor="heart" />
223
+ <LikeButton cursor="star" />
224
+ <LikeButton cursor="thumbs-up" />
225
+ <LikeButton cursor="pointer" />
226
+
227
+ // Custom cursor
228
+ <LikeButton cursor={{
229
+ url: "data:image/svg+xml;...",
230
+ hotspotX: 16,
231
+ hotspotY: 16,
232
+ fallback: "pointer"
233
+ }} />
234
+ ```
235
+
236
+ ## Advanced Examples
237
+
238
+ ### Celebration Button
239
+
240
+ Perfect for achievements and milestones:
241
+
242
+ ```tsx
243
+ <LikeButton
244
+ particlePreset="confetti"
245
+ particleConfig={{
246
+ count: 25,
247
+ speed: 1000,
248
+ distance: { min: 100, max: 150 }
249
+ }}
250
+ fillColor="#FFD700"
251
+ size={100}
252
+ />
253
+ ```
254
+
255
+ ### Upvote Button
256
+
257
+ Reddit-style upvote with fountain effect:
258
+
259
+ ```tsx
260
+ <LikeButton
261
+ particlePreset="fountain"
262
+ particleConfig={{
263
+ colors: ['#FF4500'],
264
+ shape: 'star'
265
+ }}
266
+ fillColor="#FF4500"
267
+ shape="rounded"
268
+ />
269
+ ```
270
+
271
+ ### Subtle Favorite
272
+
273
+ Gentle effect for favorites:
274
+
275
+ ```tsx
276
+ <LikeButton
277
+ particlePreset="gentle"
278
+ particleConfig={{
279
+ colors: ['#FFB6C1', '#FFC0CB'],
280
+ fadeOut: true
281
+ }}
282
+ fillColor="#FFB6C1"
283
+ />
284
+ ```
285
+
286
+ ### Custom Shape Particles
287
+
288
+ Create custom particle shapes:
289
+
290
+ ```tsx
291
+ import type { CustomParticleShape } from '@fmarlats/react-like-button';
292
+
293
+ const customDiamond: CustomParticleShape = {
294
+ render: ({ size, color, className }) => (
295
+ <svg width={size} height={size} className={className} viewBox="0 0 24 24">
296
+ <path d="M12 2 L22 12 L12 22 L2 12 Z" fill={color} />
297
+ </svg>
298
+ )
299
+ };
300
+
301
+ <LikeButton particleConfig={{ shape: customDiamond }} />
302
+ ```
303
+
304
+ ## API Reference
305
+
306
+ ### LikeButton Props
307
+
308
+ | Prop | Type | Default | Description |
309
+ |------|------|---------|-------------|
310
+ | `size` | `number` | `80` | Button size in pixels |
311
+ | `fillColor` | `string` | `"#EF4444"` | Fill color (hex or CSS color) |
312
+ | `waveColor` | `string` | `fillColor` | Wave color (defaults to fillColor) |
313
+ | `maxClicks` | `number` | `Infinity` | Maximum number of clicks allowed |
314
+ | `clicks` | `number` | - | Controlled mode: current click count |
315
+ | `defaultClicks` | `number` | `0` | Initial clicks for uncontrolled mode |
316
+ | `onChange` | `(clicks: number) => void` | - | Called with new count (ideal for `setClicks`) |
317
+ | `onClick` | `(clicks: number, event) => void` | - | Click handler with event access |
318
+ | `onRightClick` | `(clicks: number, event) => void` | - | Right-click handler |
319
+ | `shape` | `ShapePreset \| CustomShape` | `"heart"` | Button shape |
320
+ | `cursor` | `CursorPreset \| CustomCursor` | `"heart"` | Cursor style |
321
+ | `styles` | `StyleOverrides` | - | Custom style overrides |
322
+ | `renderIcon` | `(props) => ReactNode` | - | Custom icon renderer |
323
+ | `minFillPercent` | `number` | `5` | Minimum fill percentage |
324
+ | `showParticles` | `boolean` | `true` | Enable/disable particle effects |
325
+ | `showWaves` | `boolean` | `true` | Enable/disable wave animation on fill |
326
+ | `particlePreset` | `ParticlePreset` | - | Particle effect preset |
327
+ | `particleConfig` | `ParticleConfig` | - | Custom particle configuration |
328
+
329
+ ### ParticleConfig
330
+
331
+ | Property | Type | Default | Description |
332
+ |----------|------|---------|-------------|
333
+ | `shape` | `ParticleShape` | `'heart'` | Particle shape |
334
+ | `colors` | `string[]` | `['#EF4444', '#B9FF14', '#3B82F6']` | Particle colors |
335
+ | `count` | `number` | `8` | Number of particles |
336
+ | `size` | `number \| Range` | `{ min: 1.0, max: 1.5 }` | Size multiplier |
337
+ | `speed` | `number` | `500` | Animation duration (ms) |
338
+ | `distance` | `number \| Range` | `{ min: 60, max: 100 }` | Travel distance (px) |
339
+ | `spread` | `number` | `360` | Spread angle (degrees) |
340
+ | `spreadOffset` | `number` | `0` | Starting angle offset |
341
+ | `easing` | `string` | `'cubic-bezier(0.22, 1, 0.36, 1)'` | CSS easing |
342
+ | `fadeOut` | `boolean` | `true` | Fade out animation |
343
+
344
+ ### ParticlePreset
345
+
346
+ | Preset | Shape | Count | Description |
347
+ |--------|-------|-------|-------------|
348
+ | `'burst'` | ❤️ heart | 12 | Quick explosion in all directions |
349
+ | `'fountain'` | ⚫ circle | 10 | Upward spray effect |
350
+ | `'confetti'` | ◼️ square | 15 | Colorful celebration |
351
+ | `'gentle'` | ❤️ heart | 6 | Subtle floating effect |
352
+ | `'fireworks'` | ✨ sparkle | 16 | Explosive sparkles |
353
+
354
+ ### ParticleShape
355
+
356
+ - `'heart'` - Heart shape ❤️
357
+ - `'star'` - Star shape ⭐
358
+ - `'circle'` - Circle shape ⚫
359
+ - `'square'` - Square shape ◼️
360
+ - `'sparkle'` - Sparkle shape ✨
361
+ - `CustomParticleShape` - Custom shape object
362
+
363
+ ## Examples
364
+
365
+ Check out the [examples](./examples) directory for more usage examples.
366
+
367
+ ## Browser Support
368
+
369
+ - Chrome/Edge (latest)
370
+ - Firefox (latest)
371
+ - Safari (latest)
372
+ - Mobile browsers (iOS Safari, Chrome Mobile)
373
+
374
+ ## Performance
375
+
376
+ The particle system is optimized for performance:
377
+ - Particles are removed from DOM after animation
378
+ - CSS transforms for smooth 60fps animations
379
+ - Configurable particle count for performance tuning
380
+
381
+ **Recommendations:**
382
+ - Use 5-20 particles for frequent interactions
383
+ - Use 20-50 particles for special moments
384
+ - Use 50+ particles sparingly (may impact performance on slower devices)
385
+
386
+ ## Accessibility
387
+
388
+ - ARIA labels for screen readers
389
+ - Keyboard support (Enter/Space to click)
390
+ - Particles marked as decorative (`aria-hidden="true"`)
391
+ - Shift+Enter triggers right-click action for keyboard users
392
+
393
+ ## TypeScript
394
+
395
+ Full TypeScript support with comprehensive type definitions:
396
+
397
+ ```tsx
398
+ // Most common types
399
+ import type {
400
+ LikeButtonProps, // Component props
401
+ IconRenderProps, // Custom icon render function props
402
+ ParticleConfig, // Particle configuration
403
+ CustomParticleShape, // Custom particle shape
404
+ } from '@fmarlats/react-like-button';
405
+
406
+ // Hook types (for headless usage)
407
+ import type {
408
+ UseLikeButtonOptions, // Hook options
409
+ UseLikeButtonReturn, // Hook return type
410
+ } from '@fmarlats/react-like-button';
411
+
412
+ // Shape and cursor types
413
+ import type {
414
+ Shape, ShapePreset, CustomShape,
415
+ Cursor, CursorPreset, CustomCursor,
416
+ } from '@fmarlats/react-like-button';
417
+
418
+ // All particle types
419
+ import type {
420
+ ParticlePreset, ParticleShape, ParticleShapePreset,
421
+ ParticleShapeProps, Range,
422
+ } from '@fmarlats/react-like-button';
423
+ ```
424
+
425
+ ## Changelog
426
+
427
+ ### v0.9.3 (Breaking Change)
428
+
429
+ **⚠️ Breaking Change: Renamed `localClicks` to `clicks`**
430
+
431
+ The `localClicks` prop has been renamed to `clicks` for clarity:
432
+
433
+ ```tsx
434
+ // Before
435
+ <LikeButton localClicks={clicks} onClick={(n) => setClicks(n)} />
436
+
437
+ // After
438
+ <LikeButton clicks={clicks} onClick={(n) => setClicks(n)} />
439
+ ```
440
+
441
+ This also affects the `useLikeButton` hook:
442
+ - Option: `localClicks` → `clicks`
443
+ - Return value: `localClicks` → `clicks`
444
+ - `AriaLabelState.localClicks` → `AriaLabelState.clicks`
445
+
446
+ ### v0.9.0 (Breaking Change)
447
+
448
+ **⚠️ Breaking Change for Tailwind Users**
449
+
450
+ The Tailwind CSS version now requires importing a CSS file for animations and hover effects to work:
451
+
452
+ ```tsx
453
+ import { LikeButton } from '@fmarlats/react-like-button';
454
+ import '@fmarlats/react-like-button/like-button.css'; // NEW - Required
455
+ ```
456
+
457
+ **What changed:**
458
+ - Removed inline `<style>` tag injection for better performance and CSP compliance
459
+ - Wave animations and hover/active states are now defined in an external CSS file
460
+ - CSS custom properties are used for dynamic styling
461
+
462
+ **Vanilla CSS users** are not affected - continue importing `@fmarlats/react-like-button/styles.css` as before.
463
+
464
+ ## Contributing
465
+
466
+ Contributions are welcome! Please open an issue or pull request on GitHub.
467
+
468
+ ## License
469
+
470
+ MIT
471
+
472
+ ## Credits
473
+
474
+ Created by [Florian MARLATS](https://github.com/fmarlats)
475
+
476
+ ## Support
477
+
478
+ - 🐛 [Report a bug](https://github.com/fmarlats/react-like-button/issues)
479
+ - 💡 [Request a feature](https://github.com/fmarlats/react-like-button/issues)
480
+ - ⭐ [Star on GitHub](https://github.com/fmarlats/react-like-button)
481
+
482
+