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.
- Replaced hardcoded
"magnifier-help"string withReact.useId()to generate uniquearia-describedbyIDs - Prevents duplicate ID violations when multiple magnifier instances appear on the same page
- Each magnifier instance now has a guaranteed-unique
idattribute on its help text element
- Component now wraps its container
<div>ref viaReact.forwardRef - Consumers can access the container DOM node directly using a
refprop - Ref is properly cleaned up on unmount (set to
null) ReactMagnifierPropstype is now exported for consumer use
- Renamed
customImgStylestocustomImgClassandcustomContainerStylestocustomContainerClassfor semantic clarity (these apply CSS classes, not inline styles) - Backward compatibility preserved via fallback merge —
customImgStylesandcustomContainerStylesare still accepted and merged with the new props - Deprecated props are marked with
@deprecatedJSDoc in the interface
- Arrow key movement now clamps to image boundaries (
maxLeft/maxTopderived from image dimensions and zoom ratio) - Prevents the magnifier glass from moving outside the visible image area when using keyboard navigation
- Changed from
pageX/pageYtoclientX/clientYfor cursor position - Removed double-compensation with
pageXOffset/pageYOffsetthat caused offset errors in certain scroll positions
- Removed hardcoded
PIXEL_PADDINGconstant in favor offinalProps.magnifierBorderWidth - Glass positioning now respects the consumer's configured border width for accurate alignment
- The entire
finalPropsobject was wrapped inuseMemowith[props]as dependency - When
props(the entire object reference) changes,useMemomust re-run anyway, making the memoization effectively a no-op - Replaced with a plain spread — reduces overhead and simplifies the code
- Deleted the empty
scripts/directory that was left over from earlier refactoring
- The
build:libscript was a duplicate ofbuildinpackage.json; removed the redundant entry
- Removed
.npmrcfile containinglegacy-peer-deps=true - This flag suppressed legitimate peer dependency warnings — proper dependency management is preferred
- Updated
@testing-library/reactfrom15.0.7to16.3.2to resolve peer dependency conflict with@types/react@19.x(after.npmrcremoval)
- 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 topackage.json
- Added comprehensive TSDoc/JSDoc comments to all source files:
ReactMagnifier.tsx— main component with hook documentationReactMagnifier.Interface.ts— all props documented with descriptionsReactMagnifier.styled.ts— styled-components purpose docsutils.ts— all utility functions documentedexport.tsx— entry point docssetupTests.ts— test environment setup docs
| Format | Minified | Gzipped |
|---|---|---|
| ESM | 16.10 kB | 3.74 kB |
| UMD | 8.03 kB | 2.87 kB |
- Fixed keyboard arrow key handlers (↑ ↓ ← →) to update
backgroundPositionalongside 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
- 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
- Deleted
src/ReactMagnifier/style.css— redundant since v1.1.0 migrated to styled-components - Removed non-existent
index.cssimports fromsrc/index.tsxand stories
- Replaced fragile
await new Promise(resolve => setTimeout(resolve, N))withwaitForfrom@testing-library/reactinReactMagnifier.test.tsx - Fixed syntax error in
ReactMagnifier.memory.test.tsx:269(statement, eslint-disable, and expect collapsed onto one line) - All 49 tests passing
- "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"
- 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 exportingImageContainer,SrOnly, andMagnifierGlobalStylesstyled componentsMagnifierGlobalStyles(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
ImageContainerstyled component replaces the plain<div className="react-magnifier-image-container">— the class name is still applied explicitly for backward compatibility with external CSS and testsSrOnlystyled component replaces<div className="sr-only">for the screen-reader status announcement- Removed
import './style.css'fromReactMagnifier.tsx;style.cssis retained for Storybook stories
- Added
styled-componentsas a runtime dependency (moved to peer dependency in v1.2.0) - Added
@types/styled-componentsas a dev dependency (removed in v1.2.0 — v6 ships own types)
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.
- 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
tabindexhandling - Visual focus indicators via
:focus-visible
- ARIA attributes:
- Screen Reader Support - Semantic HTML structure with proper ARIA labels
- Custom Events - Dispatches custom DOM events for magnifier state changes:
magnifier-initialized- When magnifier initializesmagnifier-moved- When magnifier position changesmagnifier-visible- When magnifier becomes visiblemagnifier-invisible- When magnifier becomes hidden
- 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
- ESLint 8.56.0 with
@typescript-eslintfor modern linting rules - Prettier 3.1.1 for consistent code formatting
- TypeScript 5.3.3 with strict mode enabled
- Extracted Utilities - Created
utils.tswith 6 reusable helper functionsisValidProp()- Prop validationlogMagnifierError()- Styled console loggingtriggerCustomEvent()- Custom event dispatchgetCursorPos()- Position calculation with scroll handlingdebounce()- Debounce utilitycreateMagnifierGlass()- DOM element factory
- 17 Test Cases organized in 8 suites:
- Basic Rendering (4 tests) - Component mounting, props, attributes
- Props Configuration (4 tests) - Default props, custom values, callbacks
- Magnifier Glass Creation (2 tests) - DOM element, styling
- Visibility Control (3 tests) - Initial state, mouse enter/leave
- Keyboard Navigation (1 test) - Escape key handling
- Error Handling (1 test) - Missing imageUrl
- Component Updates (1 test) - Props changes
- React.memo Optimization (1 test) - Memoization verification
- Testing Libraries:
@testing-library/react15.0.7@testing-library/jest-dom6.1.5jsdomfor DOM simulation@vitest/uifor visual test dashboard
- 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
- 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
- Replaced generic
Functiontype 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
- Added
.sr-onlyutility class for screen reader-only content - Added
:focus-visiblestyles for keyboard navigation indicators - Improved semantic HTML structure
- 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
- 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
- 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
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
vite: 5.0.8 (build tool)vitest: 1.1.0 (test framework)@typescript-eslint/eslint-plugin: 6.15.0@typescript-eslint/parser: 6.15.0eslint: 8.56.0eslint-config-prettier: 9.1.0eslint-plugin-react: 7.33.2eslint-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.1jsdom: 29.1.1prettier: 3.1.1terser: 5.49.0 (minification)
webpack: 3.x (replaced with Vite)jest: (replaced with Vitest)webpack-cli: (replaced with Vite)babel-*: (Vite/TypeScript handles transpilation)
- 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
- Migrated from Webpack 3 to Vite 5.0.8
- ESM + UMD dual output configuration
- Source map generation for debugging
- CSS minification included
- Migrated from Jest to Vitest 1.1.0
- JSDOM environment for DOM testing
- 100% code coverage thresholds configured
- Test UI dashboard available
- ESLint with TypeScript-aware rules
- Prettier for code formatting
- Husky pre-commit hooks
- lint-staged for selective file linting
- NPM scripts for all common tasks
- Legacy peer dependency support enabled
- Proper entry point configuration
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.
Nothing deprecated in this release
- None identified
No code changes required! Simply update:
npm update @sandeepv68/react-magnifierTo use new features:
- Keyboard navigation works automatically (arrow keys, Escape)
- ARIA attributes are automatically included
- TypeScript support improved with stricter types
// 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}
/>;| 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 ✅ |
- README.md - Complete usage guide
- MODERNIZATION_SUMMARY.md - Detailed technical summary
- src/ReactMagnifier/ReactMagnifier.Interface.ts - TypeScript interface definitions
- src/ReactMagnifier/ReactMagnifier.test.tsx - Test examples
- Sandeep Vattapparambil - Modernization to React 19 and accessibility improvements
Special thanks to the React community and the WCAG standards committee for accessibility guidelines.
- React 16 support
- Basic image magnification functionality
- Webpack 3 build system
- Jest testing
- Touch screen support
- Custom event dispatching
- CSS customization support
- 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