shadcn.io is not affiliated with official shadcn/ui
Photo Editor Sidebar Block for React Aria
A photo editor in a fixed-height window: Adjustments opens Brightness, Contrast and Fade sliders under its row that filter a drawn greyscale scene, with a Reset and three more tools.
Installation
Overview
Put an editor's controls inside its navigation with this photo editor sidebar for React with React Aria. A window framed by a hairline with a plus mark on each corner holds the Sidebar with four tools: Adjustments, Filters, Crop and Resize. Choosing a tool opens its controls under its own row. Adjustments opens three Slider rows (Brightness, Contrast and Fade), each with its value beside the label, and a Reset that puts them back; as you drag, the page's scene, a hill, a sun and a fence drawn in greyscale from plain shapes, is filtered by the same values. Filters lays a grain over the scene, Crop a thirds grid and Resize the picture's size, and a list under the scene repeats the three values in text. Where each slider settles, the status line says so. It is built from Sidebar, Slider, Button, Avatar and Guides, with a CSS entrance only. Folded to icons the rail keeps the four tool icons with tooltips and hides the sliders; below the medium breakpoint it is a sheet. For photo, image and video editors and any tool whose controls belong next to its menu.
FAQ
How do the sliders change the picture?
Each slider's value is mapped to a number and written to the scene as a CSS variable: brightness from 0.6 to 1.4 and contrast from 0.5 to 1.5 feed one filter, and fade from 0 to 0.6 is the opacity of a plain layer laid over the picture. The picture itself is an SVG of a few shapes in the theme's own tokens, so it follows light and dark. Nothing is rendered to a canvas, which keeps the drag light. The sliders read from the middle, so Brightness +12 means 12 above the starting point and 0 is the original.
Why does the status line wait for the slider to settle?
A live region that speaks on every step of a drag would read out dozens of values. The values on the page and in the rail follow the drag, and the status line says the three settings once, when the thumb is released or a key press ends. Each slider also has its own value text for screen readers ("Brightness: plus 12").
What do Filters, Crop and Resize do?
They are plain rows that open a one-line note and lay a marker over the picture: a grain for Filters, a thirds grid inside a frame for Crop and the pixel size along the bottom for Resize. They show where a real tool would draw; nothing is cropped or resized. Adjustments is the one tool with controls in the rail.
What stays in the page, and how do I connect it?
Everything: the three values and the open tool are the block's own state, the picture is a drawing and nothing is opened, edited or saved. Replace SliderRow's two handlers with your editor's: onSet for the live value and onSettle for the committed one. The tools are pressed buttons rather than links. The provider is set with persist={false} and shortcut={false}, so the block writes no cookie and leaves Ctrl and Command with B to the page it sits on.
How does it work on a phone?
Below the medium breakpoint the sidebar is a sheet that the menu button opens from the start edge, the right in a right-to-left layout, and the sliders work inside it. Because the controls are behind that button, the page repeats the three values in a list under the picture and the status line says them after each adjustment, so the first screen always shows the result. Escape closes the sheet and focus returns to the menu button.
Is it accessible?
The sidebar is a navigation landmark named after the product. Each slider has a visible label, a value and the arrow, Home, End and Page keys; the Reset button is disabled while everything is at its start. The picture is hidden from assistive technology, since the list of values and the status line say everything it shows. Values are signed numbers isolated for right-to-left layouts.