@sandemo/easy-annotator 0.1.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/dist/components/AnnotatorModal.d.ts +13 -0
  4. package/dist/components/AnnotatorModal.d.ts.map +1 -0
  5. package/dist/components/EasyAnnotatorUpload.d.ts +3 -0
  6. package/dist/components/EasyAnnotatorUpload.d.ts.map +1 -0
  7. package/dist/components/FilePreviewList.d.ts +10 -0
  8. package/dist/components/FilePreviewList.d.ts.map +1 -0
  9. package/dist/components/ImageAnnotator.d.ts +17 -0
  10. package/dist/components/ImageAnnotator.d.ts.map +1 -0
  11. package/dist/components/UploadDropzone.d.ts +10 -0
  12. package/dist/components/UploadDropzone.d.ts.map +1 -0
  13. package/dist/easy-annotator.cjs +2 -0
  14. package/dist/easy-annotator.cjs.map +1 -0
  15. package/dist/easy-annotator.css +1 -0
  16. package/dist/easy-annotator.d.ts +2 -0
  17. package/dist/easy-annotator.js +709 -0
  18. package/dist/easy-annotator.js.map +1 -0
  19. package/dist/hooks/useEasyAnnotator.d.ts +29 -0
  20. package/dist/hooks/useEasyAnnotator.d.ts.map +1 -0
  21. package/dist/hooks/useObjectUrls.d.ts +5 -0
  22. package/dist/hooks/useObjectUrls.d.ts.map +1 -0
  23. package/dist/i18n/labels.d.ts +5 -0
  24. package/dist/i18n/labels.d.ts.map +1 -0
  25. package/dist/index.d.ts +12 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/markerjs3-DI_cywfl.js +2669 -0
  28. package/dist/markerjs3-DI_cywfl.js.map +1 -0
  29. package/dist/markerjs3-DiaiYpgs.cjs +57 -0
  30. package/dist/markerjs3-DiaiYpgs.cjs.map +1 -0
  31. package/dist/services/defaultPayloadBuilder.d.ts +3 -0
  32. package/dist/services/defaultPayloadBuilder.d.ts.map +1 -0
  33. package/dist/styles.cjs +2 -0
  34. package/dist/styles.cjs.map +1 -0
  35. package/dist/styles.d.ts +1 -0
  36. package/dist/styles.d.ts.map +1 -0
  37. package/dist/styles.js +2 -0
  38. package/dist/styles.js.map +1 -0
  39. package/dist/types/index.d.ts +95 -0
  40. package/dist/types/index.d.ts.map +1 -0
  41. package/dist/utils/errors.d.ts +8 -0
  42. package/dist/utils/errors.d.ts.map +1 -0
  43. package/dist/utils/file.d.ts +10 -0
  44. package/dist/utils/file.d.ts.map +1 -0
  45. package/dist/utils/id.d.ts +2 -0
  46. package/dist/utils/id.d.ts.map +1 -0
  47. package/dist/utils/image.d.ts +3 -0
  48. package/dist/utils/image.d.ts.map +1 -0
  49. package/package.json +72 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"easy-annotator.js","sources":["../src/utils/file.ts","../src/i18n/labels.ts","../src/utils/errors.ts","../src/utils/id.ts","../src/hooks/useObjectUrls.ts","../src/hooks/useEasyAnnotator.ts","../src/components/UploadDropzone.tsx","../src/components/FilePreviewList.tsx","../src/components/ImageAnnotator.tsx","../src/components/AnnotatorModal.tsx","../src/components/EasyAnnotatorUpload.tsx","../src/services/defaultPayloadBuilder.ts"],"sourcesContent":["import type { EasyAnnotatorFileType } from '../types'\n\nexport const DEFAULT_ACCEPT: string[] = [\n 'image/jpeg',\n 'image/jpg',\n 'image/png',\n 'image/webp',\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n]\n\nexport const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024\nexport const DEFAULT_MAX_FILES = 5\n\nconst IMAGE_MIMES = new Set(['image/jpeg', 'image/jpg', 'image/png', 'image/webp'])\n\nexport function isImageMime(mime: string): boolean {\n return IMAGE_MIMES.has(mime.toLowerCase())\n}\n\nexport function classifyFile(file: File): EasyAnnotatorFileType {\n const mime = file.type.toLowerCase()\n if (isImageMime(mime)) return 'image'\n if (mime === 'application/pdf') return 'pdf'\n if (mime === 'application/msword') return 'doc'\n if (\n mime === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n ) {\n return 'docx'\n }\n // Fall back to extension when MIME is empty (common for some browsers/OSes).\n const ext = file.name.toLowerCase().split('.').pop() ?? ''\n if (['jpg', 'jpeg', 'png', 'webp'].includes(ext)) return 'image'\n if (ext === 'pdf') return 'pdf'\n if (ext === 'doc') return 'doc'\n if (ext === 'docx') return 'docx'\n return 'doc'\n}\n\nexport function isAccepted(file: File, accept: string[]): boolean {\n if (accept.length === 0) return true\n const mime = file.type.toLowerCase()\n if (mime && accept.some((a) => a.toLowerCase() === mime)) return true\n const ext = file.name.toLowerCase().split('.').pop() ?? ''\n const extMimeMap: Record<string, string> = {\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n webp: 'image/webp',\n pdf: 'application/pdf',\n doc: 'application/msword',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n }\n const fallback = extMimeMap[ext]\n return fallback ? accept.includes(fallback) : false\n}\n\nexport function bytesToMb(bytes: number): number {\n return Math.round((bytes / (1024 * 1024)) * 10) / 10\n}\n\nexport function withAnnotatedFilename(originalName: string): string {\n const lastDot = originalName.lastIndexOf('.')\n if (lastDot <= 0) return `${originalName}-annotated.png`\n const base = originalName.slice(0, lastDot)\n return `${base}-annotated.png`\n}\n","import type { LabelOverrides } from '../types'\n\nexport const enLabels: LabelOverrides = {\n title: 'Upload',\n dropzoneText: 'Drag & drop files here, or',\n dropzoneButton: 'browse',\n annotate: 'Annotate',\n remove: 'Remove',\n upload: 'Upload',\n uploading: 'Uploading…',\n uploaded: 'Uploaded',\n retry: 'Retry',\n cancel: 'Cancel',\n save: 'Save',\n errorFileType: (filename) => `File type not allowed: ${filename}`,\n errorFileTooLarge: (filename, maxMb) => `File too large: ${filename} (max ${maxMb} MB)`,\n errorFileCount: (max) => `Maximum ${max} files`,\n errorAnnotationFailed: 'Failed to save annotation.',\n errorUploadFailed: 'Upload failed. Please retry.',\n modalTitle: 'Annotate image',\n loadingAnnotator: 'Loading annotator…',\n filesSelected: (count) => `${count} file${count === 1 ? '' : 's'} selected`,\n}\n\nexport const idLabels: LabelOverrides = {\n title: 'Unggah',\n dropzoneText: 'Seret & letakkan file di sini, atau',\n dropzoneButton: 'pilih file',\n annotate: 'Anotasi',\n remove: 'Hapus',\n upload: 'Unggah',\n uploading: 'Mengunggah…',\n uploaded: 'Terunggah',\n retry: 'Coba Lagi',\n cancel: 'Batal',\n save: 'Simpan',\n errorFileType: (filename) => `Tipe file tidak diizinkan: ${filename}`,\n errorFileTooLarge: (filename, maxMb) =>\n `File terlalu besar: ${filename} (maks ${maxMb} MB)`,\n errorFileCount: (max) => `Maksimal ${max} file`,\n errorAnnotationFailed: 'Gagal menyimpan anotasi.',\n errorUploadFailed: 'Unggah gagal. Silakan coba lagi.',\n modalTitle: 'Anotasi gambar',\n loadingAnnotator: 'Memuat anotator…',\n filesSelected: (count) => `${count} file dipilih`,\n}\n\nexport function mergeLabels(overrides?: Partial<LabelOverrides>): LabelOverrides {\n if (!overrides) return enLabels\n return { ...enLabels, ...overrides }\n}\n","import type { EasyAnnotatorError, EasyAnnotatorFile } from '../types'\n\nexport function fileTypeRejected(file: File, reason: string): EasyAnnotatorError {\n return { code: 'FILE_TYPE_REJECTED', file, reason }\n}\n\nexport function fileTooLarge(file: File, maxBytes: number): EasyAnnotatorError {\n return { code: 'FILE_TOO_LARGE', file, maxBytes }\n}\n\nexport function fileCountExceeded(maxFiles: number): EasyAnnotatorError {\n return { code: 'FILE_COUNT_EXCEEDED', maxFiles }\n}\n\nexport function annotationFailed(cause?: unknown): EasyAnnotatorError {\n return { code: 'ANNOTATION_FAILED', cause }\n}\n\nexport function uploadFailed(file: EasyAnnotatorFile, cause?: unknown): EasyAnnotatorError {\n return { code: 'UPLOAD_FAILED', cause, file }\n}\n\ndeclare const process: { env?: { NODE_ENV?: string } } | undefined\n\nexport function devWarn(...args: unknown[]): void {\n const env =\n typeof process !== 'undefined' && process?.env?.NODE_ENV\n ? process.env.NODE_ENV\n : 'development'\n if (env !== 'production') {\n // eslint-disable-next-line no-console\n console.warn('[easy-annotator]', ...args)\n }\n}\n","export function createId(): string {\n if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {\n return crypto.randomUUID()\n }\n return `ea_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`\n}\n","import { useCallback, useEffect, useRef } from 'react'\n\nexport function useObjectUrls() {\n const urlsRef = useRef<Set<string>>(new Set())\n\n const create = useCallback((blob: Blob): string => {\n const url = URL.createObjectURL(blob)\n urlsRef.current.add(url)\n return url\n }, [])\n\n const revoke = useCallback((url: string | undefined): void => {\n if (!url) return\n if (urlsRef.current.has(url)) {\n URL.revokeObjectURL(url)\n urlsRef.current.delete(url)\n }\n }, [])\n\n useEffect(() => {\n const urls = urlsRef.current\n return () => {\n urls.forEach((url) => URL.revokeObjectURL(url))\n urls.clear()\n }\n }, [])\n\n return { create, revoke }\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type {\n EasyAnnotatorError,\n EasyAnnotatorFile,\n EasyAnnotatorUploadHandler,\n EasyAnnotatorUploadPayload,\n EasyAnnotatorUploadedResult,\n} from '../types'\nimport {\n DEFAULT_ACCEPT,\n DEFAULT_MAX_FILES,\n DEFAULT_MAX_FILE_SIZE,\n bytesToMb,\n classifyFile,\n isAccepted,\n} from '../utils/file'\nimport {\n fileCountExceeded,\n fileTooLarge,\n fileTypeRejected,\n uploadFailed,\n} from '../utils/errors'\nimport { createId } from '../utils/id'\nimport { useObjectUrls } from './useObjectUrls'\n\nexport interface UseEasyAnnotatorOptions {\n accept?: string[]\n maxFileSize?: number\n maxFiles?: number\n multiple?: boolean\n ownerType: string\n ownerId: string | number\n fieldKey: string\n uploadHandler: EasyAnnotatorUploadHandler\n onError?: (err: EasyAnnotatorError, file?: EasyAnnotatorFile) => void\n onUploaded?: (items: EasyAnnotatorUploadedResult[]) => void\n onChange?: (files: EasyAnnotatorFile[]) => void\n}\n\nexport function useEasyAnnotator(options: UseEasyAnnotatorOptions) {\n const {\n accept = DEFAULT_ACCEPT,\n maxFileSize = DEFAULT_MAX_FILE_SIZE,\n maxFiles = DEFAULT_MAX_FILES,\n multiple = true,\n ownerType,\n ownerId,\n fieldKey,\n uploadHandler,\n onError,\n onUploaded,\n onChange,\n } = options\n\n const [files, setFiles] = useState<EasyAnnotatorFile[]>([])\n const [isUploading, setIsUploading] = useState(false)\n const { create: createObjectUrl, revoke: revokeObjectUrl } = useObjectUrls()\n\n // Keep latest callbacks in refs so they don't force effect re-runs.\n const onChangeRef = useRef(onChange)\n const onErrorRef = useRef(onError)\n const onUploadedRef = useRef(onUploaded)\n useEffect(() => {\n onChangeRef.current = onChange\n onErrorRef.current = onError\n onUploadedRef.current = onUploaded\n }, [onChange, onError, onUploaded])\n\n useEffect(() => {\n onChangeRef.current?.(files)\n }, [files])\n\n const addFiles = useCallback(\n (incoming: FileList | File[]) => {\n const arr = Array.from(incoming)\n setFiles((prev) => {\n const next = [...prev]\n const remainingSlots = Math.max(0, maxFiles - prev.length)\n let countExceeded = false\n\n for (const raw of arr) {\n if (!multiple && next.length >= 1) break\n if (next.length >= prev.length + remainingSlots) {\n countExceeded = true\n break\n }\n if (!isAccepted(raw, accept)) {\n onErrorRef.current?.(fileTypeRejected(raw, `MIME ${raw.type || 'unknown'}`))\n continue\n }\n if (raw.size > maxFileSize) {\n onErrorRef.current?.(fileTooLarge(raw, maxFileSize))\n continue\n }\n const fileType = classifyFile(raw)\n const previewUrl = fileType === 'image' ? createObjectUrl(raw) : undefined\n next.push({\n id: createId(),\n originalFile: raw,\n fileType,\n mimeType: raw.type || 'application/octet-stream',\n originalFilename: raw.name,\n previewUrl,\n status: 'idle',\n })\n }\n\n if (countExceeded || arr.length > remainingSlots) {\n onErrorRef.current?.(fileCountExceeded(maxFiles))\n }\n return next\n })\n },\n [accept, createObjectUrl, maxFileSize, maxFiles, multiple],\n )\n\n const removeFile = useCallback(\n (id: string) => {\n setFiles((prev) => {\n const target = prev.find((f) => f.id === id)\n if (target) {\n revokeObjectUrl(target.previewUrl)\n revokeObjectUrl(target.annotatedPreviewUrl)\n }\n return prev.filter((f) => f.id !== id)\n })\n },\n [revokeObjectUrl],\n )\n\n const setAnnotation = useCallback(\n (id: string, annotatedFile: File, annotationState: object) => {\n setFiles((prev) =>\n prev.map((f) => {\n if (f.id !== id) return f\n revokeObjectUrl(f.annotatedPreviewUrl)\n return {\n ...f,\n annotatedFile,\n annotationState,\n annotatedPreviewUrl: createObjectUrl(annotatedFile),\n }\n }),\n )\n },\n [createObjectUrl, revokeObjectUrl],\n )\n\n const clearAnnotation = useCallback(\n (id: string) => {\n setFiles((prev) =>\n prev.map((f) => {\n if (f.id !== id) return f\n revokeObjectUrl(f.annotatedPreviewUrl)\n const { annotatedFile: _af, annotationState: _as, annotatedPreviewUrl: _ap, ...rest } = f\n void _af\n void _as\n void _ap\n return { ...rest }\n }),\n )\n },\n [revokeObjectUrl],\n )\n\n const setStatus = useCallback(\n (id: string, status: EasyAnnotatorFile['status'], errorMessage?: string) => {\n setFiles((prev) =>\n prev.map((f) => (f.id === id ? { ...f, status, errorMessage } : f)),\n )\n },\n [],\n )\n\n const buildPayload = useCallback(\n (file: EasyAnnotatorFile): EasyAnnotatorUploadPayload => ({\n ownerType,\n ownerId,\n fieldKey,\n originalFile: file.originalFile,\n annotatedFile: file.annotatedFile,\n annotationState: file.annotationState,\n fileType: file.fileType,\n mimeType: file.mimeType,\n originalFilename: file.originalFilename,\n }),\n [fieldKey, ownerId, ownerType],\n )\n\n const uploadAll = useCallback(async () => {\n setIsUploading(true)\n const targets = (await new Promise<EasyAnnotatorFile[]>((resolve) => {\n setFiles((prev) => {\n const toUpload = prev.filter((f) => f.status === 'idle' || f.status === 'error')\n resolve(toUpload)\n return prev.map((f) =>\n toUpload.find((t) => t.id === f.id)\n ? { ...f, status: 'uploading', errorMessage: undefined }\n : f,\n )\n })\n })) as EasyAnnotatorFile[]\n\n const results: EasyAnnotatorUploadedResult[] = []\n\n for (const file of targets) {\n try {\n const result = await uploadHandler(buildPayload(file))\n results.push(result)\n setStatus(file.id, 'done')\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Upload failed'\n setStatus(file.id, 'error', message)\n onErrorRef.current?.(uploadFailed(file, err), file)\n }\n }\n\n setIsUploading(false)\n if (results.length > 0) onUploadedRef.current?.(results)\n return results\n }, [buildPayload, setStatus, uploadHandler])\n\n const stats = useMemo(\n () => ({\n total: files.length,\n remainingSlots: Math.max(0, maxFiles - files.length),\n maxFileSizeMb: bytesToMb(maxFileSize),\n }),\n [files.length, maxFileSize, maxFiles],\n )\n\n return {\n files,\n isUploading,\n stats,\n addFiles,\n removeFile,\n setAnnotation,\n clearAnnotation,\n uploadAll,\n }\n}\n","import { useCallback, useRef, useState, type DragEvent, type ChangeEvent } from 'react'\nimport type { LabelOverrides } from '../types'\n\nexport interface UploadDropzoneProps {\n accept: string[]\n multiple: boolean\n disabled?: boolean\n labels: LabelOverrides\n onFiles: (files: FileList | File[]) => void\n}\n\nexport function UploadDropzone({\n accept,\n multiple,\n disabled = false,\n labels,\n onFiles,\n}: UploadDropzoneProps) {\n const inputRef = useRef<HTMLInputElement>(null)\n const [isDragging, setIsDragging] = useState(false)\n\n const openPicker = useCallback(() => {\n if (disabled) return\n inputRef.current?.click()\n }, [disabled])\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files.length > 0) {\n onFiles(e.target.files)\n }\n e.target.value = ''\n },\n [onFiles],\n )\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n setIsDragging(false)\n if (disabled) return\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n onFiles(e.dataTransfer.files)\n }\n },\n [disabled, onFiles],\n )\n\n const handleDragOver = useCallback(\n (e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n if (!disabled) setIsDragging(true)\n },\n [disabled],\n )\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {\n e.preventDefault()\n setIsDragging(false)\n }, [])\n\n return (\n <div\n className={`ea-dropzone${isDragging ? ' ea-dropzone--active' : ''}${\n disabled ? ' ea-dropzone--disabled' : ''\n }`}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-disabled={disabled}\n onClick={openPicker}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n openPicker()\n }\n }}\n onDrop={handleDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n >\n <p className=\"ea-dropzone__text\">\n {labels.dropzoneText}{' '}\n <span className=\"ea-dropzone__button\">{labels.dropzoneButton}</span>\n </p>\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept.join(',')}\n multiple={multiple}\n onChange={handleChange}\n className=\"ea-dropzone__input\"\n disabled={disabled}\n aria-hidden=\"true\"\n tabIndex={-1}\n />\n </div>\n )\n}\n","import type { EasyAnnotatorFile, LabelOverrides } from '../types'\n\nexport interface FilePreviewListProps {\n files: EasyAnnotatorFile[]\n labels: LabelOverrides\n onAnnotate: (id: string) => void\n onRemove: (id: string) => void\n disabled?: boolean\n}\n\nfunction fileIcon(type: EasyAnnotatorFile['fileType']): string {\n switch (type) {\n case 'pdf':\n return 'PDF'\n case 'doc':\n return 'DOC'\n case 'docx':\n return 'DOCX'\n default:\n return 'IMG'\n }\n}\n\nexport function FilePreviewList({\n files,\n labels,\n onAnnotate,\n onRemove,\n disabled = false,\n}: FilePreviewListProps) {\n if (files.length === 0) return null\n\n return (\n <ul className=\"ea-list\" role=\"list\">\n {files.map((file) => {\n const isImage = file.fileType === 'image'\n const thumb = file.annotatedPreviewUrl ?? file.previewUrl\n return (\n <li key={file.id} className=\"ea-list__item\" data-status={file.status}>\n <div className=\"ea-list__thumb\">\n {isImage && thumb ? (\n <img src={thumb} alt={file.originalFilename} />\n ) : (\n <span className=\"ea-list__icon\">{fileIcon(file.fileType)}</span>\n )}\n </div>\n <div className=\"ea-list__meta\">\n <p className=\"ea-list__name\" title={file.originalFilename}>\n {file.originalFilename}\n </p>\n <p className=\"ea-list__status\">\n {file.status === 'uploading' && labels.uploading}\n {file.status === 'done' && labels.uploaded}\n {file.status === 'error' && (file.errorMessage ?? labels.errorUploadFailed)}\n {file.status === 'idle' && file.annotatedFile && '✓ annotated'}\n </p>\n </div>\n <div className=\"ea-list__actions\">\n {isImage && (\n <button\n type=\"button\"\n className=\"ea-btn ea-btn--ghost\"\n onClick={() => onAnnotate(file.id)}\n disabled={disabled || file.status === 'uploading'}\n >\n {labels.annotate}\n </button>\n )}\n <button\n type=\"button\"\n className=\"ea-btn ea-btn--danger\"\n onClick={() => onRemove(file.id)}\n disabled={disabled || file.status === 'uploading'}\n aria-label={`${labels.remove} ${file.originalFilename}`}\n >\n {labels.remove}\n </button>\n </div>\n </li>\n )\n })}\n </ul>\n )\n}\n","import { useEffect, useRef, useState } from 'react'\nimport type { LabelOverrides } from '../types'\nimport { withAnnotatedFilename } from '../utils/file'\nimport { annotationFailed, devWarn } from '../utils/errors'\n\nexport interface ImageAnnotatorHandle {\n save: () => Promise<{ file: File; state: object }>\n}\n\nexport interface ImageAnnotatorProps {\n src: string\n originalFilename: string\n initialState?: object\n labels: LabelOverrides\n onReady?: (handle: ImageAnnotatorHandle) => void\n onError?: (err: unknown) => void\n}\n\n// Local minimal interfaces so we don't leak marker.js types through our public .d.ts.\ntype MarkerAreaLike = HTMLElement & {\n targetImage: HTMLImageElement | undefined\n getState: () => object\n restoreState: (state: object, addUndoStep?: boolean) => void\n}\n\ntype RendererLike = {\n targetImage: HTMLImageElement | undefined\n rasterize: (state: object, targetCanvas?: HTMLCanvasElement) => Promise<string>\n}\n\ntype MarkerJsModule = {\n MarkerArea: new () => MarkerAreaLike\n Renderer: new () => RendererLike\n}\n\nexport function ImageAnnotator({\n src,\n originalFilename,\n initialState,\n labels,\n onReady,\n onError,\n}: ImageAnnotatorProps) {\n const containerRef = useRef<HTMLDivElement>(null)\n const imgRef = useRef<HTMLImageElement>(null)\n const markerAreaRef = useRef<MarkerAreaLike | null>(null)\n const rendererCtorRef = useRef<(new () => RendererLike) | null>(null)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n let disposed = false\n\n async function init() {\n try {\n const mod = (await import('@markerjs/markerjs3')) as unknown as MarkerJsModule\n if (disposed) return\n const img = imgRef.current\n const container = containerRef.current\n if (!img || !container) return\n\n // Wait for the <img> to have natural dimensions before handing it to MarkerArea.\n if (!img.complete || img.naturalWidth === 0) {\n await new Promise<void>((resolve, reject) => {\n img.addEventListener('load', () => resolve(), { once: true })\n img.addEventListener('error', () => reject(new Error('Image failed to load')), {\n once: true,\n })\n })\n if (disposed) return\n }\n\n const markerArea = new mod.MarkerArea()\n // marker.js 3's MarkerArea is a custom element — append, then set the target image.\n container.appendChild(markerArea)\n markerArea.targetImage = img\n\n if (initialState) {\n try {\n markerArea.restoreState(initialState, false)\n } catch (restoreErr) {\n devWarn('Failed to restore annotation state:', restoreErr)\n }\n }\n\n markerAreaRef.current = markerArea\n rendererCtorRef.current = mod.Renderer\n setLoading(false)\n\n onReady?.({\n save: async () => {\n const area = markerAreaRef.current\n const RendererCtor = rendererCtorRef.current\n const targetImg = imgRef.current\n if (!area || !RendererCtor || !targetImg) {\n throw new Error('Annotator is not ready.')\n }\n const state = area.getState()\n const renderer = new RendererCtor()\n renderer.targetImage = targetImg\n const dataUrl = await renderer.rasterize(state)\n const file = await dataUrlToFile(\n dataUrl,\n withAnnotatedFilename(originalFilename),\n )\n return { file, state }\n },\n })\n } catch (err) {\n if (disposed) return\n setLoading(false)\n setError(labels.errorAnnotationFailed)\n devWarn('Failed to load marker.js:', err)\n onError?.(annotationFailed(err))\n }\n }\n\n void init()\n\n return () => {\n disposed = true\n const area = markerAreaRef.current\n if (area && containerRef.current?.contains(area)) {\n containerRef.current.removeChild(area)\n }\n markerAreaRef.current = null\n rendererCtorRef.current = null\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [src])\n\n return (\n <div className=\"ea-annotator\">\n <div className=\"ea-annotator__stage\" ref={containerRef}>\n <img\n ref={imgRef}\n src={src}\n alt=\"\"\n className=\"ea-annotator__img\"\n crossOrigin=\"anonymous\"\n />\n </div>\n {loading && <div className=\"ea-annotator__loading\">{labels.loadingAnnotator}</div>}\n {error && <div className=\"ea-annotator__error\">{error}</div>}\n </div>\n )\n}\n\nasync function dataUrlToFile(dataUrl: string, filename: string): Promise<File> {\n const res = await fetch(dataUrl)\n const blob = await res.blob()\n return new File([blob], filename, { type: blob.type || 'image/png' })\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { LabelOverrides } from '../types'\nimport { ImageAnnotator, type ImageAnnotatorHandle } from './ImageAnnotator'\n\nexport interface AnnotatorModalProps {\n open: boolean\n src: string | null\n originalFilename: string\n initialState?: object\n labels: LabelOverrides\n onSave: (annotatedFile: File, annotationState: object) => void\n onCancel: () => void\n onError?: (err: unknown) => void\n}\n\nexport function AnnotatorModal({\n open,\n src,\n originalFilename,\n initialState,\n labels,\n onSave,\n onCancel,\n onError,\n}: AnnotatorModalProps) {\n const handleRef = useRef<ImageAnnotatorHandle | null>(null)\n const dialogRef = useRef<HTMLDivElement>(null)\n const [saving, setSaving] = useState(false)\n\n const handleSave = useCallback(async () => {\n if (!handleRef.current) return\n setSaving(true)\n try {\n const { file, state } = await handleRef.current.save()\n onSave(file, state)\n } catch (err) {\n onError?.(err)\n } finally {\n setSaving(false)\n }\n }, [onError, onSave])\n\n useEffect(() => {\n if (!open) return\n const previousActive = document.activeElement as HTMLElement | null\n dialogRef.current?.focus()\n\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onCancel()\n }\n document.addEventListener('keydown', handleKey)\n const previousOverflow = document.body.style.overflow\n document.body.style.overflow = 'hidden'\n return () => {\n document.removeEventListener('keydown', handleKey)\n document.body.style.overflow = previousOverflow\n previousActive?.focus?.()\n }\n }, [onCancel, open])\n\n if (!open || !src) return null\n\n return (\n <div\n className=\"ea-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={labels.modalTitle}\n onClick={(e) => {\n if (e.target === e.currentTarget) onCancel()\n }}\n >\n <div className=\"ea-modal__dialog\" ref={dialogRef} tabIndex={-1}>\n <header className=\"ea-modal__header\">\n <h2 className=\"ea-modal__title\">{labels.modalTitle}</h2>\n <button\n type=\"button\"\n className=\"ea-btn ea-btn--ghost\"\n onClick={onCancel}\n aria-label={labels.cancel}\n >\n ×\n </button>\n </header>\n <div className=\"ea-modal__body\">\n <ImageAnnotator\n src={src}\n originalFilename={originalFilename}\n initialState={initialState}\n labels={labels}\n onReady={(h) => {\n handleRef.current = h\n }}\n onError={onError}\n />\n </div>\n <footer className=\"ea-modal__footer\">\n <button\n type=\"button\"\n className=\"ea-btn ea-btn--ghost\"\n onClick={onCancel}\n disabled={saving}\n >\n {labels.cancel}\n </button>\n <button\n type=\"button\"\n className=\"ea-btn ea-btn--primary\"\n onClick={handleSave}\n disabled={saving}\n >\n {saving ? labels.uploading : labels.save}\n </button>\n </footer>\n </div>\n </div>\n )\n}\n","import { useCallback, useMemo, useState } from 'react'\nimport type { EasyAnnotatorUploadProps } from '../types'\nimport { DEFAULT_ACCEPT, DEFAULT_MAX_FILES, DEFAULT_MAX_FILE_SIZE, bytesToMb } from '../utils/file'\nimport { mergeLabels } from '../i18n/labels'\nimport { useEasyAnnotator } from '../hooks/useEasyAnnotator'\nimport { UploadDropzone } from './UploadDropzone'\nimport { FilePreviewList } from './FilePreviewList'\nimport { AnnotatorModal } from './AnnotatorModal'\nimport { annotationFailed } from '../utils/errors'\n\nexport function EasyAnnotatorUpload(props: EasyAnnotatorUploadProps) {\n const {\n title,\n ownerType,\n ownerId,\n fieldKey,\n uploadHandler,\n onUploaded,\n onError,\n onChange,\n accept = DEFAULT_ACCEPT,\n maxFileSize = DEFAULT_MAX_FILE_SIZE,\n maxFiles = DEFAULT_MAX_FILES,\n multiple = true,\n labels: labelOverrides,\n className,\n disabled = false,\n } = props\n\n const labels = useMemo(() => mergeLabels(labelOverrides), [labelOverrides])\n const resolvedTitle = title ?? labels.title\n\n const {\n files,\n isUploading,\n stats,\n addFiles,\n removeFile,\n setAnnotation,\n uploadAll,\n } = useEasyAnnotator({\n accept,\n maxFileSize,\n maxFiles,\n multiple,\n ownerType,\n ownerId,\n fieldKey,\n uploadHandler,\n onError,\n onUploaded,\n onChange,\n })\n\n const [activeAnnotateId, setActiveAnnotateId] = useState<string | null>(null)\n const activeFile = useMemo(\n () => files.find((f) => f.id === activeAnnotateId) ?? null,\n [activeAnnotateId, files],\n )\n\n const handleAnnotate = useCallback((id: string) => {\n setActiveAnnotateId(id)\n }, [])\n\n const handleCancelAnnotate = useCallback(() => {\n setActiveAnnotateId(null)\n }, [])\n\n const handleSaveAnnotation = useCallback(\n (annotatedFile: File, annotationState: object) => {\n if (activeAnnotateId) {\n setAnnotation(activeAnnotateId, annotatedFile, annotationState)\n }\n setActiveAnnotateId(null)\n },\n [activeAnnotateId, setAnnotation],\n )\n\n const handleAnnotatorError = useCallback(\n (err: unknown) => {\n onError?.(annotationFailed(err))\n },\n [onError],\n )\n\n const canUpload =\n !disabled &&\n !isUploading &&\n files.some((f) => f.status === 'idle' || f.status === 'error')\n\n return (\n <section className={`ea-root${className ? ` ${className}` : ''}`}>\n <header className=\"ea-header\">\n <h2 className=\"ea-title\">{resolvedTitle}</h2>\n <p className=\"ea-subtitle\">\n {labels.filesSelected(stats.total)} · max {bytesToMb(maxFileSize)} MB · up to {maxFiles}{' '}\n files\n </p>\n </header>\n\n <UploadDropzone\n accept={accept}\n multiple={multiple}\n disabled={disabled || stats.remainingSlots === 0}\n labels={labels}\n onFiles={addFiles}\n />\n\n <FilePreviewList\n files={files}\n labels={labels}\n onAnnotate={handleAnnotate}\n onRemove={removeFile}\n disabled={disabled}\n />\n\n {files.length > 0 && (\n <div className=\"ea-actions\">\n <button\n type=\"button\"\n className=\"ea-btn ea-btn--primary\"\n onClick={() => {\n void uploadAll()\n }}\n disabled={!canUpload}\n >\n {isUploading ? labels.uploading : labels.upload}\n </button>\n </div>\n )}\n\n <AnnotatorModal\n open={Boolean(activeFile)}\n src={activeFile?.previewUrl ?? null}\n originalFilename={activeFile?.originalFilename ?? ''}\n initialState={activeFile?.annotationState}\n labels={labels}\n onSave={handleSaveAnnotation}\n onCancel={handleCancelAnnotate}\n onError={handleAnnotatorError}\n />\n </section>\n )\n}\n","import type { EasyAnnotatorUploadPayload } from '../types'\n\nexport function buildFormDataPayload(payload: EasyAnnotatorUploadPayload): FormData {\n const fd = new FormData()\n fd.append('owner_type', payload.ownerType)\n fd.append('owner_id', String(payload.ownerId))\n fd.append('field_key', payload.fieldKey)\n fd.append('original_file', payload.originalFile, payload.originalFile.name)\n if (payload.annotatedFile) {\n fd.append('annotated_file', payload.annotatedFile, payload.annotatedFile.name)\n }\n if (payload.annotationState) {\n fd.append('annotation_state', JSON.stringify(payload.annotationState))\n }\n fd.append('file_type', payload.fileType)\n fd.append('mime_type', payload.mimeType)\n fd.append('original_filename', payload.originalFilename)\n return fd\n}\n"],"names":["DEFAULT_ACCEPT","DEFAULT_MAX_FILE_SIZE","DEFAULT_MAX_FILES","IMAGE_MIMES","isImageMime","mime","classifyFile","file","ext","isAccepted","accept","a","fallback","bytesToMb","bytes","withAnnotatedFilename","originalName","lastDot","enLabels","filename","maxMb","max","count","idLabels","mergeLabels","overrides","fileTypeRejected","reason","fileTooLarge","maxBytes","fileCountExceeded","maxFiles","annotationFailed","cause","uploadFailed","devWarn","args","_a","createId","useObjectUrls","urlsRef","useRef","create","useCallback","blob","url","revoke","useEffect","urls","useEasyAnnotator","options","maxFileSize","multiple","ownerType","ownerId","fieldKey","uploadHandler","onError","onUploaded","onChange","files","setFiles","useState","isUploading","setIsUploading","createObjectUrl","revokeObjectUrl","onChangeRef","onErrorRef","onUploadedRef","addFiles","incoming","arr","prev","next","remainingSlots","countExceeded","raw","_b","fileType","previewUrl","_c","removeFile","id","target","f","setAnnotation","annotatedFile","annotationState","clearAnnotation","_af","_as","_ap","rest","setStatus","status","errorMessage","buildPayload","uploadAll","targets","resolve","toUpload","t","results","result","err","message","stats","useMemo","UploadDropzone","disabled","labels","onFiles","inputRef","isDragging","setIsDragging","openPicker","handleChange","e","handleDrop","handleDragOver","handleDragLeave","jsxs","jsx","fileIcon","type","FilePreviewList","onAnnotate","onRemove","isImage","thumb","ImageAnnotator","src","originalFilename","initialState","onReady","containerRef","imgRef","markerAreaRef","rendererCtorRef","loading","setLoading","error","setError","disposed","init","mod","img","container","reject","markerArea","restoreErr","area","RendererCtor","targetImg","state","renderer","dataUrl","dataUrlToFile","AnnotatorModal","open","onSave","onCancel","handleRef","dialogRef","saving","setSaving","handleSave","previousActive","handleKey","previousOverflow","h","EasyAnnotatorUpload","props","title","labelOverrides","className","resolvedTitle","activeAnnotateId","setActiveAnnotateId","activeFile","handleAnnotate","handleCancelAnnotate","handleSaveAnnotation","handleAnnotatorError","canUpload","buildFormDataPayload","payload","fd"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { EasyAnnotatorError, EasyAnnotatorFile, EasyAnnotatorUploadHandler, EasyAnnotatorUploadedResult } from '../types';
2
+ export interface UseEasyAnnotatorOptions {
3
+ accept?: string[];
4
+ maxFileSize?: number;
5
+ maxFiles?: number;
6
+ multiple?: boolean;
7
+ ownerType: string;
8
+ ownerId: string | number;
9
+ fieldKey: string;
10
+ uploadHandler: EasyAnnotatorUploadHandler;
11
+ onError?: (err: EasyAnnotatorError, file?: EasyAnnotatorFile) => void;
12
+ onUploaded?: (items: EasyAnnotatorUploadedResult[]) => void;
13
+ onChange?: (files: EasyAnnotatorFile[]) => void;
14
+ }
15
+ export declare function useEasyAnnotator(options: UseEasyAnnotatorOptions): {
16
+ files: EasyAnnotatorFile[];
17
+ isUploading: boolean;
18
+ stats: {
19
+ total: number;
20
+ remainingSlots: number;
21
+ maxFileSizeMb: number;
22
+ };
23
+ addFiles: (incoming: FileList | File[]) => void;
24
+ removeFile: (id: string) => void;
25
+ setAnnotation: (id: string, annotatedFile: File, annotationState: object) => void;
26
+ clearAnnotation: (id: string) => void;
27
+ uploadAll: () => Promise<EasyAnnotatorUploadedResult[]>;
28
+ };
29
+ //# sourceMappingURL=useEasyAnnotator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEasyAnnotator.d.ts","sourceRoot":"","sources":["../../src/hooks/useEasyAnnotator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAE1B,2BAA2B,EAC5B,MAAM,UAAU,CAAA;AAkBjB,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,0BAA0B,CAAA;IACzC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,iBAAiB,KAAK,IAAI,CAAA;IACrE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,EAAE,KAAK,IAAI,CAAA;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAA;CAChD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB;;;;;;;;yBAkClD,QAAQ,GAAG,IAAI,EAAE;qBA4CvB,MAAM;wBAcN,MAAM,iBAAiB,IAAI,mBAAmB,MAAM;0BAkBpD,MAAM;;EA4Fd"}
@@ -0,0 +1,5 @@
1
+ export declare function useObjectUrls(): {
2
+ create: (blob: Blob) => string;
3
+ revoke: (url: string | undefined) => void;
4
+ };
5
+ //# sourceMappingURL=useObjectUrls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useObjectUrls.d.ts","sourceRoot":"","sources":["../../src/hooks/useObjectUrls.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa;mBAGO,IAAI,KAAG,MAAM;kBAMd,MAAM,GAAG,SAAS,KAAG,IAAI;EAiB3D"}
@@ -0,0 +1,5 @@
1
+ import { LabelOverrides } from '../types';
2
+ export declare const enLabels: LabelOverrides;
3
+ export declare const idLabels: LabelOverrides;
4
+ export declare function mergeLabels(overrides?: Partial<LabelOverrides>): LabelOverrides;
5
+ //# sourceMappingURL=labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labels.d.ts","sourceRoot":"","sources":["../../src/i18n/labels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C,eAAO,MAAM,QAAQ,EAAE,cAoBtB,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,cAqBtB,CAAA;AAED,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,cAAc,CAG/E"}
@@ -0,0 +1,12 @@
1
+ export { EasyAnnotatorUpload } from './components/EasyAnnotatorUpload';
2
+ export { AnnotatorModal } from './components/AnnotatorModal';
3
+ export { ImageAnnotator } from './components/ImageAnnotator';
4
+ export { UploadDropzone } from './components/UploadDropzone';
5
+ export { FilePreviewList } from './components/FilePreviewList';
6
+ export { useEasyAnnotator } from './hooks/useEasyAnnotator';
7
+ export { useObjectUrls } from './hooks/useObjectUrls';
8
+ export { buildFormDataPayload } from './services/defaultPayloadBuilder';
9
+ export { enLabels, idLabels, mergeLabels } from './i18n/labels';
10
+ export { DEFAULT_ACCEPT, DEFAULT_MAX_FILES, DEFAULT_MAX_FILE_SIZE, classifyFile, isAccepted, bytesToMb, } from './utils/file';
11
+ export type { EasyAnnotatorFile, EasyAnnotatorFileType, EasyAnnotatorStatus, EasyAnnotatorUploadPayload, EasyAnnotatorUploadedResult, EasyAnnotatorUploadHandler, EasyAnnotatorUploadProps, EasyAnnotatorConfig, EasyAnnotatorError, EasyAnnotatorErrorCode, LabelOverrides, } from './types';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAG9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AAGvE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAG/D,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACV,SAAS,GACV,MAAM,cAAc,CAAA;AAGrB,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,GACf,MAAM,SAAS,CAAA"}