# The full editor

> One component with every tool. Use it as is, or trim it down.

```tsx
"use client";

import { ImageEditor } from "@/components/image-editor/image-editor";

export default function FullEditorExample() {
  return <ImageEditor className="h-[680px] overflow-hidden rounded-xl border" src="/samples/mountain-lake.jpg" />;
}
```

## Installation

```bash
npx shadcn@latest add @photocn/image-editor
```

## Choose the tools

`tools` sets which tools appear. `panels` replaces a built-in panel or adds a panel for your own tool. Custom panels use `useImageEditor()`, just like the built-in ones.

```tsx
"use client";

import { CropIcon, SlidersHorizontalIcon, StickerIcon, WandSparklesIcon } from "lucide-react";
import { useImageEditor } from "photocn/react";

import { Button } from "@/components/ui/button";
import { ImageEditor } from "@/components/image-editor/image-editor";

// The full editor, trimmed to three built-in tools plus one of your own.
export default function CustomToolsExample() {
  return (
    <ImageEditor
      className="h-[640px] overflow-hidden rounded-xl border"
      defaultTool="filters"
      panels={{ stamp: <StampPanel /> }}
      showRecipes={false}
      src="/samples/dog.jpg"
      tools={[
        { value: "filters", label: "Filters", icon: WandSparklesIcon },
        { value: "adjust", label: "Adjust", icon: SlidersHorizontalIcon },
        { value: "compose", label: "Crop", icon: CropIcon },
        { value: "stamp", label: "Looks", icon: StickerIcon },
      ]}
    />
  );
}

// Custom panels get the same API as the built-in ones.
function StampPanel() {
  const editor = useImageEditor();
  const looks = {
    Moody: { exposure: -0.15, contrast: 0.35, shadows: -0.2 },
    Airy: { exposure: 0.2, contrast: -0.15, highlights: -0.3 },
    Punchy: { contrast: 0.45, bloom: 0.15 },
  } as const;
  return (
    <div className="flex flex-col gap-2 p-4">
      <h2 className="text-sm font-semibold">One-tap looks</h2>
      {Object.entries(looks).map(([name, look]) => (
        <Button
          key={name}
          onClick={() => editor.adjust.setLights({ ...editor.adjust.value.lights, ...look })}
          variant="outline"
        >
          {name}
        </Button>
      ))}
    </div>
  );
}
```

## On phones

When the editor is narrower than 640px, it switches to a phone layout: the tools move to a bar at the bottom, and each tool's controls open in a sheet. Set `layout="compact"` or `layout="desktop"` to choose a layout yourself. See [Compact layout](https://photocn.dev/docs/compact-layout).

## Props

`ImageEditor` takes every [option](https://photocn.dev/docs/api) of `useImageEditorState`, plus:

| Prop | Type | Description |
| --- | --- | --- |
| `editor` | `ImageEditorApi` | An editor you created with `useImageEditorState()`. |
| `tools` | `EditorToolbarTool[]` | The tools to show. Default: all of them. |
| `panels` | `Record<toolId, ReactNode>` | Replace a panel or add your own. |
| `layout` | `"auto" \| "desktop" \| "compact"` | Default `"auto"`: compact below 640px. |
| `showOpenButton` | `boolean` | Show the Open button. Default `true`. |
| `showRecipes` | `boolean` | Show the save/load look buttons. Default `true`. |
| `showHistogram` | `boolean` | Show the histogram. Default `true`. |
| `toolbarExtra` | `ReactNode` | Extra buttons, placed before Export. |
| `onSave` | `(result) => void` | Adds a Save button to the export panel, e.g. to upload the result. |
