> ## Documentation Index
> Fetch the complete documentation index at: https://docs.graphy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Editor panel

Build a settings panel from ready-made sections for text, axes, chart types and more. Panel controls use the same [commands](https://docs.graphy.dev/sdk-next/editing/commands-and-history.md) and undo history as the chart's edit menu.

Place the sections you need inside `EditorPanel.Root`, under the chart's `<GraphProvider>`:

```tsx theme={null}
import { GraphProvider } from '@graphysdk/react';
import {
  AxisSection,
  EditableGraphRenderer,
  EditorPanel,
  TitleSection,
} from '@graphysdk/react/editable';

<GraphProvider spec={spec} data={data}>
  <div style={{ display: 'flex' }}>
    <EditableGraphRenderer mode="edit" />
    <EditorPanel.Root defaultExpandedSection="Y-axis">
      <TitleSection />
      <AxisSection axis="y" />
    </EditorPanel.Root>
  </div>
</GraphProvider>;
```

Sections appear in the order you list them. One collapsible section can be open at a time; `defaultExpandedSection` identifies it by title. Without that prop, all start closed. Scope CSS to `[data-graphy-editor-panel]`, also exported as `PANEL_ROOT_ATTRIBUTE`.

The panel works in any renderer mode, including `'readonly'`. Set `mode="edit"` to also enable editing directly on the chart.

## Ready-made panels

Two assembled panels accept the same props as `EditorPanel.Root`:

* `ElementsPanel`: title, subtitle, caption, source and text size.
* `AxesPanel`: an `AxisSection` for each of `x` and `y`.

```tsx theme={null}
import { AxesPanel, ElementsPanel } from '@graphysdk/react/editable';

<>
  <ElementsPanel defaultExpandedSection="Title" />
  <AxesPanel />
</>;
```

Pass children to replace either panel's default sections.

## Pick your sections

Sections read the chart from their panel and hide when inapplicable. A fixed list therefore adapts to chart type changes. No props are required except where noted.

**Text**

* `TitleSection`, `SubtitleSection`, `CaptionSection` — text and visibility. Hiding preserves the text.
* `SourceSection` — the source's name and URL.
* `TextSizeSection` — a multiplier for all chart text.

**Frame and axes**

* `AppearanceSection` — frame corner radius and highlight dimming style.
* `AxisSection` (requires `axis="x"` or `axis="y"`) — visibility, title, ticks, label mode, position, direction, scale and domain bounds. Combo charts also offer a y-axis count. Hidden for circular axes and radial axes without a continuous scale.
* `GridSection` — a visibility switch per direction, with one shared style and thickness.
* `LegendSection` (`positions?`) — placement, alignment and style. `positions` limits choices while retaining the current position.

**Chart**

* `GraphTypeSection` — chart type picker.
* `ComboSection` — grouped bars, stacked bars or lines for an existing combo chart.
* `MappingSection` — which column feeds each aesthetic.
* `GraphOptionsSection` (`layerId?`) — data labels, percentages, stack totals and band labels. Defaults to the first layer.
* `NumberFormatSection` — abbreviation and decimal places for every number in the chart.
* `HeadlineSection` — headline metric, comparison, position and size.

**Geoms**

* `BarSection` — bar thickness and corner rounding.
* `LineSection` — thickness, curve, point visibility, size and shape, fill and missing values. Only with a line or area layer.
* `PointSection` — size and shape of standalone points. A line's companion points use `LineSection`.
* `PolarSection` — inner radius and start angle. Only on a polar chart.

**Annotations**

* `GoalSection` — goal line with a visibility toggle. Hidden on polar charts.
* `TrendsAndAveragesSection` — trend and average lines. Hidden on polar charts.
* `CalloutsSection` — text, arrow, box and difference callouts. Difference callouts require cartesian coordinates.

Sections accept `OverridableSectionProps`:

* `title`: heading and identity within the panel. Use distinct titles; `defaultExpandedSection` matches this value.
* `layout`: `'collapsible'` (default), `'fixed'` (always expanded) or `'inline'` (control beside the heading). `GoalSection` is always collapsible and has no `layout` prop.
* `preview`: summary beside a closed section's heading. `MappingSection` has no default preview.

```tsx theme={null}
<EditorPanel.Root>
  <LegendSection title="Legend placement" positions={['top', 'bottom']} />
  <GridSection layout="fixed" />
  <GraphOptionsSection layerId="bars" />
</EditorPanel.Root>
```

## Outside the provider

To render a panel outside the chart's provider, pass a `GraphHandle`. A callback ref stores the handle in state and mounts the panel when it is ready:

```tsx theme={null}
import { useState } from 'react';
import { GraphProvider, type GraphHandle } from '@graphysdk/react';
import {
  EditableGraphRenderer,
  EditorPanel,
  LegendSection,
} from '@graphysdk/react/editable';

function Page() {
  const [handle, setHandle] = useState<GraphHandle | null>(null);

  return (
    <>
      <GraphProvider spec={spec} data={data} handleRef={setHandle}>
        <EditableGraphRenderer mode="edit" />
      </GraphProvider>
      {handle && (
        <EditorPanel.Root handle={handle}>
          <LegendSection />
        </EditorPanel.Root>
      )}
    </>
  );
}
```

An explicit `handle` takes precedence over the surrounding provider. Change it to edit another chart. A section throws if its panel has neither a handle nor a provider.

## Your own section

Build a custom section with `Section` and three hooks:

* `usePanelGraph()` returns the panel's chart handle.
* `useHandleScene(graph)` subscribes to that chart's scene.
* `useControls()` returns the panel's controls, including your replacements.

For a slider, dispatch with `{ transient: true }` and call `graph.commands.commit` on `onCommit` so each drag creates one undo step:

```tsx theme={null}
import { useHandleScene } from '@graphysdk/react';
import {
  EditorPanel,
  Row,
  Section,
  SetBarWidthCommand,
  useControls,
  usePanelGraph,
} from '@graphysdk/react/editable';

function BarWidthSection() {
  const graph = usePanelGraph();
  const scene = useHandleScene(graph);
  const { Slider } = useControls();
  const bar = scene?.spec.layers[0];

  if (!bar || bar.geom !== 'bar') return null;

  const width = typeof bar.params.width === 'number' ? bar.params.width : 0.7;

  return (
    <Section title="Bar width" layout="collapsible">
      <EditorPanel.Controls.List>
        <Row label="Width">
          <Slider
            value={width}
            min={0.05}
            max={1}
            step={0.05}
            onChange={(width) =>
              graph.commands.dispatch(
                new SetBarWidthCommand({ layerId: bar.id, width }),
                { transient: true }
              )
            }
            onCommit={graph.commands.commit}
          />
        </Row>
      </EditorPanel.Controls.List>
    </Section>
  );
}
```

Use these building blocks to arrange controls:

* `Section` accepts `title`, `layout`, `preview`, `onOpenChange` and an optional header `accessory`. Clicking the accessory does not toggle the section.
* `Row` labels a control, with an optional `icon` and a `'grid'` (side by side) or `'stack'` layout.
* `EditorPanel.Controls.List` stacks rows; `EditorPanel.Controls.Grid` places controls in two columns.
* `Separator` divides groups of rows.

`ToggledSection` adds a header switch, as used by `GoalSection`. It accepts `title`, `checked`, `onToggle`, `disabled` and `preview`. Switching on opens it; switching off closes it; opening a feature that is off turns it on. To control expansion programmatically, `usePanelExpansion()` provides `expandSection(title)` and `collapseAllSections()`.

## Controls

Sections use a shared registry of controls: `ToggleGroup`, `Switch`, `Slider`, `RadioGrid`, `Button`, `TextField`, `NumberField`, `Select`, `ColorSwatches`, `CustomColor` and `FileInput`. Replace any control with a component accepting its exported props type, such as `SliderControlProps`. The built-in controls are also exported.

Use `controls` to replace controls in one panel:

```tsx theme={null}
<EditorPanel.Root controls={{ Slider: MySlider, Switch: MySwitch }}>
  <BarSection />
</EditorPanel.Root>
```

Use `ControlRegistryProvider` to replace controls across panels and [edit menus](https://docs.graphy.dev/sdk-next/editing/custom-menus.md). A panel's `controls` prop takes precedence; omitted controls inherit from the surrounding provider or the defaults.

```tsx theme={null}
import { ControlRegistryProvider } from '@graphysdk/react/editable';

<ControlRegistryProvider controls={{ Select: MySelect }}>
  <GraphProvider spec={spec} data={data}>
    <EditableGraphRenderer mode="edit" />
    <EditorPanel.Root>
      <LegendSection />
    </EditorPanel.Root>
  </GraphProvider>
</ControlRegistryProvider>;
```

Define replacement components outside render to keep their identity stable. The `controls` object can be inline.

## Look and language

The panel inherits the surrounding `GraphProvider`'s color scheme. With only a `handle`, it defaults to light. Override this with `ThemeProvider`, or pass `darkTheme` or `lightTheme` as `className`; all three are exported from `@graphysdk/react`.

Six CSS custom properties control colors and spacing: `--graphy-editor-accent`, `--graphy-editor-surface`, `--graphy-editor-text`, `--graphy-editor-border`, `--graphy-editor-padding-x` and `--graphy-editor-padding-y`. Set them on `:root` for all panels and menus, or scope them to a panel:

```css theme={null}
[data-graphy-editor-panel] {
  --graphy-editor-accent: #2f6fed;
  --graphy-editor-surface: #fafafa;
}
```

Labels use the edited chart's `formattingLocale`, falling back to its parsing locale. Wrap the panel in `EditorIntlProvider` to override the locale or [translate phrases](https://docs.graphy.dev/sdk-next/editing/custom-menus.md#translate-the-menu):

```tsx theme={null}
<EditorIntlProvider locale="pt-PT">
  <EditorPanel.Root>
    <TitleSection />
  </EditorPanel.Root>
</EditorIntlProvider>
```

## Panel or menu

Use the [edit menu](https://docs.graphy.dev/sdk-next/editing/menu.md) for quick changes to selected elements, and the panel for the full settings range. For example, the menu offers three bar widths; the panel offers a slider.

The panel also covers combo chart types, data mapping, number formats, headlines, goals, trends and averages, callouts, text size, frame appearance and source text. Titles, subtitles and captions can be edited inline or in panel fields; the menu toggles their visibility. Both interfaces share one undo history.

## Related

* [Commands & history](https://docs.graphy.dev/sdk-next/editing/commands-and-history.md) — the commands sections dispatch, transient runs and `commit()`
* [Custom menus](https://docs.graphy.dev/sdk-next/editing/custom-menus.md) — the edit menu's rows, controls and translation
* [Provider & renderer](https://docs.graphy.dev/sdk-next/rendering/provider-and-renderer.md) — `handleRef`, `colorScheme`, `formattingLocale`


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.