@jepepa/like-button 0.8.0

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 @@
1
+ {"version":3,"sources":["../src/LikeButton/DefaultHeartIcon.tsx","../src/LikeButton/LikeButton.tsx","../src/Particle/shapes/CircleShape.tsx","../src/Particle/shapes/HeartShape.tsx","../src/Particle/shapes/SparkleShape.tsx","../src/Particle/shapes/SquareShape.tsx","../src/Particle/shapes/StarShape.tsx","../src/Particle/shapes/utils.ts","../src/Particle/useParticle.ts","../src/Particle/Particle.tsx","../src/LikeButton/useLikeButton.ts","../src/Particle/presets.ts","../src/Particle/utils.ts","../src/LikeButton/utils.ts","../src/LikeButton/LikeButton.vanilla.tsx","../src/Particle/Particle.vanilla.tsx"],"sourcesContent":["import type { IconRenderProps } from \"./types\"\n\n/**\n * Default heart icon for LikeButton.\n * Can be used as reference for creating custom icons.\n */\nexport function DefaultHeartIcon({ size, className }: IconRenderProps) {\n return (\n <svg\n className={className}\n style={{\n width: size,\n height: size,\n stroke: \"#111827\",\n strokeWidth: 2,\n fill: \"transparent\",\n }}\n viewBox=\"0 0 24 24\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z\"\n />\n </svg>\n )\n}\n\nexport default DefaultHeartIcon\n","import { useId, useMemo } from \"react\"\nimport { Particle } from \"../Particle/Particle\"\nimport { DefaultHeartIcon } from \"./DefaultHeartIcon\"\nimport type { LikeButtonProps } from \"./types\"\nimport { LIKE_BUTTON_DEFAULTS, useLikeButton } from \"./useLikeButton\"\nimport {\n computeButtonStyles,\n computeHoverOffset,\n DEFAULT_STYLES,\n generateDynamicStyles,\n getCursorStyle,\n getShapeStyles,\n} from \"./utils\"\n\nexport type { LikeButtonProps }\n\n// Maximum fill height percentage (leaves room for wave animation at top)\nconst MAX_FILL_HEIGHT = 85\n\n/**\n * LikeButton - Animated like button with liquid fill and particle effects.\n * This version uses Tailwind CSS for styling.\n *\n * @example\n * ```tsx\n * // Default heart button\n * <LikeButton onClick={(clicks) => console.log('Clicks:', clicks)} />\n *\n * // Custom icon\n * <LikeButton renderIcon={({ size }) => <CustomIcon size={size} />} />\n *\n * // Custom shape\n * <LikeButton shape=\"rounded\" />\n * <LikeButton shape={{ clipPath: \"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)\" }} />\n *\n * // Custom styles\n * <LikeButton styles={{ shadowOffset: 4, borderWidth: 2 }} />\n *\n * // Custom cursor\n * <LikeButton cursor=\"star\" />\n * <LikeButton cursor=\"pointer\" /> // Standard pointer\n * <LikeButton cursor={{ url: \"data:image/svg+xml;...\", hotspotX: 16, hotspotY: 16 }} />\n *\n * // Minimum fill for custom shapes\n * <LikeButton minFillPercent={15} shape={{ clipPath: \"polygon(...)\" }} />\n *\n * // Particle presets\n * <LikeButton particlePreset=\"burst\" />\n * <LikeButton particlePreset=\"confetti\" />\n * <LikeButton particlePreset=\"fireworks\" />\n *\n * // Custom particle configuration\n * <LikeButton particleConfig={{\n * shape: 'star',\n * colors: ['#FFD700', '#FFA500'],\n * count: 15,\n * speed: 800\n * }} />\n *\n * // Combine preset with custom config\n * <LikeButton\n * particlePreset=\"burst\"\n * particleConfig={{ count: 20, colors: ['#ff0000'] }}\n * />\n *\n * // Advanced particle configuration\n * <LikeButton particleConfig={{\n * shape: 'sparkle',\n * count: 12,\n * speed: 600,\n * distance: { min: 80, max: 120 },\n * spread: 180,\n * spreadOffset: -90, // Upward spray\n * size: { min: 1.2, max: 2.0 },\n * easing: 'cubic-bezier(0.22, 1, 0.36, 1)',\n * fadeOut: true\n * }} />\n * ```\n */\nexport function LikeButton({\n size = LIKE_BUTTON_DEFAULTS.size,\n fillColor = LIKE_BUTTON_DEFAULTS.fillColor,\n waveColor = LIKE_BUTTON_DEFAULTS.waveColor,\n className = \"\",\n showParticles = true,\n renderIcon,\n shape = \"circle\",\n styles = {},\n cursor = \"heart\",\n minFillPercent = 0,\n ...hookOptions\n}: LikeButtonProps) {\n // Clamp minFillPercent to valid range (0-85)\n const clampedMinFill = Math.max(0, Math.min(MAX_FILL_HEIGHT, minFillPercent))\n // Hooks must be called first and in consistent order\n const reactId = useId()\n const buttonId = `like-button${reactId.replace(/:/g, \"-\")}`\n\n const {\n handleClick,\n handleRightClick,\n disabled,\n ariaLabel,\n isPressed,\n isMaxed,\n fillPercentage,\n particles,\n } = useLikeButton({ showParticles, ...hookOptions })\n\n // Memoize style computations\n const mergedStyles = useMemo(() => ({ ...DEFAULT_STYLES, ...styles }), [styles])\n\n const shapeStyles = useMemo(() => getShapeStyles(shape), [shape])\n\n const buttonStyle = useMemo(\n () => computeButtonStyles(size, mergedStyles, shapeStyles),\n [size, mergedStyles, shapeStyles],\n )\n\n const hoverShadowOffset = useMemo(\n () => computeHoverOffset(mergedStyles.shadowOffset),\n [mergedStyles.shadowOffset],\n )\n\n const dynamicStyles = useMemo(\n () => `\n @keyframes wave-scroll-left {\n from { transform: translateX(0); }\n to { transform: translateX(-50%); }\n }\n @keyframes wave-scroll-right {\n from { transform: translateX(-50%); }\n to { transform: translateX(0); }\n }\n ${generateDynamicStyles(`#${buttonId}`, hoverShadowOffset, mergedStyles)}\n `,\n [buttonId, hoverShadowOffset, mergedStyles],\n )\n\n // Cursor style (not-allowed when disabled)\n const cursorStyle = useMemo(\n () => (disabled ? \"not-allowed\" : getCursorStyle(cursor)),\n [cursor, disabled],\n )\n\n // Icon configuration\n const iconSize = size * 0.5\n const iconRenderProps = {\n size: iconSize,\n className: \"relative z-20 transition-colors duration-300 pointer-events-none\",\n isMaxed,\n fillPercentage,\n }\n\n const renderedIcon =\n renderIcon === null ? null : renderIcon === undefined ? (\n <DefaultHeartIcon {...iconRenderProps} />\n ) : (\n renderIcon(iconRenderProps)\n )\n\n return (\n <div className=\"relative inline-block\">\n {/* Dynamic styles for hover/active states */}\n <style>{dynamicStyles}</style>\n\n <button\n id={buttonId}\n type=\"button\"\n onClick={handleClick}\n onContextMenu={handleRightClick}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-pressed={isPressed}\n aria-disabled={disabled}\n style={{ ...buttonStyle, cursor: cursorStyle }}\n className={`relative overflow-hidden z-10 border-solid flex items-center justify-center group transition-all focus:outline-none focus-visible:ring-4 focus-visible:ring-primary-dark focus-visible:ring-offset-2 ${className}`}\n >\n {/* Liquid Fill Container */}\n <div\n className=\"absolute bottom-0 left-0 right-0 z-0 transition-[height] duration-500 ease-out\"\n style={{\n backgroundColor: fillColor,\n height: isMaxed\n ? \"100%\"\n : `${clampedMinFill + (fillPercentage / 100) * (MAX_FILL_HEIGHT - clampedMinFill)}%`,\n }}\n >\n {/* Wave 1 (Back Layer) */}\n <div\n className=\"absolute bottom-full left-0 w-[200%] h-4 flex\"\n style={{ animation: \"wave-scroll-left 3s linear infinite\" }}\n >\n {[0, 1].map((i) => (\n <svg\n key={i}\n className=\"w-1/2 h-full fill-current\"\n style={{ color: waveColor }}\n viewBox=\"0 0 100 20\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M0,10 Q25,0 50,10 T100,10 V20 H0 Z\" />\n </svg>\n ))}\n </div>\n\n {/* Wave 2 (Front Layer) */}\n <div\n className=\"absolute bottom-full left-0 w-[200%] h-4 flex\"\n style={{ animation: \"wave-scroll-right 1.5s linear infinite\" }}\n >\n {[0, 1].map((i) => (\n <svg\n key={i}\n className=\"w-1/2 h-full fill-current\"\n style={{ color: fillColor }}\n viewBox=\"0 0 100 20\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M0,10 Q25,5 50,10 T100,10 V20 H0 Z\" />\n </svg>\n ))}\n </div>\n </div>\n\n {/* Icon (customizable via renderIcon prop) */}\n {renderedIcon}\n </button>\n\n {/* Particles */}\n {showParticles && (\n <div\n className=\"absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 pointer-events-none\"\n aria-hidden=\"true\"\n >\n {particles.map((p) => (\n <Particle key={p.id} {...p} />\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default LikeButton\n","import type { ParticleShapeProps } from \"../types\"\n\n/**\n * Circle-shaped particle component.\n * Simple filled circle for clean, minimal effects.\n */\nexport function CircleShape({ size, color, className = \"\" }: ParticleShapeProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n className={`fill-current ${className}`}\n style={{ color }}\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n </svg>\n )\n}\n","import type { ParticleShapeProps } from \"../types\"\n\n/**\n * Heart-shaped particle component.\n * Classic heart shape for like/love interactions.\n */\nexport function HeartShape({ size, color, className = \"\" }: ParticleShapeProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n className={`fill-current ${className}`}\n style={{ color }}\n aria-hidden=\"true\"\n >\n <path d=\"M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z\" />\n </svg>\n )\n}\n","import type { ParticleShapeProps } from \"../types\"\n\n/**\n * Sparkle-shaped particle component.\n * 4-pointed sparkle/diamond for magical, glittery effects.\n */\nexport function SparkleShape({ size, color, className = \"\" }: ParticleShapeProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n className={`fill-current ${className}`}\n style={{ color }}\n aria-hidden=\"true\"\n >\n <path d=\"M12 2l2.5 7.5L22 12l-7.5 2.5L12 22l-2.5-7.5L2 12l7.5-2.5L12 2z\" />\n </svg>\n )\n}\n","import type { ParticleShapeProps } from \"../types\"\n\n/**\n * Square-shaped particle component.\n * Rounded square for geometric, modern effects.\n */\nexport function SquareShape({ size, color, className = \"\" }: ParticleShapeProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n className={`fill-current ${className}`}\n style={{ color }}\n aria-hidden=\"true\"\n >\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\" />\n </svg>\n )\n}\n","import type { ParticleShapeProps } from \"../types\"\n\n/**\n * Star-shaped particle component.\n * Classic 5-pointed star for celebration effects.\n */\nexport function StarShape({ size, color, className = \"\" }: ParticleShapeProps) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n className={`fill-current ${className}`}\n style={{ color }}\n aria-hidden=\"true\"\n >\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n </svg>\n )\n}\n","import type { ParticleShape, ParticleShapeProps } from \"../types\"\nimport { CircleShape } from \"./CircleShape\"\nimport { HeartShape } from \"./HeartShape\"\nimport { SparkleShape } from \"./SparkleShape\"\nimport { SquareShape } from \"./SquareShape\"\nimport { StarShape } from \"./StarShape\"\n\n/**\n * Get the appropriate shape component based on shape configuration.\n *\n * @param shape - Either a preset shape name or custom shape config\n * @returns React component that renders the shape\n *\n * @example\n * ```tsx\n * const ShapeComponent = getParticleShape('star');\n * return <ShapeComponent size={40} color=\"#FFD700\" />;\n * ```\n *\n * @example\n * ```tsx\n * const ShapeComponent = getParticleShape({\n * render: ({ size, color }) => <div style={{ width: size, height: size, background: color }} />\n * });\n * return <ShapeComponent size={40} color=\"#FFD700\" />;\n * ```\n */\nexport function getParticleShape(shape: ParticleShape): React.ComponentType<ParticleShapeProps> {\n // Handle custom shape\n if (typeof shape === \"object\" && \"render\" in shape) {\n // Return a wrapper component that calls the custom render function\n return ({ size, color, className }: ParticleShapeProps) =>\n shape.render({ size, color, className }) as React.ReactElement\n }\n\n // Handle preset shapes\n switch (shape) {\n case \"heart\":\n return HeartShape\n case \"star\":\n return StarShape\n case \"circle\":\n return CircleShape\n case \"square\":\n return SquareShape\n case \"sparkle\":\n return SparkleShape\n default:\n // TypeScript should prevent this, but fallback to heart for safety\n return HeartShape\n }\n}\n","import { useEffect, useState } from \"react\"\nimport type { ParticleShape } from \"./types\"\n\n/** Props for particle components */\nexport interface ParticleProps {\n /** Angle in degrees (0-360) for particle direction */\n angle: number\n /** Distance in pixels the particle travels */\n distance: number\n /** Scale multiplier for particle size */\n scale: number\n /** Color of the particle (hex or CSS color) */\n color: string\n /** Particle shape (preset or custom) */\n shape: ParticleShape\n /** Animation duration in milliseconds */\n speed: number\n /** CSS easing function for animation */\n easing: string\n /** Whether particle should fade out */\n fadeOut: boolean\n}\n\n/** Return type for the useParticle hook */\nexport interface UseParticleReturn {\n /** Whether the animation has started */\n isAnimating: boolean\n /** X position offset in pixels */\n x: number\n /** Y position offset in pixels */\n y: number\n /** Computed transform string */\n transform: string\n /** Computed opacity value */\n opacity: number\n /** Animation duration in milliseconds */\n speed: number\n /** CSS easing function */\n easing: string\n /** Whether to fade out */\n fadeOut: boolean\n}\n\n/**\n * Headless hook for particle animation logic.\n * Handles animation state and position calculations.\n */\nexport function useParticle({\n angle,\n distance,\n scale,\n speed,\n easing,\n fadeOut,\n}: Pick<\n ParticleProps,\n \"angle\" | \"distance\" | \"scale\" | \"speed\" | \"easing\" | \"fadeOut\"\n>): UseParticleReturn {\n const [isAnimating, setIsAnimating] = useState(false)\n\n // Trigger animation after mount\n useEffect(() => {\n const timer = requestAnimationFrame(() => setIsAnimating(true))\n return () => cancelAnimationFrame(timer)\n }, [])\n\n // Calculate final position\n const x = Math.cos((angle * Math.PI) / 180) * distance\n const y = Math.sin((angle * Math.PI) / 180) * distance\n\n return {\n isAnimating,\n x,\n y,\n transform: isAnimating\n ? `translate(${x}px, ${y}px) scale(${scale})`\n : \"translate(0, 0) scale(0)\",\n opacity: isAnimating ? 0 : 1,\n speed,\n easing,\n fadeOut,\n }\n}\n","import { getParticleShape } from \"./shapes\"\nimport type { ParticleProps } from \"./useParticle\"\nimport { useParticle } from \"./useParticle\"\n\n/**\n * Particle - Animated particle for burst effects.\n * This version uses Tailwind CSS for styling.\n *\n * Supports multiple shapes (heart, star, circle, square, sparkle) and custom shapes.\n * Animation is fully configurable via speed, easing, and fadeOut props.\n */\nexport function Particle({\n angle,\n distance,\n scale,\n color,\n shape,\n speed,\n easing,\n fadeOut,\n}: ParticleProps) {\n const { transform, opacity } = useParticle({\n angle,\n distance,\n scale,\n speed,\n easing,\n fadeOut,\n })\n\n // Get the shape component (preset or custom)\n const ShapeComponent = getParticleShape(shape)\n\n return (\n <div\n className=\"absolute w-10 h-10 transition-all\"\n style={{\n color,\n transform,\n opacity: fadeOut ? opacity : 1,\n transitionDuration: `${speed}ms`,\n transitionTimingFunction: easing,\n }}\n >\n <ShapeComponent size={40} color={color} className=\"w-full h-full\" />\n </div>\n )\n}\n\nexport default Particle\n","import { useCallback, useState } from \"react\"\nimport type { ParticleConfig, ParticlePreset, ParticleShape } from \"../Particle/types\"\nimport {\n normalizeRange,\n randomAngle,\n randomInRange,\n resolveParticleConfig,\n} from \"../Particle/utils\"\n\n/** Data structure for a single particle effect */\nexport interface ParticleData {\n id: string\n angle: number\n distance: number\n scale: number\n color: string\n shape: ParticleShape\n speed: number\n easing: string\n fadeOut: boolean\n}\n\n/** Options for the useLikeButton hook */\nexport interface UseLikeButtonOptions {\n /** Number of clicks by current user (controlled mode). If not provided, internal state is used. */\n localClicks?: number\n /** Maximum number of clicks allowed per user */\n maxClicks?: number\n /** Callback when button is clicked. Receives the new local click count. */\n onClick?: (newLocalClicks: number) => void\n /** Callback when button is right-clicked. Receives the current click count. Does not increment or spawn particles. */\n onRightClick?: (currentClicks: number) => void\n /** Whether the button is disabled */\n disabled?: boolean\n /** Show particle effects on click */\n showParticles?: boolean\n /** Custom aria-label override */\n ariaLabel?: string\n\n // ========== PARTICLE CONFIGURATION ==========\n /**\n * Particle effect preset (burst, fountain, confetti, gentle, fireworks)\n * @example\n * ```tsx\n * useLikeButton({ particlePreset: 'burst' })\n * ```\n */\n particlePreset?: ParticlePreset\n\n /**\n * Custom particle configuration (overrides preset)\n * @example\n * ```tsx\n * useLikeButton({\n * particleConfig: {\n * shape: 'star',\n * colors: ['#FFD700', '#FFA500'],\n * count: 12,\n * }\n * })\n * ```\n */\n particleConfig?: Partial<ParticleConfig>\n}\n\n/** Default values */\nexport const LIKE_BUTTON_DEFAULTS = {\n maxClicks: 14,\n size: 96,\n fillColor: \"#EF4444\",\n waveColor: \"#B91C1C\",\n} as const\n\n/** Return type for the useLikeButton hook */\nexport interface UseLikeButtonReturn {\n /** Current click count */\n localClicks: number\n /** Whether max clicks reached */\n isMaxed: boolean\n /** Whether button is disabled */\n disabled: boolean\n /** Fill percentage (0-100) */\n fillPercentage: number\n /** Active particles to render */\n particles: ParticleData[]\n /** Click handler for the button */\n handleClick: () => void\n /** Right-click handler for the button */\n handleRightClick: (e: React.MouseEvent) => void\n /** Aria label for accessibility */\n ariaLabel: string\n /** Whether button has been pressed */\n isPressed: boolean\n}\n\n/**\n * Headless hook for LikeButton logic.\n * Handles state management, particle spawning, and accessibility.\n *\n * @example\n * ```tsx\n * const { handleClick, localClicks, particles, ariaLabel } = useLikeButton({\n * maxClicks: 10,\n * onClick: (clicks) => console.log('Clicked!', clicks),\n * });\n * ```\n */\nexport function useLikeButton(options: UseLikeButtonOptions = {}): UseLikeButtonReturn {\n const {\n localClicks: externalLocalClicks,\n maxClicks = LIKE_BUTTON_DEFAULTS.maxClicks,\n onClick,\n onRightClick,\n disabled: externalDisabled,\n showParticles = true,\n particlePreset,\n particleConfig,\n ariaLabel: customAriaLabel,\n } = options\n\n // Internal state for uncontrolled mode\n const [internalLocalClicks, setInternalLocalClicks] = useState(0)\n const [particles, setParticles] = useState<ParticleData[]>([])\n\n // Use external state if provided, otherwise use internal\n const localClicks = externalLocalClicks ?? internalLocalClicks\n const isMaxed = localClicks >= maxClicks\n const disabled = externalDisabled ?? isMaxed\n\n const spawnParticles = useCallback(() => {\n if (!showParticles) return\n\n // Resolve final particle configuration from preset and custom config\n const config = resolveParticleConfig(particlePreset, particleConfig)\n\n // Normalize ranges for random value generation\n const distanceRange = normalizeRange(config.distance)\n const sizeRange = normalizeRange(config.size)\n\n const id = Date.now()\n\n const newParticles = Array.from({ length: config.count }).map((_, i) => ({\n id: `${id}-${i}`,\n angle: randomAngle(config.spread, config.spreadOffset),\n distance: randomInRange(distanceRange),\n scale: randomInRange(sizeRange),\n color: config.colors[Math.floor(Math.random() * config.colors.length)],\n shape: config.shape,\n speed: config.speed,\n easing: config.easing,\n fadeOut: config.fadeOut,\n }))\n\n setParticles((prev) => [...prev, ...newParticles])\n\n // Cleanup particles after animation completes\n // Add buffer time to ensure animation finishes\n const cleanupDelay = config.speed + 100\n setTimeout(() => {\n setParticles((prev) => prev.filter((p) => !newParticles.find((np) => np.id === p.id)))\n }, cleanupDelay)\n }, [showParticles, particlePreset, particleConfig])\n\n const handleClick = useCallback(() => {\n if (disabled) return\n\n const newLocalClicks = localClicks + 1\n\n // Update internal state if in uncontrolled mode\n if (externalLocalClicks === undefined) {\n setInternalLocalClicks(newLocalClicks)\n }\n\n spawnParticles()\n onClick?.(newLocalClicks)\n }, [disabled, localClicks, externalLocalClicks, spawnParticles, onClick])\n\n const handleRightClick = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault() // Prevent context menu\n if (disabled) return\n\n // Right-click does not increment clicks or spawn particles\n // It only calls the callback with the current click count\n onRightClick?.(localClicks)\n },\n [disabled, localClicks, onRightClick],\n )\n\n const fillPercentage = (localClicks / maxClicks) * 100\n\n const defaultAriaLabel = isMaxed\n ? \"Thank you for your likes!\"\n : `Like this content. ${maxClicks - localClicks} clicks remaining`\n\n return {\n localClicks,\n isMaxed,\n disabled,\n fillPercentage,\n particles,\n handleClick,\n handleRightClick,\n ariaLabel: customAriaLabel ?? defaultAriaLabel,\n isPressed: localClicks > 0,\n }\n}\n","import type { ParticleConfig, ParticlePreset, ParticlePresetConfig } from \"./types\"\n\n/**\n * Default particle configuration.\n * Used as the base for all particle effects when no preset or custom config is provided.\n */\nexport const DEFAULT_PARTICLE_CONFIG: Required<ParticleConfig> = {\n shape: \"heart\",\n speed: 500,\n distance: { min: 60, max: 100 },\n spread: 360,\n spreadOffset: 0,\n size: { min: 1.0, max: 1.5 },\n colors: [\"#EF4444\", \"#B9FF14\", \"#3B82F6\"],\n count: 8,\n easing: \"cubic-bezier(0.22, 1, 0.36, 1)\",\n fadeOut: true,\n}\n\n/**\n * Built-in particle effect presets.\n * Each preset provides a distinct visual effect optimized for different use cases.\n *\n * @example\n * ```tsx\n * import { PARTICLE_PRESETS } from '@jepepa/like-button';\n *\n * // Use a preset directly\n * const burstConfig = PARTICLE_PRESETS.burst;\n * ```\n */\nexport const PARTICLE_PRESETS: Record<ParticlePreset, ParticlePresetConfig> = {\n /**\n * Burst - Fast, enthusiastic explosion effect\n * - Wide 360° spread\n * - Fast animation (400ms)\n * - Multiple colors\n * - 12 particles\n * - Perfect for: Likes, favorites, celebrations\n */\n burst: {\n shape: \"heart\",\n speed: 400,\n distance: { min: 80, max: 120 },\n spread: 360,\n spreadOffset: 0,\n size: { min: 1.0, max: 1.5 },\n colors: [\"#EF4444\", \"#F59E0B\", \"#3B82F6\"],\n count: 12,\n easing: \"cubic-bezier(0.22, 1, 0.36, 1)\",\n fadeOut: true,\n },\n\n /**\n * Fountain - Upward spray effect\n * - 120° upward spread\n * - Medium animation (600ms)\n * - Cool colors (blue, purple, pink)\n * - 10 particles\n * - Perfect for: Achievements, upgrades, success\n */\n fountain: {\n shape: \"circle\",\n speed: 600,\n distance: { min: 60, max: 100 },\n spread: 120,\n spreadOffset: -90, // Upward\n size: { min: 0.8, max: 1.2 },\n colors: [\"#3B82F6\", \"#8B5CF6\", \"#EC4899\"],\n count: 10,\n easing: \"cubic-bezier(0.22, 1, 0.36, 1)\",\n fadeOut: true,\n },\n\n /**\n * Confetti - Colorful celebration effect\n * - Full 360° spread\n * - Slow animation (800ms)\n * - Rainbow colors\n * - 15 particles\n * - Perfect for: Milestones, victories, special events\n */\n confetti: {\n shape: \"square\",\n speed: 800,\n distance: { min: 70, max: 110 },\n spread: 360,\n spreadOffset: 0,\n size: { min: 0.6, max: 1.4 },\n colors: [\"#EF4444\", \"#F59E0B\", \"#10B981\", \"#3B82F6\", \"#8B5CF6\", \"#EC4899\"],\n count: 15,\n easing: \"ease-out\",\n fadeOut: true,\n },\n\n /**\n * Gentle - Subtle, calm effect\n * - 180° upward spread\n * - Slow animation (700ms)\n * - Soft red tones\n * - 6 particles\n * - Perfect for: Subtle interactions, quiet appreciation\n */\n gentle: {\n shape: \"heart\",\n speed: 700,\n distance: { min: 40, max: 60 },\n spread: 180,\n spreadOffset: -90,\n size: { min: 0.8, max: 1.0 },\n colors: [\"#EF4444\", \"#F87171\"],\n count: 6,\n easing: \"ease-in-out\",\n fadeOut: true,\n },\n\n /**\n * Fireworks - Explosive sparkle effect\n * - Full 360° spread\n * - Medium-fast animation (500ms)\n * - Warm sparkle colors\n * - 16 particles\n * - Large size range\n * - Perfect for: Big celebrations, major achievements\n */\n fireworks: {\n shape: \"sparkle\",\n speed: 500,\n distance: { min: 100, max: 150 },\n spread: 360,\n spreadOffset: 0,\n size: { min: 1.2, max: 2.0 },\n colors: [\"#FBBF24\", \"#F59E0B\", \"#EF4444\", \"#EC4899\"],\n count: 16,\n easing: \"cubic-bezier(0.22, 1, 0.36, 1)\",\n fadeOut: true,\n },\n}\n\n/**\n * Get a particle preset configuration by name.\n *\n * @param preset - The preset name\n * @returns The complete particle configuration for the preset\n *\n * @example\n * ```tsx\n * import { getParticlePreset } from '@jepepa/like-button';\n *\n * const burstConfig = getParticlePreset('burst');\n * const fountainConfig = getParticlePreset('fountain');\n * ```\n */\nexport function getParticlePreset(preset: ParticlePreset): ParticlePresetConfig {\n return PARTICLE_PRESETS[preset]\n}\n","import { DEFAULT_PARTICLE_CONFIG, getParticlePreset } from \"./presets\"\nimport type { ParticleConfig, ParticlePreset, Range } from \"./types\"\n\n/**\n * Normalize a number or range configuration to a Range object.\n *\n * @param value - Either a single number or a range object\n * @returns Range object with min and max values\n *\n * @example\n * ```ts\n * normalizeRange(100) // { min: 100, max: 100 }\n * normalizeRange({ min: 50, max: 150 }) // { min: 50, max: 150 }\n * ```\n */\nexport function normalizeRange(value: number | Range): Range {\n return typeof value === \"number\" ? { min: value, max: value } : value\n}\n\n/**\n * Generate a random value within a range.\n *\n * @param range - Range object with min and max values\n * @returns Random number between min and max (inclusive)\n *\n * @example\n * ```ts\n * randomInRange({ min: 50, max: 100 }) // e.g., 73.42\n * randomInRange({ min: 1, max: 1 }) // 1\n * ```\n */\nexport function randomInRange(range: Range): number {\n return range.min + Math.random() * (range.max - range.min)\n}\n\n/**\n * Normalize an angle to the 0-360 degree range.\n *\n * @param angle - Angle in degrees (can be negative or > 360)\n * @returns Normalized angle between 0 and 360\n *\n * @example\n * ```ts\n * normalizeAngle(450) // 90\n * normalizeAngle(-90) // 270\n * normalizeAngle(180) // 180\n * ```\n */\nexport function normalizeAngle(angle: number): number {\n const normalized = angle % 360\n const result = normalized < 0 ? normalized + 360 : normalized\n // Handle -0 edge case\n return result === 0 ? 0 : result\n}\n\n/**\n * Generate a random angle within a spread range.\n *\n * @param spread - Spread angle in degrees (0-360)\n * @param offset - Starting angle offset in degrees\n * @returns Random angle within the spread range\n *\n * @example\n * ```ts\n * // Full circle\n * randomAngle(360, 0) // e.g., 234.5\n *\n * // Upward semicircle\n * randomAngle(180, -90) // e.g., -45 (normalized to 315)\n *\n * // Narrow 45° cone pointing right\n * randomAngle(45, -22.5) // e.g., 10\n * ```\n */\nexport function randomAngle(spread: number, offset: number): number {\n const angle = offset + Math.random() * spread\n return normalizeAngle(angle)\n}\n\n/**\n * Merge two particle configurations, with override taking precedence.\n * Performs a shallow merge - override values replace base values.\n *\n * @param base - Base configuration\n * @param override - Override configuration (takes precedence)\n * @returns Merged configuration\n *\n * @example\n * ```ts\n * const base = { count: 8, colors: ['#FF0000'], speed: 500 };\n * const override = { count: 12, speed: 600 };\n * const merged = mergeParticleConfig(base, override);\n * // Result: { count: 12, colors: ['#FF0000'], speed: 600 }\n * ```\n */\nexport function mergeParticleConfig(\n base: Partial<ParticleConfig>,\n override?: Partial<ParticleConfig>,\n): Partial<ParticleConfig> {\n if (!override) {\n return base\n }\n\n return {\n ...base,\n ...override,\n }\n}\n\n/**\n * Resolve final particle configuration from preset and custom config.\n * Merge priority: defaults < preset < custom config\n *\n * @param preset - Optional preset name\n * @param config - Optional custom configuration\n * @returns Complete particle configuration with all required fields\n *\n * @example\n * ```ts\n * // Use defaults only\n * const config1 = resolveParticleConfig(undefined, undefined);\n *\n * // Use preset\n * const config2 = resolveParticleConfig('burst', undefined);\n *\n * // Use preset with overrides\n * const config3 = resolveParticleConfig('burst', { count: 20 });\n *\n * // Use custom config only\n * const config4 = resolveParticleConfig(undefined, { count: 15, colors: ['#000'] });\n * ```\n */\nexport function resolveParticleConfig(\n preset: ParticlePreset | undefined,\n config: Partial<ParticleConfig> | undefined,\n): Required<ParticleConfig> {\n // Start with defaults\n let resolved: Partial<ParticleConfig> = { ...DEFAULT_PARTICLE_CONFIG }\n\n // Apply preset if provided\n if (preset) {\n resolved = mergeParticleConfig(resolved, getParticlePreset(preset))\n }\n\n // Apply custom config (highest priority)\n if (config) {\n resolved = mergeParticleConfig(resolved, config)\n }\n\n return resolved as Required<ParticleConfig>\n}\n","import type { Cursor, CursorPreset, Shape, StyleOverrides } from \"./types\"\n\n/** Default style values for brutalist design */\nexport const DEFAULT_STYLES: Required<StyleOverrides> = {\n borderWidth: 4,\n borderColor: \"#111827\",\n shadowOffset: 8,\n shadowColor: \"#111827\",\n backgroundColor: \"white\",\n}\n\n/**\n * Compute CSS properties from a shape prop value.\n * Handles both preset strings and custom shape objects.\n */\nexport function getShapeStyles(shape: Shape = \"circle\"): React.CSSProperties {\n if (typeof shape === \"string\") {\n switch (shape) {\n case \"circle\":\n return { borderRadius: \"9999px\" }\n case \"rounded\":\n return { borderRadius: \"1rem\" }\n case \"square\":\n return { borderRadius: \"0\" }\n default:\n return { borderRadius: \"9999px\" }\n }\n }\n\n // Custom shape object\n const styles: React.CSSProperties = {}\n if (shape.clipPath) {\n styles.clipPath = shape.clipPath\n // When using clipPath, default to no border-radius unless specified\n styles.borderRadius = shape.borderRadius ?? \"0\"\n } else if (shape.borderRadius) {\n styles.borderRadius = shape.borderRadius\n }\n return styles\n}\n\n/**\n * Compute the shadow offset for hover state.\n * Returns half the original offset, with a minimum of 2px.\n */\nexport function computeHoverOffset(shadowOffset: number): number {\n return Math.max(shadowOffset / 2, 2)\n}\n\n/**\n * Compute button inline styles from merged style overrides and shape styles.\n */\nexport function computeButtonStyles(\n size: number,\n mergedStyles: Required<StyleOverrides>,\n shapeStyles: React.CSSProperties,\n): React.CSSProperties {\n return {\n width: size,\n height: size,\n borderWidth: mergedStyles.borderWidth,\n borderColor: mergedStyles.borderColor,\n backgroundColor: mergedStyles.backgroundColor,\n boxShadow: `${mergedStyles.shadowOffset}px ${mergedStyles.shadowOffset}px 0px ${mergedStyles.shadowColor}`,\n ...shapeStyles,\n }\n}\n\n/**\n * Generate dynamic CSS for hover/active states.\n * Uses :not(:disabled) to prevent animations on disabled buttons.\n */\nexport function generateDynamicStyles(\n buttonSelector: string,\n hoverShadowOffset: number,\n mergedStyles: Required<StyleOverrides>,\n): string {\n const translateOnHover = mergedStyles.shadowOffset - hoverShadowOffset\n\n return `\n ${buttonSelector}:hover:not(:disabled) {\n box-shadow: ${hoverShadowOffset}px ${hoverShadowOffset}px 0px ${mergedStyles.shadowColor};\n transform: translate(${translateOnHover}px, ${translateOnHover}px);\n }\n ${buttonSelector}:active:not(:disabled) {\n box-shadow: none;\n transform: translate(${mergedStyles.shadowOffset}px, ${mergedStyles.shadowOffset}px) scale(0.9);\n }\n `\n}\n\n// ============================================\n// Cursor Utilities\n// ============================================\n\n/** SVG cursor data URLs for preset cursors (32x32, hotspot at center) */\nconst CURSOR_SVGS: Record<Exclude<CursorPreset, \"pointer\" | \"none\">, string> = {\n heart: `data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 24 24' fill='%23EF4444' stroke='%23111827' stroke-width='1.5'><path d='M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z'/></svg>`,\n star: `data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 24 24' fill='%23FBBF24' stroke='%23111827' stroke-width='1.5'><path d='M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'/></svg>`,\n \"thumbs-up\": `data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 24 24' fill='%233B82F6' stroke='%23111827' stroke-width='1.5'><path d='M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3'/></svg>`,\n}\n\n/** Default hotspot position (center of 32x32 cursor) */\nconst DEFAULT_HOTSPOT = 16\n\n/**\n * Generate CSS cursor value from cursor prop.\n * Returns a complete CSS cursor property value.\n */\nexport function getCursorStyle(cursor: Cursor = \"heart\"): string {\n // Handle preset strings\n if (typeof cursor === \"string\") {\n switch (cursor) {\n case \"pointer\":\n return \"pointer\"\n case \"none\":\n return \"none\"\n case \"heart\":\n case \"star\":\n case \"thumbs-up\":\n return `url(\"${CURSOR_SVGS[cursor]}\") ${DEFAULT_HOTSPOT} ${DEFAULT_HOTSPOT}, pointer`\n default:\n // Fallback for unknown presets\n return \"pointer\"\n }\n }\n\n // Handle custom cursor object\n const {\n url,\n hotspotX = DEFAULT_HOTSPOT,\n hotspotY = DEFAULT_HOTSPOT,\n fallback = \"pointer\",\n } = cursor\n return `url(\"${url}\") ${hotspotX} ${hotspotY}, ${fallback}`\n}\n","import { useId, useMemo } from \"react\"\nimport { ParticleVanilla } from \"../Particle/Particle.vanilla\"\nimport { DefaultHeartIcon } from \"./DefaultHeartIcon\"\nimport type { IconRenderProps, LikeButtonVanillaProps } from \"./types\"\nimport { LIKE_BUTTON_DEFAULTS, useLikeButton } from \"./useLikeButton\"\nimport {\n computeButtonStyles,\n computeHoverOffset,\n DEFAULT_STYLES,\n generateDynamicStyles,\n getCursorStyle,\n getShapeStyles,\n} from \"./utils\"\n\nexport type { LikeButtonVanillaProps }\n\n// Maximum fill height percentage (leaves room for wave animation at top)\nconst MAX_FILL_HEIGHT = 85\n\n/**\n * LikeButton - Animated like button with liquid fill and particle effects.\n * This version uses vanilla CSS (no Tailwind dependency).\n *\n * @example\n * ```tsx\n * import { LikeButtonVanilla } from '@jepepa/like-button';\n * import '@jepepa/like-button/styles.css';\n *\n * // Default usage\n * <LikeButtonVanilla onClick={(clicks) => console.log('Clicks:', clicks)} />\n *\n * // Custom icon\n * <LikeButtonVanilla renderIcon={({ size }) => <CustomIcon size={size} />} />\n *\n * // Custom shape\n * <LikeButtonVanilla shape=\"rounded\" />\n * <LikeButtonVanilla shape={{ clipPath: \"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)\" }} />\n *\n * // Custom styles\n * <LikeButtonVanilla styles={{ shadowOffset: 4, borderWidth: 2 }} />\n *\n * // Custom cursor\n * <LikeButtonVanilla cursor=\"star\" />\n * <LikeButtonVanilla cursor={{ url: \"data:image/svg+xml;...\", hotspotX: 16, hotspotY: 16 }} />\n *\n * // Minimum fill for custom shapes\n * <LikeButtonVanilla minFillPercent={15} shape={{ clipPath: \"polygon(...)\" }} />\n *\n * // Particle presets (same API as Tailwind version)\n * <LikeButtonVanilla particlePreset=\"burst\" />\n * <LikeButtonVanilla particlePreset=\"confetti\" />\n * <LikeButtonVanilla particlePreset=\"fireworks\" />\n *\n * // Custom particle configuration\n * <LikeButtonVanilla particleConfig={{\n * shape: 'star',\n * colors: ['#FFD700', '#FFA500'],\n * count: 15,\n * speed: 800\n * }} />\n *\n * // Combine preset with custom config\n * <LikeButtonVanilla\n * particlePreset=\"burst\"\n * particleConfig={{ count: 20 }}\n * />\n * ```\n */\nexport function LikeButtonVanilla({\n size = LIKE_BUTTON_DEFAULTS.size,\n fillColor = LIKE_BUTTON_DEFAULTS.fillColor,\n waveColor = LIKE_BUTTON_DEFAULTS.waveColor,\n className = \"\",\n showParticles = true,\n renderIcon,\n shape = \"circle\",\n styles = {},\n cursor = \"heart\",\n minFillPercent = 0,\n ...hookOptions\n}: LikeButtonVanillaProps) {\n // Clamp minFillPercent to valid range (0-85)\n const clampedMinFill = Math.max(0, Math.min(MAX_FILL_HEIGHT, minFillPercent))\n // Hooks must be called first and in consistent order\n const reactId = useId()\n const buttonId = `like-button${reactId.replace(/:/g, \"-\")}`\n\n const {\n handleClick,\n handleRightClick,\n disabled,\n ariaLabel,\n isPressed,\n isMaxed,\n fillPercentage,\n particles,\n } = useLikeButton({ showParticles, ...hookOptions })\n\n // Memoize style computations\n const mergedStyles = useMemo(() => ({ ...DEFAULT_STYLES, ...styles }), [styles])\n\n const shapeStyles = useMemo(() => getShapeStyles(shape), [shape])\n\n const buttonStyle = useMemo(\n () => computeButtonStyles(size, mergedStyles, shapeStyles),\n [size, mergedStyles, shapeStyles],\n )\n\n const hoverShadowOffset = useMemo(\n () => computeHoverOffset(mergedStyles.shadowOffset),\n [mergedStyles.shadowOffset],\n )\n\n const dynamicStyles = useMemo(\n () => generateDynamicStyles(`#${buttonId}`, hoverShadowOffset, mergedStyles),\n [buttonId, hoverShadowOffset, mergedStyles],\n )\n\n // Cursor style (not-allowed when disabled)\n const cursorStyle = useMemo(\n () => (disabled ? \"not-allowed\" : getCursorStyle(cursor)),\n [cursor, disabled],\n )\n\n // Icon configuration\n const iconSize = size * 0.5\n const iconRenderProps: IconRenderProps = {\n size: iconSize,\n className: \"like-button__icon\",\n isMaxed,\n fillPercentage,\n }\n\n const renderedIcon =\n renderIcon === null ? null : renderIcon === undefined ? (\n <DefaultHeartIcon {...iconRenderProps} />\n ) : (\n renderIcon(iconRenderProps)\n )\n\n return (\n <div className=\"like-button-container\">\n {/* Dynamic styles for hover/active states */}\n <style>{dynamicStyles}</style>\n\n <button\n id={buttonId}\n type=\"button\"\n onClick={handleClick}\n onContextMenu={handleRightClick}\n disabled={disabled}\n aria-label={ariaLabel}\n aria-pressed={isPressed}\n aria-disabled={disabled}\n style={{ ...buttonStyle, cursor: cursorStyle }}\n className={`like-button ${className}`.trim()}\n >\n {/* Liquid Fill Container */}\n <div\n className=\"like-button__fill\"\n style={{\n backgroundColor: fillColor,\n height: isMaxed\n ? \"100%\"\n : `${clampedMinFill + (fillPercentage / 100) * (MAX_FILL_HEIGHT - clampedMinFill)}%`,\n }}\n >\n {/* Wave 1 (Back Layer) */}\n <div className=\"like-button__wave like-button__wave--back\">\n {[0, 1].map((i) => (\n <svg\n key={i}\n className=\"like-button__wave-svg\"\n style={{ color: waveColor }}\n viewBox=\"0 0 100 20\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M0,10 Q25,0 50,10 T100,10 V20 H0 Z\" />\n </svg>\n ))}\n </div>\n\n {/* Wave 2 (Front Layer) */}\n <div className=\"like-button__wave like-button__wave--front\">\n {[0, 1].map((i) => (\n <svg\n key={i}\n className=\"like-button__wave-svg\"\n style={{ color: fillColor }}\n viewBox=\"0 0 100 20\"\n preserveAspectRatio=\"none\"\n aria-hidden=\"true\"\n >\n <path d=\"M0,10 Q25,5 50,10 T100,10 V20 H0 Z\" />\n </svg>\n ))}\n </div>\n </div>\n\n {/* Icon (customizable via renderIcon prop) */}\n {renderedIcon}\n </button>\n\n {/* Particles */}\n {showParticles && (\n <div className=\"like-button__particles\" aria-hidden=\"true\">\n {particles.map((p) => (\n <ParticleVanilla key={p.id} {...p} />\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default LikeButtonVanilla\n","import { getParticleShape } from \"./shapes\"\nimport type { ParticleProps } from \"./useParticle\"\nimport { useParticle } from \"./useParticle\"\n\n/**\n * Particle - Animated particle for burst effects.\n * This version uses vanilla CSS (no Tailwind dependency).\n *\n * Supports multiple shapes (heart, star, circle, square, sparkle) and custom shapes.\n * Animation is fully configurable via speed, easing, and fadeOut props.\n */\nexport function ParticleVanilla({\n angle,\n distance,\n scale,\n color,\n shape,\n speed,\n easing,\n fadeOut,\n}: ParticleProps) {\n const { transform, opacity } = useParticle({\n angle,\n distance,\n scale,\n speed,\n easing,\n fadeOut,\n })\n\n // Get the shape component (preset or custom)\n const ShapeComponent = getParticleShape(shape)\n\n return (\n <div\n className=\"particle\"\n style={{\n color,\n transform,\n opacity: fadeOut ? opacity : 1,\n transitionDuration: `${speed}ms`,\n transitionTimingFunction: easing,\n }}\n >\n <ShapeComponent size={40} color={color} className=\"particle__icon\" />\n </div>\n )\n}\n\nexport default ParticleVanilla\n"],"mappings":"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","names":["jsx","jsx","jsx","jsx","jsx","jsx","useState","useState","jsx","useId","useMemo","jsx","jsx","jsxs","MAX_FILL_HEIGHT","useId","useMemo"]}