Skip to content

Latest commit

 

History

History
467 lines (331 loc) · 17.2 KB

File metadata and controls

467 lines (331 loc) · 17.2 KB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.3.0] - 2026-07-29

🚀 New Features

React 19 useId() for ARIA ID Generation

  • Replaced hardcoded "magnifier-help" string with React.useId() to generate unique aria-describedby IDs
  • Prevents duplicate ID violations when multiple magnifier instances appear on the same page
  • Each magnifier instance now has a guaranteed-unique id attribute on its help text element

React.forwardRef Support

  • Component now wraps its container <div> ref via React.forwardRef
  • Consumers can access the container DOM node directly using a ref prop
  • Ref is properly cleaned up on unmount (set to null)
  • ReactMagnifierProps type is now exported for consumer use

Prop Renames: customImgStylescustomImgClass, customContainerStylescustomContainerClass

  • Renamed customImgStyles to customImgClass and customContainerStyles to customContainerClass for semantic clarity (these apply CSS classes, not inline styles)
  • Backward compatibility preserved via fallback merge — customImgStyles and customContainerStyles are still accepted and merged with the new props
  • Deprecated props are marked with @deprecated JSDoc in the interface

🐛 Bug Fixes

Keyboard Bounds Clamping

  • Arrow key movement now clamps to image boundaries (maxLeft/maxTop derived from image dimensions and zoom ratio)
  • Prevents the magnifier glass from moving outside the visible image area when using keyboard navigation

getCursorPos Scroll Calculation Fix

  • Changed from pageX/pageY to clientX/clientY for cursor position
  • Removed double-compensation with pageXOffset/pageYOffset that caused offset errors in certain scroll positions

PIXEL_PADDING Replaced with magnifierBorderWidth

  • Removed hardcoded PIXEL_PADDING constant in favor of finalProps.magnifierBorderWidth
  • Glass positioning now respects the consumer's configured border width for accurate alignment

🧹 Code Cleanup

Removed Redundant useMemo on Props

  • The entire finalProps object was wrapped in useMemo with [props] as dependency
  • When props (the entire object reference) changes, useMemo must re-run anyway, making the memoization effectively a no-op
  • Replaced with a plain spread — reduces overhead and simplifies the code

Removed Empty scripts/ Directory

  • Deleted the empty scripts/ directory that was left over from earlier refactoring

Removed Duplicate build:lib Script

  • The build:lib script was a duplicate of build in package.json; removed the redundant entry

Removed .npmrc

  • Removed .npmrc file containing legacy-peer-deps=true
  • This flag suppressed legitimate peer dependency warnings — proper dependency management is preferred

📦 Dependency Updates

  • Updated @testing-library/react from 15.0.7 to 16.3.2 to resolve peer dependency conflict with @types/react@19.x (after .npmrc removal)

🔧 Dev Tooling

  • Husky pre-commit hooks configured with lint-staged
  • Runs linting and formatting on staged *.{ts,tsx,json,css,md} files
  • Added "prepare": "husky install" script to package.json

📝 Documentation

  • Added comprehensive TSDoc/JSDoc comments to all source files:
    • ReactMagnifier.tsx — main component with hook documentation
    • ReactMagnifier.Interface.ts — all props documented with descriptions
    • ReactMagnifier.styled.ts — styled-components purpose docs
    • utils.ts — all utility functions documented
    • export.tsx — entry point docs
    • setupTests.ts — test environment setup docs

Bundle Sizes (Post-Fix)

Format Minified Gzipped
ESM 16.10 kB 3.74 kB
UMD 8.03 kB 2.87 kB

[1.1.1] - 2026-07-25

🐛 Bug Fixes

Keyboard Navigation Background Sync

  • Fixed keyboard arrow key handlers (↑ ↓ ← →) to update backgroundPosition alongside glass position
  • Previously, moving the magnifier with keyboard would shift the glass but the zoomed content would not follow
  • Added updateBackgroundPosition() helper that derives logical coordinates from the glass element's DOM position

Event Name Consistency

  • Fixed misspelled custom event names (magnfier-*magnifier-*) across all consumer code
  • The component dispatches correctly-spelled events, but stories, tests, and documentation referenced misspelled versions, meaning event listeners would never fire
  • Affected files: ReactMagnifier.stories.tsx, ReactMagnifier.memory.test.tsx, README.md, CHANGELOG.md, RELEASE_NOTES.md, TECHNICAL_DOCS.md

Changed

Code Cleanup

  • Deleted src/ReactMagnifier/style.css — redundant since v1.1.0 migrated to styled-components
  • Removed non-existent index.css imports from src/index.tsx and stories

Test Improvements

  • Replaced fragile await new Promise(resolve => setTimeout(resolve, N)) with waitFor from @testing-library/react in ReactMagnifier.test.tsx
  • Fixed syntax error in ReactMagnifier.memory.test.tsx:269 (statement, eslint-disable, and expect collapsed onto one line)
  • All 49 tests passing

Documentation Fixes

  • "Zero Dependencies" → "Minimal runtime dependencies (styled-components is the sole runtime dependency)"
  • "17 comprehensive test cases" → "49 comprehensive test cases"
  • Removed references to non-existent npm scripts (build-tsc, build-dev, build-prod)
  • "Jest testing library" → "Vitest testing library"
  • Updated test count from "50+" to accurate "49"

[1.1.0] - 2026-07-20

🎨 CSS-in-JS Migration

Added

  • styled-components integration — component styles are now co-located with the component via CSS-in-JS, eliminating the need to import a separate stylesheet
  • ReactMagnifier.styled.ts — new file exporting ImageContainer, SrOnly, and MagnifierGlobalStyles styled components
  • MagnifierGlobalStyles (createGlobalStyle) covers the imperatively-created magnifier glass element (.react-magnifier-glass, .show-magnifier, .hide-magnifier) which cannot be a styled component because the glass DOM node is created manually

Changed

  • ImageContainer styled component replaces the plain <div className="react-magnifier-image-container"> — the class name is still applied explicitly for backward compatibility with external CSS and tests
  • SrOnly styled component replaces <div className="sr-only"> for the screen-reader status announcement
  • Removed import './style.css' from ReactMagnifier.tsx; style.css is retained for Storybook stories

Dependencies

  • Added styled-components as a runtime dependency (moved to peer dependency in v1.2.0)
  • Added @types/styled-components as a dev dependency (removed in v1.2.0 — v6 ships own types)

[1.0.0] - 2026-07-18

✨ Major Release - Modernization & Accessibility

This is a major overhaul modernizing ReactMagnifier from a legacy 2019-era component to a production-ready React 19 library with comprehensive accessibility, improved tooling, and significantly better performance.

🎯 Added

Core Features

  • React 19 Support - Migrated from React 16 to React 19.0.0-rc.1 with modern hooks architecture
  • Keyboard Navigation - Full keyboard support:
    • Arrow keys (Up/Down/Left/Right) to move magnifier glass (10px per keypress)
    • Escape key to close magnifier
  • Enhanced Accessibility - WCAG 2.1 Level AA compliance:
    • ARIA attributes: role="group", aria-label, aria-describedby, aria-live
    • Screen reader support with status announcements
    • Focus management with proper tabindex handling
    • Visual focus indicators via :focus-visible
  • Screen Reader Support - Semantic HTML structure with proper ARIA labels
  • Custom Events - Dispatches custom DOM events for magnifier state changes:
    • magnifier-initialized - When magnifier initializes
    • magnifier-moved - When magnifier position changes
    • magnifier-visible - When magnifier becomes visible
    • magnifier-invisible - When magnifier becomes hidden

Build & Tooling

  • Vite Migration - Replaced Webpack 3 with Vite 5.0.8
    • 10x faster build times (~589ms vs previous ~5000ms)
    • Built-in ES module support
    • Better development experience with HMR
  • Dual Distribution Format:
    • ESM (25.25 kB, 6.29 kB gzipped) for modern browsers
    • UMD (12.08 kB, 4.61 kB gzipped) for CommonJS compatibility
    • Source maps included for debugging
    • TypeScript declarations (.d.ts) generated
  • TypeScript Strict Mode - Full type safety across codebase
  • Vitest Migration - Replaced Jest with Vitest 1.1.0
    • 49 comprehensive test cases
    • 100% code coverage targets
    • JSDOM environment for DOM testing
    • Better performance and faster test execution

Code Quality

  • ESLint 8.56.0 with @typescript-eslint for modern linting rules
  • Prettier 3.1.1 for consistent code formatting
  • TypeScript 5.3.3 with strict mode enabled
  • Extracted Utilities - Created utils.ts with 6 reusable helper functions
    • isValidProp() - Prop validation
    • logMagnifierError() - Styled console logging
    • triggerCustomEvent() - Custom event dispatch
    • getCursorPos() - Position calculation with scroll handling
    • debounce() - Debounce utility
    • createMagnifierGlass() - DOM element factory

Testing Infrastructure

  • 17 Test Cases organized in 8 suites:
    1. Basic Rendering (4 tests) - Component mounting, props, attributes
    2. Props Configuration (4 tests) - Default props, custom values, callbacks
    3. Magnifier Glass Creation (2 tests) - DOM element, styling
    4. Visibility Control (3 tests) - Initial state, mouse enter/leave
    5. Keyboard Navigation (1 test) - Escape key handling
    6. Error Handling (1 test) - Missing imageUrl
    7. Component Updates (1 test) - Props changes
    8. React.memo Optimization (1 test) - Memoization verification
  • Testing Libraries:
    • @testing-library/react 15.0.7
    • @testing-library/jest-dom 6.1.5
    • jsdom for DOM simulation
    • @vitest/ui for visual test dashboard

🎨 Changed

Component Architecture

  • Converted from class-based (React.Component) to functional component with hooks
  • Implemented 8 memoized useCallback handlers for event management
  • Added 3 useRef references for DOM element access
  • Used 2 useEffect effects for lifecycle management
  • Added useMemo for props merging with defaults
  • Wrapped component with React.memo for performance optimization

Bundle Size Reduction

  • ESM Bundle: 13.92 kB minified (3.49 kB gzipped) — down from 25.25 kB in v1.1.1
  • UMD Bundle: 7.51 kB minified (2.74 kB gzipped) — down from 12.08 kB in v1.1.1
  • CSS: 0 kB — styles injected at runtime via styled-components
  • Previous Size: ~18 kB minified (v0.0.4)
  • Improvement: ~81% smaller gzipped bundle from v0.0.4

TypeScript Improvements

  • Replaced generic Function type with specific callback signature: (container: HTMLDivElement | null) => void
  • Added comprehensive JSDoc comments for all interface properties
  • Improved type inference across components
  • Added proper generic types for callback functions

CSS Enhancements

  • Added .sr-only utility class for screen reader-only content
  • Added :focus-visible styles for keyboard navigation indicators
  • Improved semantic HTML structure

Documentation

  • Completely rewritten README.md with:
    • Keyboard navigation guide
    • Accessibility features documentation
    • Updated examples and use cases
    • Migration guide from v0.0.4
    • Comprehensive API documentation
    • TypeScript examples

🚀 Performance Improvements

  • React.memo prevents unnecessary re-renders
  • useCallback with precise dependencies eliminates stale closures
  • useMemo prevents recalculation of props merging
  • Optimized event listener cleanup
  • No memory leaks detected
  • Faster build times with Vite (10x improvement)
  • Faster test execution with Vitest

🔐 Security Enhancements

  • TypeScript strict mode prevents type-related vulnerabilities
  • Minimal runtime dependencies (React, ReactDOM, and styled-components are peer dependencies — nothing bundled)
  • React's built-in XSS prevention
  • Proper event scoping
  • No eval() or dynamic code execution

📦 Dependencies

Updated

  • react: 16.12.0 → 19.0.0-rc.1 (peer dependency)
  • react-dom: 16.12.0 → 19.0.0-rc.1 (peer dependency)
  • typescript: 3.x → 5.3.3

New Dev Dependencies

  • vite: 5.0.8 (build tool)
  • vitest: 1.1.0 (test framework)
  • @typescript-eslint/eslint-plugin: 6.15.0
  • @typescript-eslint/parser: 6.15.0
  • eslint: 8.56.0
  • eslint-config-prettier: 9.1.0
  • eslint-plugin-react: 7.33.2
  • eslint-plugin-react-hooks: 4.6.0
  • @vitejs/plugin-react: 4.2.1
  • @vitest/ui: 1.1.0
  • @testing-library/react: 15.0.7
  • @testing-library/jest-dom: 6.1.5
  • @testing-library/user-event: 14.5.1
  • jsdom: 29.1.1
  • prettier: 3.1.1
  • terser: 5.49.0 (minification)

Removed

  • webpack: 3.x (replaced with Vite)
  • jest: (replaced with Vitest)
  • webpack-cli: (replaced with Vite)
  • babel-*: (Vite/TypeScript handles transpilation)

🐛 Bug Fixes

  • Fixed null reference errors with defensive programming
  • Improved event handler cleanup to prevent memory leaks
  • Better error handling for missing or invalid image URLs
  • Fixed focus management for keyboard navigation

⚙️ Tooling Changes

Build System

  • Migrated from Webpack 3 to Vite 5.0.8
  • ESM + UMD dual output configuration
  • Source map generation for debugging
  • CSS minification included

Testing

  • Migrated from Jest to Vitest 1.1.0
  • JSDOM environment for DOM testing
  • 100% code coverage thresholds configured
  • Test UI dashboard available

Linting & Formatting

  • ESLint with TypeScript-aware rules
  • Prettier for code formatting
  • Husky pre-commit hooks
  • lint-staged for selective file linting

Package Management

  • NPM scripts for all common tasks
  • Legacy peer dependency support enabled
  • Proper entry point configuration

🔄 Breaking Changes

None - Fully backward compatible with v0.0.4

All existing props and events continue to work exactly as before. New features are opt-in enhancements.

⚠️ Deprecated

Nothing deprecated in this release

🚧 Known Limitations

  • None identified

📖 Migration Guide

From v0.0.4

No code changes required! Simply update:

npm update @sandeepv68/react-magnifier

To use new features:

  • Keyboard navigation works automatically (arrow keys, Escape)
  • ARIA attributes are automatically included
  • TypeScript support improved with stricter types

Recommended Changes for New Projects

// Modern import with CSS
import ReactMagnifier from '@sandeepv68/react-magnifier';
import '@sandeepv68/react-magnifier/dist/style.css';

// Leverage keyboard navigation and accessibility
<ReactMagnifier
  imageUrl="image.jpg"
  imageAltText="Descriptive text for screen readers"
  zoomSize={2.5}
/>;

📊 Project Statistics

Metric Value
TypeScript Errors 0
Test Cases 49
Bundle Size (ESM) 13.92 kB → 3.49 kB gzipped
Bundle Size (UMD) 7.51 kB → 2.74 kB gzipped
Type Declarations Generated via vite-plugin-dts
Build Time ~4s
Type Check Time < 1 second
Code Coverage Target 100%
Accessibility WCAG 2.1 Level AA ✅

🎓 Documentation

👥 Contributors

  • Sandeep Vattapparambil - Modernization to React 19 and accessibility improvements

🙏 Acknowledgements

Special thanks to the React community and the WCAG standards committee for accessibility guidelines.


[0.0.4] - 2020-XX-XX

Original v0.0.4 Features

  • React 16 support
  • Basic image magnification functionality
  • Webpack 3 build system
  • Jest testing
  • Touch screen support
  • Custom event dispatching
  • CSS customization support

Version History

  • v1.3.0 (2026-07-29) - forwardRef, React 19 useId(), prop renames, keyboard bounds clamping, dev tooling (husky/lint-staged), TSDoc comments
  • v1.2.0 (2026-07-27) - Production readiness fixes: bundle externalization, type declarations, dependency cleanup
  • v1.1.1 (2026-07-25) - Bug fixes, documentation cleanup, test improvements
  • v1.1.0 (2026-07-20) - CSS-in-JS migration via styled-components
  • v1.0.0 (2026-07-18) - Major modernization to React 19
  • v0.0.4 (2020) - Original stable release
  • v0.0.3 - Initial release

[Unreleased]: Changes that will be included in the next release [1.3.0]: Current stable release