mapped-image 0.3.0 → 0.3.1

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.
@@ -38,6 +38,10 @@ type MappedImageProps = {
38
38
  onColumnWeightsChange?: (weights: number[]) => void;
39
39
  /** Fires once a row-weight drag is released, with the full resolved weight array for the current image. */
40
40
  onRowWeightsChange?: (weights: number[]) => void;
41
+ /** Fires continuously while a column-weight handle is being dragged, with the live preview weight array. */
42
+ onColumnWeightsDrag?: (weights: number[]) => void;
43
+ /** Fires continuously while a row-weight handle is being dragged, with the live preview weight array. */
44
+ onRowWeightsDrag?: (weights: number[]) => void;
41
45
  };
42
46
  type ImageLayerProps = {
43
47
  image: ImageConfig;
@@ -52,6 +56,8 @@ type ImageLayerProps = {
52
56
  weightsEditable?: boolean;
53
57
  onColumnWeightsChange?: (weights: number[]) => void;
54
58
  onRowWeightsChange?: (weights: number[]) => void;
59
+ onColumnWeightsDrag?: (weights: number[]) => void;
60
+ onRowWeightsDrag?: (weights: number[]) => void;
55
61
  onCellClick: GridProps["onCellClick"];
56
62
  };
57
63
  type GridProps = {
@@ -65,6 +71,8 @@ type GridProps = {
65
71
  weightsEditable?: boolean;
66
72
  onColumnWeightsChange?: (weights: number[]) => void;
67
73
  onRowWeightsChange?: (weights: number[]) => void;
74
+ onColumnWeightsDrag?: (weights: number[]) => void;
75
+ onRowWeightsDrag?: (weights: number[]) => void;
68
76
  onCellClick?: (props: ICellClickProps) => void;
69
77
  };
70
78
  interface ICellClickProps {
@@ -173,6 +173,8 @@ var Grid = ({
173
173
  weightsEditable,
174
174
  onColumnWeightsChange,
175
175
  onRowWeightsChange,
176
+ onColumnWeightsDrag,
177
+ onRowWeightsDrag,
176
178
  onCellClick
177
179
  }) => {
178
180
  const [dragState, setDragState] = useState(null);
@@ -242,7 +244,11 @@ var Grid = ({
242
244
  axis: "column",
243
245
  boundary: colRight(index),
244
246
  length: height,
245
- onDrag: (deltaUnits) => setDragState({ axis: "column", index, deltaWeight: deltaUnits / pxPerColWeightUnit }),
247
+ onDrag: (deltaUnits) => {
248
+ const deltaWeight = deltaUnits / pxPerColWeightUnit;
249
+ setDragState({ axis: "column", index, deltaWeight });
250
+ onColumnWeightsDrag?.(applyWeightDelta(columnWeights, index, deltaWeight));
251
+ },
246
252
  onDragEnd: () => {
247
253
  onColumnWeightsChange?.(displayColumnWeights);
248
254
  setDragState(null);
@@ -256,7 +262,11 @@ var Grid = ({
256
262
  axis: "row",
257
263
  boundary: rowTop(index),
258
264
  length: width,
259
- onDrag: (deltaUnits) => setDragState({ axis: "row", index, deltaWeight: deltaUnits / pxPerRowWeightUnit }),
265
+ onDrag: (deltaUnits) => {
266
+ const deltaWeight = deltaUnits / pxPerRowWeightUnit;
267
+ setDragState({ axis: "row", index, deltaWeight });
268
+ onRowWeightsDrag?.(applyWeightDelta(rowWeights, index, deltaWeight));
269
+ },
260
270
  onDragEnd: () => {
261
271
  onRowWeightsChange?.(displayRowWeights);
262
272
  setDragState(null);
@@ -321,6 +331,8 @@ var ImageLayer = ({
321
331
  weightsEditable,
322
332
  onColumnWeightsChange,
323
333
  onRowWeightsChange,
334
+ onColumnWeightsDrag,
335
+ onRowWeightsDrag,
324
336
  onCellClick
325
337
  }) => {
326
338
  const [imgBounds, setImgBounds] = useState2(null);
@@ -368,6 +380,8 @@ var ImageLayer = ({
368
380
  weightsEditable,
369
381
  onColumnWeightsChange,
370
382
  onRowWeightsChange,
383
+ onColumnWeightsDrag,
384
+ onRowWeightsDrag,
371
385
  onCellClick
372
386
  }
373
387
  ),
@@ -435,6 +449,8 @@ var MappedImage = (props) => {
435
449
  weightsEditable: props.weightsEditable,
436
450
  onColumnWeightsChange: props.onColumnWeightsChange,
437
451
  onRowWeightsChange: props.onRowWeightsChange,
452
+ onColumnWeightsDrag: props.onColumnWeightsDrag,
453
+ onRowWeightsDrag: props.onRowWeightsDrag,
438
454
  onCellClick: handleCellClick
439
455
  },
440
456
  selectedImage.src
@@ -1 +1 @@
1
- {"version":3,"sources":["../MappedImage.tsx","#style-inject:#style-inject","../MappedImage.css","../components/DefaultImageSelector.tsx","../components/ImageLayer.tsx","../components/Grid.tsx","../helpers/weights.ts","../helpers/headerIcon.ts","../helpers/cellAccessibility.ts","../components/WeightHandle.tsx","../components/ZoomController.tsx","../helpers/imageBounds.ts","../helpers/colNames.ts"],"sourcesContent":["import { useState } from \"react\";\nimport \"leaflet/dist/leaflet.css\";\nimport \"./MappedImage.css\";\nimport type { ICellClickProps, ImageSelectorProps, MappedImageProps } from \"./types\";\nimport { DefaultImageSelector } from \"./components/DefaultImageSelector\";\nimport { ImageLayer } from \"./components/ImageLayer\";\n\n// Type-only re-export; doesn't add a non-component export for fast-refresh purposes.\n// eslint-disable-next-line react-refresh/only-export-components\nexport * from \"./types\";\n\nexport const MappedImage = (props: MappedImageProps) => {\n if (props.images.length === 0) {\n throw new Error(\"MappedImage requires at least one entry in `images`.\");\n }\n\n const invalidImage = props.images.find((image) => image.rows <= 0 || image.columns <= 0);\n if (invalidImage) {\n throw new Error(\n `MappedImage: image \"${invalidImage.name}\" must have rows > 0 and columns > 0.`,\n );\n }\n\n const [internalSelectedCells, setInternalSelectedCells] = useState<Set<string>>(\n props.selectedCells ?? new Set(),\n );\n const isSelectionControlled = props.selectedCells !== undefined;\n const selectedCells = isSelectionControlled ? props.selectedCells! : internalSelectedCells;\n\n const [selectedImageIndex, setSelectedImageIndex] = useState(\n props.selectedImageIndex ?? 0,\n );\n\n const selectedImage = props.images[selectedImageIndex];\n const colOffset = props.images\n .slice(0, selectedImageIndex)\n .reduce((sum, image) => sum + image.columns, 0);\n const rowOffset = props.images\n .slice(0, selectedImageIndex)\n .reduce((sum, image) => sum + image.rows, 0);\n\n const handleSelectImage = (index: number) => {\n setSelectedImageIndex(index);\n props.onSelectedImageIndexChange?.(index);\n };\n\n const handleCellClick = ({ row, col }: ICellClickProps) => {\n const cellId = `${row},${col}`;\n const next = new Set(selectedCells);\n if (next.has(cellId)) {\n next.delete(cellId);\n } else {\n next.add(cellId);\n }\n\n if (!isSelectionControlled) {\n setInternalSelectedCells(next);\n }\n props.onSelectedCellsChange?.(next);\n props.onCellClick?.({ row, col });\n };\n\n const renderSelector = props.renderImageSelector ?? (\n (selectorProps: ImageSelectorProps) => <DefaultImageSelector {...selectorProps} />\n );\n\n return (\n <div style={{ position: \"relative\", width: props.width, height: props.height }}>\n <ImageLayer\n key={selectedImage.src}\n image={selectedImage}\n colOffset={colOffset}\n rowOffset={rowOffset}\n width={props.width}\n height={props.height}\n alt={props.alt}\n selectedCells={selectedCells}\n maxBoundsPadding={props.maxBoundsPadding}\n zoomMultiplier={props.zoomMultiplier}\n weightsEditable={props.weightsEditable}\n onColumnWeightsChange={props.onColumnWeightsChange}\n onRowWeightsChange={props.onRowWeightsChange}\n onCellClick={handleCellClick}\n />\n {renderSelector({\n images: props.images,\n selectedIndex: selectedImageIndex,\n onSelect: handleSelectImage,\n })}\n </div>\n );\n};\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".grid-header-label-icon {\\n background: none;\\n border: none;\\n}\\n.grid-header-label {\\n position: absolute;\\n display: block;\\n font-weight: bold;\\n white-space: nowrap;\\n}\\n.grid-header-label--column {\\n transform: translate(-50%, -100%);\\n}\\n.grid-header-label--row {\\n transform: translate(-100%, -50%);\\n}\\n.grid-weight-handle--column {\\n cursor: col-resize;\\n}\\n.grid-weight-handle--row {\\n cursor: row-resize;\\n}\\n.grid-weight-handle:hover {\\n stroke-opacity: 0.6;\\n}\\n\")","import type { ImageSelectorProps } from \"../types\";\n\nexport const DefaultImageSelector = ({ images, selectedIndex, onSelect }: ImageSelectorProps) => (\n <div\n style={{\n position: \"absolute\",\n top: 10,\n right: 10,\n zIndex: 1000,\n display: \"flex\",\n gap: 8,\n }}\n >\n {images.map((image, index) => (\n <button\n key={image.name}\n type=\"button\"\n onClick={() => onSelect(index)}\n style={{\n padding: \"12px 20px\",\n fontSize: 16,\n fontWeight: index === selectedIndex ? \"bold\" : \"normal\",\n background: index === selectedIndex ? \"#3388ff\" : \"white\",\n color: index === selectedIndex ? \"white\" : \"black\",\n border: \"1px solid #3388ff\",\n borderRadius: 6,\n }}\n >\n {image.name}\n </button>\n ))}\n </div>\n);\n","import { useEffect, useState } from \"react\";\nimport { CRS, type LatLngBoundsExpression, type LatLngTuple } from \"leaflet\";\nimport { MapContainer, ImageOverlay } from \"react-leaflet\";\nimport type { ImageLayerProps } from \"../types\";\nimport { Grid } from \"./Grid\";\nimport { ZoomController } from \"./ZoomController\";\nimport { imageBounds } from \"../helpers/imageBounds\";\nimport { colNames } from \"../helpers/colNames\";\nimport { resolveWeights } from \"../helpers/weights\";\n\nexport const ImageLayer = ({\n image,\n colOffset,\n rowOffset,\n width,\n height,\n alt,\n selectedCells,\n maxBoundsPadding = 100,\n zoomMultiplier = 1,\n weightsEditable,\n onColumnWeightsChange,\n onRowWeightsChange,\n onCellClick,\n}: ImageLayerProps) => {\n const [imgBounds, setImgBounds] = useState<LatLngTuple | null>(null);\n const [loadError, setLoadError] = useState<Error | null>(null);\n\n useEffect(() => {\n imageBounds(image.src, width, height).then(setImgBounds).catch(setLoadError);\n }, [image.src, width, height]);\n\n if (loadError) {\n throw loadError;\n }\n\n if (!imgBounds) {\n return null;\n }\n\n const [imgHeight, imgWidth] = imgBounds;\n const bounds: LatLngBoundsExpression = [[0, 0], imgBounds];\n const maxBounds: LatLngBoundsExpression = [\n [-maxBoundsPadding , -maxBoundsPadding],\n [imgHeight + maxBoundsPadding, imgWidth + maxBoundsPadding],\n ];\n const columnLabels = colNames(colOffset, image.columns);\n const columnWeights = resolveWeights(image.columns, image.columnWeights);\n const rowWeights = resolveWeights(image.rows, image.rowWeights);\n\n return (\n <MapContainer\n crs={CRS.Simple}\n bounds={bounds}\n boundsOptions={{ padding: [50, 50] }}\n maxBounds={maxBounds}\n maxBoundsViscosity={0.5}\n style={{ width, height }}\n maxZoom={2}\n >\n <ZoomController zoomMultiplier={zoomMultiplier} />\n <Grid\n rows={image.rows}\n rowOffset={rowOffset}\n rowWeights={rowWeights}\n columnLabels={columnLabels}\n columnWeights={columnWeights}\n imgBounds={imgBounds}\n selectedCells={selectedCells}\n weightsEditable={weightsEditable}\n onColumnWeightsChange={onColumnWeightsChange}\n onRowWeightsChange={onRowWeightsChange}\n onCellClick={onCellClick}\n />\n <ImageOverlay url={image.src} bounds={bounds} alt={alt} />\n </MapContainer>\n );\n};\n","import { useState } from \"react\";\nimport { Rectangle, Marker } from \"react-leaflet\";\nimport type { LatLngBoundsExpression } from \"leaflet\";\nimport type { GridProps } from \"../types\";\nimport { applyWeightDelta, weightOffsets } from \"../helpers/weights\";\nimport { headerIcon } from \"../helpers/headerIcon\";\nimport { bindCellAccessibility } from \"../helpers/cellAccessibility\";\nimport { WeightHandle } from \"./WeightHandle\";\n\ntype DragState = { axis: \"column\" | \"row\"; index: number; deltaWeight: number };\n\nexport const Grid = ({\n rows,\n rowOffset,\n rowWeights,\n columnLabels,\n columnWeights,\n imgBounds,\n selectedCells,\n weightsEditable,\n onColumnWeightsChange,\n onRowWeightsChange,\n onCellClick,\n}: GridProps) => {\n const [dragState, setDragState] = useState<DragState | null>(null);\n const [height, width] = imgBounds;\n\n const displayColumnWeights =\n dragState?.axis === \"column\"\n ? applyWeightDelta(columnWeights, dragState.index, dragState.deltaWeight)\n : columnWeights;\n const displayRowWeights =\n dragState?.axis === \"row\"\n ? applyWeightDelta(rowWeights, dragState.index, dragState.deltaWeight)\n : rowWeights;\n\n const colOffsets = weightOffsets(displayColumnWeights);\n const pxPerColWeightUnit = width / colOffsets[colOffsets.length - 1];\n const colLeft = (colCount: number) => colOffsets[colCount] * pxPerColWeightUnit;\n const colRight = (colCount: number) => colOffsets[colCount + 1] * pxPerColWeightUnit;\n\n const rowOffsets = weightOffsets(displayRowWeights);\n const pxPerRowWeightUnit = height / rowOffsets[rowOffsets.length - 1];\n const rowBottom = (rowCount: number) => rowOffsets[rowCount] * pxPerRowWeightUnit;\n const rowTop = (rowCount: number) => rowOffsets[rowCount + 1] * pxPerRowWeightUnit;\n\n const cells = Array.from({ length: rows }).map((_, rowCount) =>\n columnLabels.map((columnLabel, colCount) => {\n const bounds: LatLngBoundsExpression = [\n [rowTop(rowCount), colRight(colCount)],\n [rowBottom(rowCount), colLeft(colCount)],\n ];\n\n const rowLabel = rowOffset + (rows - rowCount);\n const cellId = `${rowLabel},${columnLabel}`;\n const selected = selectedCells.has(cellId);\n const activate = () => onCellClick?.({ col: columnLabel, row: rowLabel });\n\n return (\n <Rectangle\n key={cellId}\n ref={(instance) =>\n bindCellAccessibility(instance, `${columnLabel}${rowLabel}`, selected, activate)\n }\n bounds={bounds}\n pathOptions={{\n fillColor: selected ? \"red\" : \"transparent\",\n fillOpacity: selected ? 0.5 : 0,\n weight: 1.5,\n }}\n eventHandlers={{\n click: activate,\n }}\n />\n );\n }),\n );\n\n const columnHeaders = columnLabels.map((columnLabel, colCount) => (\n <Marker\n key={`col-${columnLabel}`}\n position={[height, (colLeft(colCount) + colRight(colCount)) / 2]}\n icon={headerIcon(columnLabel, \"grid-header-label--column\")}\n interactive={false}\n />\n ));\n\n const rowHeaders = Array.from({ length: rows }).map((_, rowCount) => {\n const rowLabel = rowOffset + (rows - rowCount);\n return (\n <Marker\n key={`row-${rowLabel}`}\n position={[(rowBottom(rowCount) + rowTop(rowCount)) / 2, -7]}\n icon={headerIcon(String(rowLabel), \"grid-header-label--row\")}\n interactive={false}\n />\n );\n });\n\n const columnHandles = weightsEditable\n ? columnLabels.slice(0, -1).map((_, index) => (\n <WeightHandle\n key={`col-handle-${index}`}\n axis=\"column\"\n boundary={colRight(index)}\n length={height}\n onDrag={(deltaUnits) =>\n setDragState({ axis: \"column\", index, deltaWeight: deltaUnits / pxPerColWeightUnit })\n }\n onDragEnd={() => {\n onColumnWeightsChange?.(displayColumnWeights);\n setDragState(null);\n }}\n />\n ))\n : [];\n\n const rowHandles = weightsEditable\n ? Array.from({ length: rows - 1 }).map((_, index) => (\n <WeightHandle\n key={`row-handle-${index}`}\n axis=\"row\"\n boundary={rowTop(index)}\n length={width}\n onDrag={(deltaUnits) =>\n setDragState({ axis: \"row\", index, deltaWeight: deltaUnits / pxPerRowWeightUnit })\n }\n onDragEnd={() => {\n onRowWeightsChange?.(displayRowWeights);\n setDragState(null);\n }}\n />\n ))\n : [];\n\n return [...cells, columnHeaders, rowHeaders, columnHandles, rowHandles];\n};\n","export const resolveWeights = (\n count: number,\n overrides: Record<number, number> = {},\n): number[] => Array.from({ length: count }, (_, i) => overrides[i] ?? 1);\n\n/** Cumulative leading edge (in weight units) of each index, plus the total at the end. */\nexport const weightOffsets = (weights: number[]): number[] => {\n const offsets = [0];\n weights.forEach((weight) => offsets.push(offsets[offsets.length - 1] + weight));\n return offsets;\n};\n\nconst MIN_WEIGHT = 0.2;\n\n/** Shifts weight from index+1 into index (or back, for a negative delta), clamped so neither drops below MIN_WEIGHT. Total weight is preserved. */\nexport const applyWeightDelta = (weights: number[], index: number, delta: number): number[] => {\n const a = weights[index];\n const b = weights[index + 1];\n const clampedDelta = Math.max(-(a - MIN_WEIGHT), Math.min(b - MIN_WEIGHT, delta));\n\n const next = [...weights];\n next[index] = a + clampedDelta;\n next[index + 1] = b - clampedDelta;\n return next;\n};\n","import { divIcon } from \"leaflet\";\n\nexport const headerIcon = (label: string, className: string) =>\n divIcon({\n html: `<span class=\"grid-header-label ${className}\">${label}</span>`,\n className: \"grid-header-label-icon\",\n iconSize: [0, 0],\n });\n","import type { Rectangle as LeafletRectangle } from \"leaflet\";\n\n// Path.getElement() returns the underlying SVG node but isn't declared in @types/leaflet, hence the cast.\nconst getPathElement = (instance: LeafletRectangle) =>\n (instance as unknown as { getElement(): SVGElement | undefined }).getElement();\n\nexport const bindCellAccessibility = (\n instance: LeafletRectangle | null,\n label: string,\n selected: boolean,\n onActivate: () => void,\n) => {\n const el = instance && getPathElement(instance);\n if (!el) {\n return;\n }\n\n el.setAttribute(\"role\", \"button\");\n el.setAttribute(\"tabindex\", \"0\");\n el.setAttribute(\"aria-label\", label);\n el.setAttribute(\"aria-pressed\", String(selected));\n el.onkeydown = (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onActivate();\n }\n };\n};\n","import { useRef } from \"react\";\nimport { Polyline, useMap } from \"react-leaflet\";\nimport type { LatLngExpression, LeafletMouseEvent } from \"leaflet\";\n\ntype WeightHandleProps = {\n axis: \"column\" | \"row\";\n /** Position along the cross-axis: lng for a column boundary, lat for a row boundary. */\n boundary: number;\n /** Full span of the line: image height for column boundaries, image width for row boundaries. */\n length: number;\n onDrag: (deltaUnits: number) => void;\n onDragEnd: () => void;\n};\n\nexport const WeightHandle = ({ axis, boundary, length, onDrag, onDragEnd }: WeightHandleProps) => {\n const map = useMap();\n const dragStartRef = useRef<number | null>(null);\n\n const positions: LatLngExpression[] =\n axis === \"column\" ? [[0, boundary], [length, boundary]] : [[boundary, 0], [boundary, length]];\n\n const handleMouseDown = (event: LeafletMouseEvent) => {\n event.originalEvent.preventDefault();\n map.dragging.disable();\n dragStartRef.current = axis === \"column\" ? event.latlng.lng : event.latlng.lat;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n if (dragStartRef.current === null) {\n return;\n }\n const latlng = map.mouseEventToLatLng(moveEvent);\n const current = axis === \"column\" ? latlng.lng : latlng.lat;\n onDrag(current - dragStartRef.current);\n };\n\n const handleMouseUp = () => {\n dragStartRef.current = null;\n map.dragging.enable();\n onDragEnd();\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n };\n\n return (\n <Polyline\n positions={positions}\n pathOptions={{\n color: \"#3388ff\",\n weight: 6,\n opacity: 0.15,\n className: `grid-weight-handle grid-weight-handle--${axis}`,\n }}\n eventHandlers={{ mousedown: handleMouseDown }}\n />\n );\n};\n","import { useEffect, useRef } from \"react\";\nimport { useMap } from \"react-leaflet\";\n\ntype ZoomControllerProps = {\n zoomMultiplier: number;\n};\n\nexport const ZoomController = ({ zoomMultiplier }: ZoomControllerProps) => {\n const map = useMap();\n const baseZoomRef = useRef<number | null>(null);\n\n useEffect(() => {\n // Capture the zoom react-leaflet's fitBounds already settled on, before any multiplier is applied.\n if (baseZoomRef.current === null) {\n baseZoomRef.current = map.getZoom();\n }\n\n map.setZoom(baseZoomRef.current + Math.log2(zoomMultiplier));\n }, [map, zoomMultiplier]);\n\n return null;\n};\n","import type { LatLngTuple } from \"leaflet\";\r\n\r\nexport const imageBounds = (src: string, containerWidth: number, containerHeight: number): Promise<LatLngTuple> =>\r\n new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.src = src;\r\n img.onload = () => {\r\n const scale = Math.min(containerWidth / img.width, containerHeight / img.height);\r\n resolve([img.height * scale, img.width * scale]);\r\n };\r\n img.onerror = () => reject(new Error(`Failed to load image: ${src}`));\r\n });","const toColumnLetter = (n: number): string => {\n let result = \"\";\n let remaining = n;\n\n while (remaining > 0) {\n const remainder = (remaining - 1) % 26;\n result = String.fromCharCode(65 + remainder) + result;\n remaining = Math.floor((remaining - 1) / 26);\n }\n\n return result;\n};\n\nexport const colNames = (startIndex: number, count: number): string[] =>\n Array.from({ length: count }, (_, i) => toColumnLetter(startIndex + i + 1));\n"],"mappings":"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","names":["useState","useEffect","useState","jsx","jsx","useRef","useMap","jsx","useState","useEffect","jsx","jsxs","useState"]}
1
+ {"version":3,"sources":["../MappedImage.tsx","#style-inject:#style-inject","../MappedImage.css","../components/DefaultImageSelector.tsx","../components/ImageLayer.tsx","../components/Grid.tsx","../helpers/weights.ts","../helpers/headerIcon.ts","../helpers/cellAccessibility.ts","../components/WeightHandle.tsx","../components/ZoomController.tsx","../helpers/imageBounds.ts","../helpers/colNames.ts"],"sourcesContent":["import { useState } from \"react\";\nimport \"leaflet/dist/leaflet.css\";\nimport \"./MappedImage.css\";\nimport type { ICellClickProps, ImageSelectorProps, MappedImageProps } from \"./types\";\nimport { DefaultImageSelector } from \"./components/DefaultImageSelector\";\nimport { ImageLayer } from \"./components/ImageLayer\";\n\n// Type-only re-export; doesn't add a non-component export for fast-refresh purposes.\n// eslint-disable-next-line react-refresh/only-export-components\nexport * from \"./types\";\n\nexport const MappedImage = (props: MappedImageProps) => {\n if (props.images.length === 0) {\n throw new Error(\"MappedImage requires at least one entry in `images`.\");\n }\n\n const invalidImage = props.images.find((image) => image.rows <= 0 || image.columns <= 0);\n if (invalidImage) {\n throw new Error(\n `MappedImage: image \"${invalidImage.name}\" must have rows > 0 and columns > 0.`,\n );\n }\n\n const [internalSelectedCells, setInternalSelectedCells] = useState<Set<string>>(\n props.selectedCells ?? new Set(),\n );\n const isSelectionControlled = props.selectedCells !== undefined;\n const selectedCells = isSelectionControlled ? props.selectedCells! : internalSelectedCells;\n\n const [selectedImageIndex, setSelectedImageIndex] = useState(\n props.selectedImageIndex ?? 0,\n );\n\n const selectedImage = props.images[selectedImageIndex];\n const colOffset = props.images\n .slice(0, selectedImageIndex)\n .reduce((sum, image) => sum + image.columns, 0);\n const rowOffset = props.images\n .slice(0, selectedImageIndex)\n .reduce((sum, image) => sum + image.rows, 0);\n\n const handleSelectImage = (index: number) => {\n setSelectedImageIndex(index);\n props.onSelectedImageIndexChange?.(index);\n };\n\n const handleCellClick = ({ row, col }: ICellClickProps) => {\n const cellId = `${row},${col}`;\n const next = new Set(selectedCells);\n if (next.has(cellId)) {\n next.delete(cellId);\n } else {\n next.add(cellId);\n }\n\n if (!isSelectionControlled) {\n setInternalSelectedCells(next);\n }\n props.onSelectedCellsChange?.(next);\n props.onCellClick?.({ row, col });\n };\n\n const renderSelector = props.renderImageSelector ?? (\n (selectorProps: ImageSelectorProps) => <DefaultImageSelector {...selectorProps} />\n );\n\n return (\n <div style={{ position: \"relative\", width: props.width, height: props.height }}>\n <ImageLayer\n key={selectedImage.src}\n image={selectedImage}\n colOffset={colOffset}\n rowOffset={rowOffset}\n width={props.width}\n height={props.height}\n alt={props.alt}\n selectedCells={selectedCells}\n maxBoundsPadding={props.maxBoundsPadding}\n zoomMultiplier={props.zoomMultiplier}\n weightsEditable={props.weightsEditable}\n onColumnWeightsChange={props.onColumnWeightsChange}\n onRowWeightsChange={props.onRowWeightsChange}\n onColumnWeightsDrag={props.onColumnWeightsDrag}\n onRowWeightsDrag={props.onRowWeightsDrag}\n onCellClick={handleCellClick}\n />\n {renderSelector({\n images: props.images,\n selectedIndex: selectedImageIndex,\n onSelect: handleSelectImage,\n })}\n </div>\n );\n};\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".grid-header-label-icon {\\n background: none;\\n border: none;\\n}\\n.grid-header-label {\\n position: absolute;\\n display: block;\\n font-weight: bold;\\n white-space: nowrap;\\n}\\n.grid-header-label--column {\\n transform: translate(-50%, -100%);\\n}\\n.grid-header-label--row {\\n transform: translate(-100%, -50%);\\n}\\n.grid-weight-handle--column {\\n cursor: col-resize;\\n}\\n.grid-weight-handle--row {\\n cursor: row-resize;\\n}\\n.grid-weight-handle:hover {\\n stroke-opacity: 0.6;\\n}\\n\")","import type { ImageSelectorProps } from \"../types\";\n\nexport const DefaultImageSelector = ({ images, selectedIndex, onSelect }: ImageSelectorProps) => (\n <div\n style={{\n position: \"absolute\",\n top: 10,\n right: 10,\n zIndex: 1000,\n display: \"flex\",\n gap: 8,\n }}\n >\n {images.map((image, index) => (\n <button\n key={image.name}\n type=\"button\"\n onClick={() => onSelect(index)}\n style={{\n padding: \"12px 20px\",\n fontSize: 16,\n fontWeight: index === selectedIndex ? \"bold\" : \"normal\",\n background: index === selectedIndex ? \"#3388ff\" : \"white\",\n color: index === selectedIndex ? \"white\" : \"black\",\n border: \"1px solid #3388ff\",\n borderRadius: 6,\n }}\n >\n {image.name}\n </button>\n ))}\n </div>\n);\n","import { useEffect, useState } from \"react\";\nimport { CRS, type LatLngBoundsExpression, type LatLngTuple } from \"leaflet\";\nimport { MapContainer, ImageOverlay } from \"react-leaflet\";\nimport type { ImageLayerProps } from \"../types\";\nimport { Grid } from \"./Grid\";\nimport { ZoomController } from \"./ZoomController\";\nimport { imageBounds } from \"../helpers/imageBounds\";\nimport { colNames } from \"../helpers/colNames\";\nimport { resolveWeights } from \"../helpers/weights\";\n\nexport const ImageLayer = ({\n image,\n colOffset,\n rowOffset,\n width,\n height,\n alt,\n selectedCells,\n maxBoundsPadding = 100,\n zoomMultiplier = 1,\n weightsEditable,\n onColumnWeightsChange,\n onRowWeightsChange,\n onColumnWeightsDrag,\n onRowWeightsDrag,\n onCellClick,\n}: ImageLayerProps) => {\n const [imgBounds, setImgBounds] = useState<LatLngTuple | null>(null);\n const [loadError, setLoadError] = useState<Error | null>(null);\n\n useEffect(() => {\n imageBounds(image.src, width, height).then(setImgBounds).catch(setLoadError);\n }, [image.src, width, height]);\n\n if (loadError) {\n throw loadError;\n }\n\n if (!imgBounds) {\n return null;\n }\n\n const [imgHeight, imgWidth] = imgBounds;\n const bounds: LatLngBoundsExpression = [[0, 0], imgBounds];\n const maxBounds: LatLngBoundsExpression = [\n [-maxBoundsPadding , -maxBoundsPadding],\n [imgHeight + maxBoundsPadding, imgWidth + maxBoundsPadding],\n ];\n const columnLabels = colNames(colOffset, image.columns);\n const columnWeights = resolveWeights(image.columns, image.columnWeights);\n const rowWeights = resolveWeights(image.rows, image.rowWeights);\n\n return (\n <MapContainer\n crs={CRS.Simple}\n bounds={bounds}\n boundsOptions={{ padding: [50, 50] }}\n maxBounds={maxBounds}\n maxBoundsViscosity={0.5}\n style={{ width, height }}\n maxZoom={2}\n >\n <ZoomController zoomMultiplier={zoomMultiplier} />\n <Grid\n rows={image.rows}\n rowOffset={rowOffset}\n rowWeights={rowWeights}\n columnLabels={columnLabels}\n columnWeights={columnWeights}\n imgBounds={imgBounds}\n selectedCells={selectedCells}\n weightsEditable={weightsEditable}\n onColumnWeightsChange={onColumnWeightsChange}\n onRowWeightsChange={onRowWeightsChange}\n onColumnWeightsDrag={onColumnWeightsDrag}\n onRowWeightsDrag={onRowWeightsDrag}\n onCellClick={onCellClick}\n />\n <ImageOverlay url={image.src} bounds={bounds} alt={alt} />\n </MapContainer>\n );\n};\n","import { useState } from \"react\";\nimport { Rectangle, Marker } from \"react-leaflet\";\nimport type { LatLngBoundsExpression } from \"leaflet\";\nimport type { GridProps } from \"../types\";\nimport { applyWeightDelta, weightOffsets } from \"../helpers/weights\";\nimport { headerIcon } from \"../helpers/headerIcon\";\nimport { bindCellAccessibility } from \"../helpers/cellAccessibility\";\nimport { WeightHandle } from \"./WeightHandle\";\n\ntype DragState = { axis: \"column\" | \"row\"; index: number; deltaWeight: number };\n\nexport const Grid = ({\n rows,\n rowOffset,\n rowWeights,\n columnLabels,\n columnWeights,\n imgBounds,\n selectedCells,\n weightsEditable,\n onColumnWeightsChange,\n onRowWeightsChange,\n onColumnWeightsDrag,\n onRowWeightsDrag,\n onCellClick,\n}: GridProps) => {\n const [dragState, setDragState] = useState<DragState | null>(null);\n const [height, width] = imgBounds;\n\n const displayColumnWeights =\n dragState?.axis === \"column\"\n ? applyWeightDelta(columnWeights, dragState.index, dragState.deltaWeight)\n : columnWeights;\n const displayRowWeights =\n dragState?.axis === \"row\"\n ? applyWeightDelta(rowWeights, dragState.index, dragState.deltaWeight)\n : rowWeights;\n\n const colOffsets = weightOffsets(displayColumnWeights);\n const pxPerColWeightUnit = width / colOffsets[colOffsets.length - 1];\n const colLeft = (colCount: number) => colOffsets[colCount] * pxPerColWeightUnit;\n const colRight = (colCount: number) => colOffsets[colCount + 1] * pxPerColWeightUnit;\n\n const rowOffsets = weightOffsets(displayRowWeights);\n const pxPerRowWeightUnit = height / rowOffsets[rowOffsets.length - 1];\n const rowBottom = (rowCount: number) => rowOffsets[rowCount] * pxPerRowWeightUnit;\n const rowTop = (rowCount: number) => rowOffsets[rowCount + 1] * pxPerRowWeightUnit;\n\n const cells = Array.from({ length: rows }).map((_, rowCount) =>\n columnLabels.map((columnLabel, colCount) => {\n const bounds: LatLngBoundsExpression = [\n [rowTop(rowCount), colRight(colCount)],\n [rowBottom(rowCount), colLeft(colCount)],\n ];\n\n const rowLabel = rowOffset + (rows - rowCount);\n const cellId = `${rowLabel},${columnLabel}`;\n const selected = selectedCells.has(cellId);\n const activate = () => onCellClick?.({ col: columnLabel, row: rowLabel });\n\n return (\n <Rectangle\n key={cellId}\n ref={(instance) =>\n bindCellAccessibility(instance, `${columnLabel}${rowLabel}`, selected, activate)\n }\n bounds={bounds}\n pathOptions={{\n fillColor: selected ? \"red\" : \"transparent\",\n fillOpacity: selected ? 0.5 : 0,\n weight: 1.5,\n }}\n eventHandlers={{\n click: activate,\n }}\n />\n );\n }),\n );\n\n const columnHeaders = columnLabels.map((columnLabel, colCount) => (\n <Marker\n key={`col-${columnLabel}`}\n position={[height, (colLeft(colCount) + colRight(colCount)) / 2]}\n icon={headerIcon(columnLabel, \"grid-header-label--column\")}\n interactive={false}\n />\n ));\n\n const rowHeaders = Array.from({ length: rows }).map((_, rowCount) => {\n const rowLabel = rowOffset + (rows - rowCount);\n return (\n <Marker\n key={`row-${rowLabel}`}\n position={[(rowBottom(rowCount) + rowTop(rowCount)) / 2, -7]}\n icon={headerIcon(String(rowLabel), \"grid-header-label--row\")}\n interactive={false}\n />\n );\n });\n\n const columnHandles = weightsEditable\n ? columnLabels.slice(0, -1).map((_, index) => (\n <WeightHandle\n key={`col-handle-${index}`}\n axis=\"column\"\n boundary={colRight(index)}\n length={height}\n onDrag={(deltaUnits) => {\n const deltaWeight = deltaUnits / pxPerColWeightUnit;\n setDragState({ axis: \"column\", index, deltaWeight });\n onColumnWeightsDrag?.(applyWeightDelta(columnWeights, index, deltaWeight));\n }}\n onDragEnd={() => {\n onColumnWeightsChange?.(displayColumnWeights);\n setDragState(null);\n }}\n />\n ))\n : [];\n\n const rowHandles = weightsEditable\n ? Array.from({ length: rows - 1 }).map((_, index) => (\n <WeightHandle\n key={`row-handle-${index}`}\n axis=\"row\"\n boundary={rowTop(index)}\n length={width}\n onDrag={(deltaUnits) => {\n const deltaWeight = deltaUnits / pxPerRowWeightUnit;\n setDragState({ axis: \"row\", index, deltaWeight });\n onRowWeightsDrag?.(applyWeightDelta(rowWeights, index, deltaWeight));\n }}\n onDragEnd={() => {\n onRowWeightsChange?.(displayRowWeights);\n setDragState(null);\n }}\n />\n ))\n : [];\n\n return [...cells, columnHeaders, rowHeaders, columnHandles, rowHandles];\n};\n","export const resolveWeights = (\n count: number,\n overrides: Record<number, number> = {},\n): number[] => Array.from({ length: count }, (_, i) => overrides[i] ?? 1);\n\n/** Cumulative leading edge (in weight units) of each index, plus the total at the end. */\nexport const weightOffsets = (weights: number[]): number[] => {\n const offsets = [0];\n weights.forEach((weight) => offsets.push(offsets[offsets.length - 1] + weight));\n return offsets;\n};\n\nconst MIN_WEIGHT = 0.2;\n\n/** Shifts weight from index+1 into index (or back, for a negative delta), clamped so neither drops below MIN_WEIGHT. Total weight is preserved. */\nexport const applyWeightDelta = (weights: number[], index: number, delta: number): number[] => {\n const a = weights[index];\n const b = weights[index + 1];\n const clampedDelta = Math.max(-(a - MIN_WEIGHT), Math.min(b - MIN_WEIGHT, delta));\n\n const next = [...weights];\n next[index] = a + clampedDelta;\n next[index + 1] = b - clampedDelta;\n return next;\n};\n","import { divIcon } from \"leaflet\";\n\nexport const headerIcon = (label: string, className: string) =>\n divIcon({\n html: `<span class=\"grid-header-label ${className}\">${label}</span>`,\n className: \"grid-header-label-icon\",\n iconSize: [0, 0],\n });\n","import type { Rectangle as LeafletRectangle } from \"leaflet\";\n\n// Path.getElement() returns the underlying SVG node but isn't declared in @types/leaflet, hence the cast.\nconst getPathElement = (instance: LeafletRectangle) =>\n (instance as unknown as { getElement(): SVGElement | undefined }).getElement();\n\nexport const bindCellAccessibility = (\n instance: LeafletRectangle | null,\n label: string,\n selected: boolean,\n onActivate: () => void,\n) => {\n const el = instance && getPathElement(instance);\n if (!el) {\n return;\n }\n\n el.setAttribute(\"role\", \"button\");\n el.setAttribute(\"tabindex\", \"0\");\n el.setAttribute(\"aria-label\", label);\n el.setAttribute(\"aria-pressed\", String(selected));\n el.onkeydown = (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onActivate();\n }\n };\n};\n","import { useRef } from \"react\";\nimport { Polyline, useMap } from \"react-leaflet\";\nimport type { LatLngExpression, LeafletMouseEvent } from \"leaflet\";\n\ntype WeightHandleProps = {\n axis: \"column\" | \"row\";\n /** Position along the cross-axis: lng for a column boundary, lat for a row boundary. */\n boundary: number;\n /** Full span of the line: image height for column boundaries, image width for row boundaries. */\n length: number;\n onDrag: (deltaUnits: number) => void;\n onDragEnd: () => void;\n};\n\nexport const WeightHandle = ({ axis, boundary, length, onDrag, onDragEnd }: WeightHandleProps) => {\n const map = useMap();\n const dragStartRef = useRef<number | null>(null);\n\n const positions: LatLngExpression[] =\n axis === \"column\" ? [[0, boundary], [length, boundary]] : [[boundary, 0], [boundary, length]];\n\n const handleMouseDown = (event: LeafletMouseEvent) => {\n event.originalEvent.preventDefault();\n map.dragging.disable();\n dragStartRef.current = axis === \"column\" ? event.latlng.lng : event.latlng.lat;\n\n const handleMouseMove = (moveEvent: MouseEvent) => {\n if (dragStartRef.current === null) {\n return;\n }\n const latlng = map.mouseEventToLatLng(moveEvent);\n const current = axis === \"column\" ? latlng.lng : latlng.lat;\n onDrag(current - dragStartRef.current);\n };\n\n const handleMouseUp = () => {\n dragStartRef.current = null;\n map.dragging.enable();\n onDragEnd();\n window.removeEventListener(\"mousemove\", handleMouseMove);\n window.removeEventListener(\"mouseup\", handleMouseUp);\n };\n\n window.addEventListener(\"mousemove\", handleMouseMove);\n window.addEventListener(\"mouseup\", handleMouseUp);\n };\n\n return (\n <Polyline\n positions={positions}\n pathOptions={{\n color: \"#3388ff\",\n weight: 6,\n opacity: 0.15,\n className: `grid-weight-handle grid-weight-handle--${axis}`,\n }}\n eventHandlers={{ mousedown: handleMouseDown }}\n />\n );\n};\n","import { useEffect, useRef } from \"react\";\nimport { useMap } from \"react-leaflet\";\n\ntype ZoomControllerProps = {\n zoomMultiplier: number;\n};\n\nexport const ZoomController = ({ zoomMultiplier }: ZoomControllerProps) => {\n const map = useMap();\n const baseZoomRef = useRef<number | null>(null);\n\n useEffect(() => {\n // Capture the zoom react-leaflet's fitBounds already settled on, before any multiplier is applied.\n if (baseZoomRef.current === null) {\n baseZoomRef.current = map.getZoom();\n }\n\n map.setZoom(baseZoomRef.current + Math.log2(zoomMultiplier));\n }, [map, zoomMultiplier]);\n\n return null;\n};\n","import type { LatLngTuple } from \"leaflet\";\r\n\r\nexport const imageBounds = (src: string, containerWidth: number, containerHeight: number): Promise<LatLngTuple> =>\r\n new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.src = src;\r\n img.onload = () => {\r\n const scale = Math.min(containerWidth / img.width, containerHeight / img.height);\r\n resolve([img.height * scale, img.width * scale]);\r\n };\r\n img.onerror = () => reject(new Error(`Failed to load image: ${src}`));\r\n });","const toColumnLetter = (n: number): string => {\n let result = \"\";\n let remaining = n;\n\n while (remaining > 0) {\n const remainder = (remaining - 1) % 26;\n result = String.fromCharCode(65 + remainder) + result;\n remaining = Math.floor((remaining - 1) / 26);\n }\n\n return result;\n};\n\nexport const colNames = (startIndex: number, count: number): string[] =>\n Array.from({ length: count }, (_, i) => toColumnLetter(startIndex + i + 1));\n"],"mappings":"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","names":["useState","useEffect","useState","jsx","jsx","useRef","useMap","jsx","useState","useEffect","jsx","jsxs","useState"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapped-image",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "A React component that overlays a clickable, weighted row/column grid on top of one or more images, built on react-leaflet.",