diff --git a/components/image-zoom/README.md b/components/image-zoom/README.md new file mode 100644 index 0000000..f4f5914 --- /dev/null +++ b/components/image-zoom/README.md @@ -0,0 +1,26 @@ +# imageZoom + +A custom [Retool](https://retool.com/) component that adds image zoom and magnification capabilities to your Retool applications. + +## Features + +- **Normal mode** — Click to zoom in/out on the image; drag to pan while zoomed in. +- **Glass mode** — A circular magnifier lens follows the cursor over the image. + +## Retool State Properties + +| Property | Type | Default | Description | +|---|---|---|---| +| `imageUrl` | `string` | Sample flower image | URL of the image to display | +| `imageAlt` | `string` | `""` | Alt text for the image | +| `zoomMode` | `string` | `"normal"` | Zoom mode: `normal`, `glass`, `self`, or `side` | +| `zoomLevel` | `number` | `3` | Magnification multiplier | + +## Zoom Modes + +### `normal` +Click anywhere on the image to zoom in to the configured `zoomLevel`. Click again to zoom back out. While zoomed in, drag the image to pan. + +### `glass` +A circular magnifier lens (180×180 px by default) follows the mouse cursor and shows the area under it at `zoomLevel` magnification. + diff --git a/components/image-zoom/cover.png b/components/image-zoom/cover.png new file mode 100644 index 0000000..d3f5a12 --- /dev/null +++ b/components/image-zoom/cover.png @@ -0,0 +1 @@ + diff --git a/components/image-zoom/metadata.json b/components/image-zoom/metadata.json new file mode 100644 index 0000000..a68d504 --- /dev/null +++ b/components/image-zoom/metadata.json @@ -0,0 +1,7 @@ +{ + "id": "image-zoom", + "title": "Image Zoom", + "author": "@MiguelOrtiz", + "shortDescription": "A component that adds image zoom and magnification capabilities to your Retool applications.", + "tags": ["Custom", "React", "UI Components"] +} diff --git a/components/image-zoom/package.json b/components/image-zoom/package.json new file mode 100644 index 0000000..b4515dd --- /dev/null +++ b/components/image-zoom/package.json @@ -0,0 +1,42 @@ +{ + "name": "my-react-app", + "version": "0.1.0", + "private": true, + "dependencies": { + "@tryretool/custom-component-support": "latest", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "engines": { + "node": ">=20.0.0" + }, +"scripts": { + "dev": "npx retool-ccl dev", + "deploy": "npx retool-ccl deploy", + "test": "vitest" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@types/react": "^18.2.55", + "@types/react-dom": "^18.2.19", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", + "eslint": "^8.57.0", + "eslint-plugin-react": "^7.34.1", + "postcss-modules": "^6.0.0", + "prettier": "^3.0.3", + "typescript": "^5.4.0", + "vitest": "^4.0.17" + } +} diff --git a/components/image-zoom/source/components/imageMagnifier.tsx b/components/image-zoom/source/components/imageMagnifier.tsx new file mode 100644 index 0000000..5c4a805 --- /dev/null +++ b/components/image-zoom/source/components/imageMagnifier.tsx @@ -0,0 +1,189 @@ +import React, { useRef, useState } from 'react' + +const ImageMagnifier = ({ + src, + className = '', + width, + height, + alt, + mode = 'glass', + magnifierHeight = 150, + magnifierWidth = 150, + zoomLevel = 3 +}) => { + const [showMagnifier, setShowMagnifier] = useState(false) + const [[imgWidth, imgHeight], setSize] = useState([0, 0]) + const [[x, y], setXY] = useState([0, 0]) + + const mouseEnter = (e) => { + const el = e.currentTarget + + const { width, height } = el.getBoundingClientRect() + setSize([width, height]) + setShowMagnifier(true) + } + + const mouseLeave = (e) => { + e.preventDefault() + setShowMagnifier(false) + } + + const mouseMove = (e) => { + const el = e.currentTarget + const { top, left } = el.getBoundingClientRect() + + const x = e.pageX - left - window.scrollX + const y = e.pageY - top - window.scrollY + + setXY([x, y]) + } + + return ( +