From 7d854ad0488dea4eeaf07b07cc121e81b2eab8e8 Mon Sep 17 00:00:00 2001 From: Abhinav Dhiman Date: Tue, 14 Oct 2025 16:00:55 +0530 Subject: [PATCH 1/6] feat: add object detection focus options and coordinate-based positioning for image transformations --- examples/react-example/src/index.tsx | 6 + .../src/ImageKitEditor.tsx | 10 +- .../sidebar/transformation-config-sidebar.tsx | 106 +++++--- packages/imagekit-editor-dev/src/index.tsx | 1 + .../imagekit-editor-dev/src/schema/index.ts | 239 +++++++++++++++++- packages/imagekit-editor-dev/src/store.ts | 11 + 6 files changed, 330 insertions(+), 43 deletions(-) diff --git a/examples/react-example/src/index.tsx b/examples/react-example/src/index.tsx index c227ce9..2100c20 100644 --- a/examples/react-example/src/index.tsx +++ b/examples/react-example/src/index.tsx @@ -36,6 +36,12 @@ function App() { requireSignedUrl: false, }, }, + { + url: "https://ik.imagekit.io/v3sxk1svj/brown%20bear%20plush%20toy%20on%20whi....jpg?updatedAt=1760432666859", + metadata: { + requireSignedUrl: false, + }, + }, // ...Array.from({ length: 10000 }).map((_, i) => ({ // url: `https://ik.imagekit.io/v3sxk1svj/placeholder.jpg?updatedAt=${Date.now()}&v=${i}`, // metadata: { diff --git a/packages/imagekit-editor-dev/src/ImageKitEditor.tsx b/packages/imagekit-editor-dev/src/ImageKitEditor.tsx index bd9f3db..886a512 100644 --- a/packages/imagekit-editor-dev/src/ImageKitEditor.tsx +++ b/packages/imagekit-editor-dev/src/ImageKitEditor.tsx @@ -4,6 +4,7 @@ import merge from "lodash/merge" import React, { forwardRef, useImperativeHandle } from "react" import { EditorLayout, EditorWrapper } from "./components/editor" import type { HeaderProps } from "./components/header" +import type { DEFAULT_FOCUS_OBJECTS } from "./schema" import { type FileElement, type RequiredMetadata, @@ -24,7 +25,9 @@ interface EditorProps { signer?: Signer onAddImage?: () => void exportOptions?: HeaderProps["exportOptions"] - + focusObjects?: ReadonlyArray< + (typeof DEFAULT_FOCUS_OBJECTS)[number] | (string & {}) + > onClose: (args: { dirty: boolean; destroy: () => void }) => void } @@ -32,7 +35,7 @@ function ImageKitEditorImpl( props: EditorProps, ref: React.Ref, ) { - const { theme, initialImages, signer } = props + const { theme, initialImages, signer, focusObjects } = props const { addImage, addImages, @@ -62,8 +65,9 @@ function ImageKitEditorImpl( initialize({ imageList: initialImages, signer, + focusObjects, }) - }, [initialImages, signer, initialize]) + }, [initialImages, signer, focusObjects, initialize]) useImperativeHandle( ref, diff --git a/packages/imagekit-editor-dev/src/components/sidebar/transformation-config-sidebar.tsx b/packages/imagekit-editor-dev/src/components/sidebar/transformation-config-sidebar.tsx index 294187d..24a8bb6 100644 --- a/packages/imagekit-editor-dev/src/components/sidebar/transformation-config-sidebar.tsx +++ b/packages/imagekit-editor-dev/src/components/sidebar/transformation-config-sidebar.tsx @@ -37,13 +37,14 @@ import { PiArrowLeft } from "@react-icons/all-files/pi/PiArrowLeft" import { PiCaretDown } from "@react-icons/all-files/pi/PiCaretDown" import { PiInfo } from "@react-icons/all-files/pi/PiInfo" import { PiX } from "@react-icons/all-files/pi/PiX" +import startCase from "lodash/startCase" import { useEffect, useMemo } from "react" import { Controller, type SubmitHandler, useForm } from "react-hook-form" import Select from "react-select" import CreateableSelect from "react-select/creatable" import { z } from "zod/v3" import type { TransformationField } from "../../schema" -import { transformationSchema } from "../../schema" +import { DEFAULT_FOCUS_OBJECTS, transformationSchema } from "../../schema" import { useEditorStore } from "../../store" import { isStepAligned } from "../../utils" import AnchorField from "../common/AnchorField" @@ -61,6 +62,7 @@ export const TransformationConfigSidebar: React.FC = () => { addTransformation, updateTransformation, imageList, + focusObjects, _setSidebarState, _internalState, _setTransformationToEdit, @@ -296,40 +298,74 @@ export const TransformationConfigSidebar: React.FC = () => { ( -