@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.
@@ -0,0 +1,562 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
3
+
4
+ /**
5
+ * Particle System Type Definitions
6
+ *
7
+ * This file contains all type definitions for the enhanced particle effects system.
8
+ * Supports configurable shapes, animations, presets, and custom particle configurations.
9
+ */
10
+ /**
11
+ * Built-in particle shape presets
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * <LikeButton particleConfig={{ shape: 'star' }} />
16
+ * <LikeButton particleConfig={{ shape: 'heart' }} />
17
+ * <LikeButton particleConfig={{ shape: 'sparkle' }} />
18
+ * ```
19
+ */
20
+ type ParticleShapePreset = "heart" | "star" | "circle" | "square" | "sparkle";
21
+ /**
22
+ * Props passed to particle shape render functions
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const MyShape = ({ size, color, className }: ParticleShapeProps) => (
27
+ * <svg width={size} height={size} className={className}>
28
+ * <circle cx={size/2} cy={size/2} r={size/2} fill={color} />
29
+ * </svg>
30
+ * );
31
+ * ```
32
+ */
33
+ interface ParticleShapeProps {
34
+ /** Size of the shape in pixels */
35
+ size: number;
36
+ /** Color of the shape (hex or CSS color) */
37
+ color: string;
38
+ /** Additional CSS class names */
39
+ className?: string;
40
+ }
41
+ /**
42
+ * Custom particle shape configuration
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * const customShape: CustomParticleShape = {
47
+ * render: ({ size, color }) => (
48
+ * <svg width={size} height={size}>
49
+ * <polygon points="..." fill={color} />
50
+ * </svg>
51
+ * )
52
+ * };
53
+ *
54
+ * <LikeButton particleConfig={{ shape: customShape }} />
55
+ * ```
56
+ */
57
+ interface CustomParticleShape {
58
+ /** Custom render function for the particle shape */
59
+ render: (props: ParticleShapeProps) => React.ReactNode;
60
+ }
61
+ /**
62
+ * Particle shape - either a preset string or custom shape config
63
+ *
64
+ * @example
65
+ * ```tsx
66
+ * // Using preset
67
+ * const shape1: ParticleShape = 'star';
68
+ *
69
+ * // Using custom shape
70
+ * const shape2: ParticleShape = {
71
+ * render: (props) => <MyCustomShape {...props} />
72
+ * };
73
+ * ```
74
+ */
75
+ type ParticleShape = ParticleShapePreset | CustomParticleShape;
76
+ /**
77
+ * Built-in particle effect presets
78
+ *
79
+ * - **burst**: Quick explosion of hearts in all directions (12 particles)
80
+ * - **fountain**: Upward spray effect (10 particles)
81
+ * - **confetti**: Colorful celebration with mixed shapes (15 particles)
82
+ * - **gentle**: Subtle floating effect (6 particles)
83
+ * - **fireworks**: Explosive sparkle effect (16 particles)
84
+ *
85
+ * @example
86
+ * ```tsx
87
+ * <LikeButton particlePreset="burst" />
88
+ * <LikeButton particlePreset="confetti" />
89
+ * <LikeButton particlePreset="fireworks" />
90
+ * ```
91
+ */
92
+ type ParticlePreset = "burst" | "fountain" | "confetti" | "gentle" | "fireworks";
93
+ /**
94
+ * Range configuration for numeric values
95
+ *
96
+ * @example
97
+ * ```tsx
98
+ * const distanceRange: Range = { min: 80, max: 120 };
99
+ * const sizeRange: Range = { min: 1.0, max: 2.0 };
100
+ *
101
+ * <LikeButton particleConfig={{
102
+ * distance: distanceRange,
103
+ * size: sizeRange
104
+ * }} />
105
+ * ```
106
+ */
107
+ interface Range {
108
+ /** Minimum value */
109
+ min: number;
110
+ /** Maximum value */
111
+ max: number;
112
+ }
113
+ /**
114
+ * Complete particle configuration interface.
115
+ * All fields are optional - defaults will be applied.
116
+ *
117
+ * @example
118
+ * ```tsx
119
+ * const config: ParticleConfig = {
120
+ * shape: 'star',
121
+ * colors: ['#FFD700', '#FFA500'],
122
+ * count: 12,
123
+ * speed: 600,
124
+ * distance: { min: 80, max: 120 },
125
+ * spread: 180,
126
+ * spreadOffset: -90,
127
+ * };
128
+ * ```
129
+ */
130
+ interface ParticleConfig {
131
+ /**
132
+ * Particle shape - preset name or custom shape config
133
+ * @default 'heart'
134
+ */
135
+ shape?: ParticleShape;
136
+ /**
137
+ * Array of colors for particles (randomly selected)
138
+ * @default ['#EF4444', '#B9FF14', '#3B82F6']
139
+ */
140
+ colors?: string[];
141
+ /**
142
+ * Number of particles to spawn per click
143
+ * @default 8
144
+ */
145
+ count?: number;
146
+ /**
147
+ * Size range for particles (scale multiplier)
148
+ * Can be a single number or a range
149
+ * @default { min: 1.0, max: 1.5 }
150
+ */
151
+ size?: number | Range;
152
+ /**
153
+ * Animation duration in milliseconds
154
+ * @default 500
155
+ */
156
+ speed?: number;
157
+ /**
158
+ * Distance particles travel in pixels
159
+ * Can be a single number or a range
160
+ * @default { min: 60, max: 100 }
161
+ */
162
+ distance?: number | Range;
163
+ /**
164
+ * Spread angle in degrees (0-360)
165
+ * 360 = full circle, 180 = semicircle, etc.
166
+ * @default 360
167
+ */
168
+ spread?: number;
169
+ /**
170
+ * Starting angle offset in degrees
171
+ * 0 = right, 90 = down, 180 = left, 270 = up
172
+ * @default 0
173
+ */
174
+ spreadOffset?: number;
175
+ /**
176
+ * CSS easing function for particle animation
177
+ * @default 'cubic-bezier(0.22, 1, 0.36, 1)'
178
+ */
179
+ easing?: string;
180
+ /**
181
+ * Whether particles fade out during animation
182
+ * @default true
183
+ */
184
+ fadeOut?: boolean;
185
+ }
186
+ /**
187
+ * Preset configuration type.
188
+ * Used internally to define preset configurations.
189
+ */
190
+ type ParticlePresetConfig = Required<Omit<ParticleConfig, "shape">> & {
191
+ shape: ParticleShapePreset;
192
+ };
193
+
194
+ /** Data structure for a single particle effect */
195
+ interface ParticleData {
196
+ id: string;
197
+ angle: number;
198
+ distance: number;
199
+ scale: number;
200
+ color: string;
201
+ shape: ParticleShape;
202
+ speed: number;
203
+ easing: string;
204
+ fadeOut: boolean;
205
+ }
206
+ /**
207
+ * State object passed to dynamic aria-label functions.
208
+ * Enables internationalization (i18n) support for accessibility labels.
209
+ */
210
+ interface AriaLabelState {
211
+ /** Whether the maximum clicks have been reached */
212
+ isMaxed: boolean;
213
+ /** Number of clicks remaining before max */
214
+ remaining: number;
215
+ /** Current number of clicks by the user */
216
+ clicks: number;
217
+ /** Maximum number of clicks allowed */
218
+ maxClicks: number;
219
+ }
220
+ /**
221
+ * Aria label can be either:
222
+ * - A static string for simple use cases
223
+ * - A function that receives state for dynamic/i18n labels
224
+ *
225
+ * @example
226
+ * ```tsx
227
+ * // Static string
228
+ * ariaLabel="Like this post"
229
+ *
230
+ * // Dynamic function for i18n
231
+ * ariaLabel={({ isMaxed, remaining }) =>
232
+ * isMaxed ? t('likes.maxed') : t('likes.remaining', { count: remaining })
233
+ * }
234
+ * ```
235
+ */
236
+ type AriaLabelProp = string | ((state: AriaLabelState) => string);
237
+ /** Options for the useLikeButton hook */
238
+ interface UseLikeButtonOptions {
239
+ /** Current click count (controlled mode). If not provided, internal state is used. */
240
+ clicks?: number;
241
+ /**
242
+ * Initial click count for uncontrolled mode.
243
+ * Only used on first render; ignored if `clicks` prop is provided.
244
+ * @default 0
245
+ */
246
+ defaultClicks?: number;
247
+ /** Maximum number of clicks allowed per user */
248
+ maxClicks?: number;
249
+ /**
250
+ * Callback when button is clicked.
251
+ * @param clicks - The current click count, after increment
252
+ * @param event - The mouse event that triggered the click
253
+ */
254
+ onClick?: (clicks: number, event: React.MouseEvent<HTMLButtonElement>) => void;
255
+ /**
256
+ * Callback when click count changes. Simpler alternative to onClick for controlled mode.
257
+ * Called with just the new count, ideal for state setters like `onChange={setClicks}`.
258
+ * @param clicks - The new click count
259
+ */
260
+ onChange?: (clicks: number) => void;
261
+ /**
262
+ * Callback when button is right-clicked. Also triggered by Shift+Enter for keyboard accessibility.
263
+ * @param clicks - The current click count, not incremented as right-click does not increment
264
+ * @param event - The mouse or keyboard event that triggered the action
265
+ */
266
+ onRightClick?: (clicks: number, event: React.MouseEvent<HTMLButtonElement> | React.KeyboardEvent<HTMLButtonElement>) => void;
267
+ /** Whether the button is disabled */
268
+ disabled?: boolean;
269
+ /**
270
+ * Show particle effects on click.
271
+ * When false, no particles are spawned or rendered.
272
+ * @default true
273
+ */
274
+ showParticles?: boolean;
275
+ /**
276
+ * Custom aria-label override. Accepts either a static string or a function
277
+ * that receives the current state for dynamic/i18n labels.
278
+ *
279
+ * @example
280
+ * ```tsx
281
+ * // Static string
282
+ * ariaLabel="Like this post"
283
+ *
284
+ * // Dynamic function for i18n support
285
+ * ariaLabel={({ isMaxed, remaining }) =>
286
+ * isMaxed ? t('likes.maxed') : t('likes.remaining', { count: remaining })
287
+ * }
288
+ * ```
289
+ */
290
+ ariaLabel?: AriaLabelProp;
291
+ /**
292
+ * Particle effect preset (burst, fountain, confetti, gentle, fireworks)
293
+ * @example
294
+ * ```tsx
295
+ * useLikeButton({ particlePreset: 'burst' })
296
+ * ```
297
+ */
298
+ particlePreset?: ParticlePreset;
299
+ /**
300
+ * Custom particle configuration (overrides preset)
301
+ * @example
302
+ * ```tsx
303
+ * useLikeButton({
304
+ * particleConfig: {
305
+ * shape: 'star',
306
+ * colors: ['#FFD700', '#FFA500'],
307
+ * count: 12,
308
+ * }
309
+ * })
310
+ * ```
311
+ */
312
+ particleConfig?: Partial<ParticleConfig>;
313
+ }
314
+ /** Default values */
315
+ declare const LIKE_BUTTON_DEFAULTS: {
316
+ readonly maxClicks: 1;
317
+ readonly size: 96;
318
+ readonly fillColor: "#EF4444";
319
+ readonly waveColor: "#B91C1C";
320
+ };
321
+ /** Return type for the useLikeButton hook */
322
+ interface UseLikeButtonReturn {
323
+ /** Current click count */
324
+ clicks: number;
325
+ /** Whether max clicks reached */
326
+ isMaxed: boolean;
327
+ /** Whether button is disabled */
328
+ disabled: boolean;
329
+ /** Fill percentage (0-100) */
330
+ fillPercentage: number;
331
+ /** Active particles to render */
332
+ particles: ParticleData[];
333
+ /** Click handler for the button */
334
+ handleClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
335
+ /** Right-click handler for the button */
336
+ handleRightClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
337
+ /**
338
+ * Keyboard handler for accessibility.
339
+ * Triggers onRightClick when Shift+Enter is pressed.
340
+ */
341
+ handleKeyDown: (e: React.KeyboardEvent<HTMLButtonElement>) => void;
342
+ /** Aria label for accessibility */
343
+ ariaLabel: string;
344
+ /** Whether button has been pressed */
345
+ isPressed: boolean;
346
+ /** Whether onRightClick is provided (for aria-keyshortcuts) */
347
+ hasRightClickAction: boolean;
348
+ }
349
+ /**
350
+ * Headless hook for LikeButton logic.
351
+ * Handles state management, particle spawning, and accessibility.
352
+ *
353
+ * @example
354
+ * ```tsx
355
+ * const { handleClick, clicks, particles, ariaLabel } = useLikeButton({
356
+ * maxClicks: 10,
357
+ * onClick: (count, event) => {
358
+ * console.log('Clicked!', count)
359
+ * // Access event if needed
360
+ * event.stopPropagation()
361
+ * },
362
+ * });
363
+ * ```
364
+ */
365
+ declare function useLikeButton(options?: UseLikeButtonOptions): UseLikeButtonReturn;
366
+
367
+ /** Props passed to custom icon render function */
368
+ interface IconRenderProps {
369
+ /** Suggested icon size in pixels (50% of button size by default) */
370
+ size: number;
371
+ /** Base CSS classes for positioning and transitions */
372
+ className: string;
373
+ /** Whether button is at max clicks */
374
+ isMaxed: boolean;
375
+ /** Current fill percentage (0-100) */
376
+ fillPercentage: number;
377
+ }
378
+ /** Preset shape values */
379
+ type ShapePreset = "circle" | "rounded" | "square";
380
+ /** Custom shape configuration */
381
+ interface CustomShape {
382
+ /** CSS border-radius value (e.g., "1rem", "50%", "1rem 2rem") */
383
+ borderRadius?: string;
384
+ /** CSS clip-path value for custom shapes (e.g., "polygon(...)", "circle(...)") */
385
+ clipPath?: string;
386
+ }
387
+ /** Shape prop type - either a preset or custom configuration */
388
+ type Shape = ShapePreset | CustomShape;
389
+ /** Preset cursor values */
390
+ type CursorPreset = "heart" | "star" | "thumbs-up" | "pointer" | "none";
391
+ /** Custom cursor configuration */
392
+ interface CustomCursor {
393
+ /**
394
+ * Cursor URL - can be a data URL (SVG/image) or external URL.
395
+ * @example "data:image/svg+xml;utf8,<svg>...</svg>"
396
+ * @example "/cursors/my-cursor.png"
397
+ */
398
+ url: string;
399
+ /** Hotspot X coordinate (default: 16) */
400
+ hotspotX?: number;
401
+ /** Hotspot Y coordinate (default: 16) */
402
+ hotspotY?: number;
403
+ /** Fallback cursor if custom cursor fails to load (default: "pointer") */
404
+ fallback?: "pointer" | "default" | "grab";
405
+ }
406
+ /**
407
+ * Cursor prop type - either a preset string or custom configuration.
408
+ * - "heart" (default): Heart-shaped cursor
409
+ * - "star": Star-shaped cursor
410
+ * - "thumbs-up": Thumbs up cursor
411
+ * - "pointer": Standard pointer cursor (disables custom cursor)
412
+ * - "none": Hides cursor entirely
413
+ * - CustomCursor: Custom cursor with URL and hotspot configuration
414
+ */
415
+ type Cursor = CursorPreset | CustomCursor;
416
+ /** Override brutalist styling */
417
+ interface StyleOverrides {
418
+ /** Border width in pixels (default: 4) */
419
+ borderWidth?: number;
420
+ /** Border color (default: "#111827") */
421
+ borderColor?: string;
422
+ /** Shadow offset in pixels (default: 8) */
423
+ shadowOffset?: number;
424
+ /** Shadow color (default: "#111827") */
425
+ shadowColor?: string;
426
+ /** Background color (default: "white") */
427
+ backgroundColor?: string;
428
+ }
429
+ /**
430
+ * Base props shared between Tailwind and Vanilla CSS versions.
431
+ * Both versions accept identical props for API consistency.
432
+ */
433
+ interface BaseLikeButtonProps extends UseLikeButtonOptions {
434
+ /** Button size in pixels */
435
+ size?: number;
436
+ /** Fill color for the liquid effect */
437
+ fillColor?: string;
438
+ /** Wave color (darker shade for back wave) */
439
+ waveColor?: string;
440
+ /** Additional CSS class name */
441
+ className?: string;
442
+ /**
443
+ * Show animated wave effect on top of the liquid fill.
444
+ * When false, the fill displays as a flat color without wave animation.
445
+ * @default true
446
+ */
447
+ showWaves?: boolean;
448
+ /**
449
+ * Initial/minimum fill percentage shown even before any clicks.
450
+ * Useful for custom shapes with narrow bottoms (e.g., hearts, diamonds)
451
+ * where low fill percentages may be invisible.
452
+ *
453
+ * Valid range: 0-85 (values above 85 will be clamped to 85)
454
+ * @default 0
455
+ * @example
456
+ * // Show 15% minimum fill for a heart shape
457
+ * <LikeButton minFillPercent={15} shape={{ clipPath: "polygon(...)" }} />
458
+ */
459
+ minFillPercent?: number;
460
+ /**
461
+ * Custom icon render function.
462
+ * - If undefined: renders default heart icon
463
+ * - If null: renders no icon
464
+ * - If function: calls with IconRenderProps
465
+ */
466
+ renderIcon?: ((props: IconRenderProps) => React.ReactNode) | null;
467
+ /**
468
+ * Button shape.
469
+ * - Presets: "circle" (default), "rounded", "square"
470
+ * - Custom: { borderRadius?: string, clipPath?: string }
471
+ */
472
+ shape?: Shape;
473
+ /** Override brutalist styling (border, shadow, background) */
474
+ styles?: StyleOverrides;
475
+ /**
476
+ * Cursor displayed when hovering over the button.
477
+ * - "heart" (default): Heart-shaped cursor
478
+ * - "star": Star-shaped cursor
479
+ * - "thumbs-up": Thumbs up cursor
480
+ * - "pointer": Standard pointer cursor
481
+ * - "none": Hides cursor
482
+ * - CustomCursor: { url, hotspotX?, hotspotY?, fallback? }
483
+ */
484
+ cursor?: Cursor;
485
+ }
486
+ /** Props for the LikeButton component (Tailwind version) */
487
+ type LikeButtonProps = BaseLikeButtonProps;
488
+ /** Props for the LikeButton component (Vanilla CSS version) */
489
+ type LikeButtonVanillaProps = BaseLikeButtonProps;
490
+
491
+ /**
492
+ * Default heart icon for LikeButton.
493
+ * Can be used as reference for creating custom icons.
494
+ */
495
+ declare function DefaultHeartIcon({ size, className }: IconRenderProps): react_jsx_runtime.JSX.Element;
496
+
497
+ /**
498
+ * LikeButton - Animated like button with liquid fill and particle effects.
499
+ * This version uses vanilla CSS (no Tailwind dependency).
500
+ *
501
+ * @example
502
+ * ```tsx
503
+ * import { LikeButtonVanilla } from '@fmarlats/react-like-button';
504
+ * import '@fmarlats/react-like-button/styles.css';
505
+ *
506
+ * // Default usage
507
+ * <LikeButtonVanilla onClick={(clicks, event) => console.log('Clicks:', clicks)} />
508
+ *
509
+ * // Custom icon
510
+ * <LikeButtonVanilla renderIcon={({ size }) => <CustomIcon size={size} />} />
511
+ *
512
+ * // Custom shape
513
+ * <LikeButtonVanilla shape="rounded" />
514
+ * <LikeButtonVanilla shape={{ clipPath: "polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)" }} />
515
+ *
516
+ * // Custom styles
517
+ * <LikeButtonVanilla styles={{ shadowOffset: 4, borderWidth: 2 }} />
518
+ *
519
+ * // Custom cursor
520
+ * <LikeButtonVanilla cursor="star" />
521
+ * <LikeButtonVanilla cursor={{ url: "data:image/svg+xml;...", hotspotX: 16, hotspotY: 16 }} />
522
+ *
523
+ * // Minimum fill for custom shapes
524
+ * <LikeButtonVanilla minFillPercent={15} shape={{ clipPath: "polygon(...)" }} />
525
+ *
526
+ * // Particle presets (same API as Tailwind version)
527
+ * <LikeButtonVanilla particlePreset="burst" />
528
+ * <LikeButtonVanilla particlePreset="confetti" />
529
+ * <LikeButtonVanilla particlePreset="fireworks" />
530
+ *
531
+ * // Custom particle configuration
532
+ * <LikeButtonVanilla particleConfig={{
533
+ * shape: 'star',
534
+ * colors: ['#FFD700', '#FFA500'],
535
+ * count: 15,
536
+ * speed: 800
537
+ * }} />
538
+ *
539
+ * // Combine preset with custom config
540
+ * <LikeButtonVanilla
541
+ * particlePreset="burst"
542
+ * particleConfig={{ count: 20 }}
543
+ * />
544
+ * ```
545
+ */
546
+ declare const LikeButtonVanilla: react.ForwardRefExoticComponent<BaseLikeButtonProps & react.RefAttributes<HTMLButtonElement>>;
547
+
548
+ /**
549
+ * Built-in particle effect presets.
550
+ * Each preset provides a distinct visual effect optimized for different use cases.
551
+ *
552
+ * @example
553
+ * ```tsx
554
+ * import { PARTICLE_PRESETS } from '@fmarlats/react-like-button';
555
+ *
556
+ * // Use a preset directly
557
+ * const burstConfig = PARTICLE_PRESETS.burst;
558
+ * ```
559
+ */
560
+ declare const PARTICLE_PRESETS: Record<ParticlePreset, ParticlePresetConfig>;
561
+
562
+ export { type AriaLabelProp, type AriaLabelState, type BaseLikeButtonProps, type Cursor, type CursorPreset, type CustomCursor, type CustomParticleShape, type CustomShape, DefaultHeartIcon, type IconRenderProps, LIKE_BUTTON_DEFAULTS, type LikeButtonProps, LikeButtonVanilla, type LikeButtonVanillaProps, PARTICLE_PRESETS, type ParticleConfig, type ParticleData, type ParticlePreset, type ParticleShape, type ParticleShapePreset, type ParticleShapeProps, type Range, type Shape, type ShapePreset, type StyleOverrides, type UseLikeButtonOptions, type UseLikeButtonReturn, LikeButtonVanilla as default, useLikeButton };
@@ -0,0 +1,16 @@
1
+ import {
2
+ DefaultHeartIcon,
3
+ LIKE_BUTTON_DEFAULTS,
4
+ LikeButtonVanilla,
5
+ PARTICLE_PRESETS,
6
+ useLikeButton
7
+ } from "./chunk-VLFZGMEX.js";
8
+ export {
9
+ DefaultHeartIcon,
10
+ LIKE_BUTTON_DEFAULTS,
11
+ LikeButtonVanilla,
12
+ PARTICLE_PRESETS,
13
+ LikeButtonVanilla as default,
14
+ useLikeButton
15
+ };
16
+ //# sourceMappingURL=vanilla.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json ADDED
@@ -0,0 +1,109 @@
1
+ {
2
+ "name": "@fmarlats/react-like-button",
3
+ "version": "1.1.4",
4
+ "description": "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.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./vanilla": {
16
+ "types": "./dist/vanilla.d.ts",
17
+ "import": "./dist/vanilla.js",
18
+ "require": "./dist/vanilla.cjs"
19
+ },
20
+ "./styles.css": "./dist/styles.css",
21
+ "./like-button.css": "./dist/like-button.css"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "sideEffects": [
27
+ "*.css"
28
+ ],
29
+ "scripts": {
30
+ "build": "tsup && node scripts/build-css.js",
31
+ "dev": "tsup --watch",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "test:coverage": "vitest run --coverage",
35
+ "typecheck": "tsc --noEmit",
36
+ "format": "biome format --write .",
37
+ "format:check": "biome format .",
38
+ "lint": "biome lint .",
39
+ "lint:fix": "biome lint --write .",
40
+ "check": "biome check --write .",
41
+ "ci": "biome ci .",
42
+ "prepublishOnly": "pnpm run ci && pnpm run typecheck && pnpm run test && pnpm run build"
43
+ },
44
+ "devDependencies": {
45
+ "@biomejs/biome": "2.3.10",
46
+ "@testing-library/jest-dom": "^6.6.3",
47
+ "@testing-library/react": "^16.3.0",
48
+ "@types/react": "^19.2.7",
49
+ "@types/react-dom": "^19.2.3",
50
+ "@vitejs/plugin-react": "^4.4.1",
51
+ "jsdom": "^26.1.0",
52
+ "react": "^19.2.3",
53
+ "react-dom": "^19.2.3",
54
+ "tsup": "^8.5.0",
55
+ "typescript": "^5.8.3",
56
+ "vitest": "^3.2.3"
57
+ },
58
+ "keywords": [
59
+ "react",
60
+ "react-component",
61
+ "like-button",
62
+ "like",
63
+ "button",
64
+ "animation",
65
+ "animated-button",
66
+ "particles",
67
+ "particle-effects",
68
+ "liquid-fill",
69
+ "liquid-animation",
70
+ "wave-animation",
71
+ "brutalist",
72
+ "brutalist-design",
73
+ "tailwind",
74
+ "tailwindcss",
75
+ "vanilla-css",
76
+ "typescript",
77
+ "interactive",
78
+ "ui-component",
79
+ "react-ui",
80
+ "engagement",
81
+ "social",
82
+ "heart-button",
83
+ "favorite-button",
84
+ "upvote",
85
+ "rating",
86
+ "feedback",
87
+ "click-animation",
88
+ "micro-interaction",
89
+ "headless-ui",
90
+ "customizable",
91
+ "accessible",
92
+ "a11y",
93
+ "multiple-likes"
94
+ ],
95
+ "author": "Florian MARLATS",
96
+ "license": "MIT",
97
+ "repository": {
98
+ "type": "git",
99
+ "url": "git+https://github.com/fmarlats/react-like-button.git"
100
+ },
101
+ "homepage": "https://github.com/fmarlats/react-like-button#readme",
102
+ "bugs": {
103
+ "url": "https://github.com/fmarlats/react-like-button/issues"
104
+ },
105
+ "peerDependencies": {
106
+ "react": "^18.0.0 || ^19.0.0",
107
+ "react-dom": "^18.0.0 || ^19.0.0"
108
+ }
109
+ }