# Shapes

Shapes are workbook-local worksheet resources. Use `univer run` to create or maintain them through the Pro Shapes facade, then use facade readback to verify command-line results.

For visual verification, open the workbook with `univer view`. `univer run` does not export shape images, perform browser screenshots, or provide an interactive shape editor.

## Core Workflow

Look up the workbook and worksheet, configure a shape builder with `newShape()`, call `build()`, then pass the result to `insertShape(shapeInfo)`.

```bash
univer run ./diagram.univer --code 'async () => {
  const workbook = univerAPI.getActiveWorkbook();
  const sheet = workbook.getSheetByName("Sheet1");
  if (!sheet) return { success: false, error: "Sheet1 not found" };

  const shapeInfo = sheet
    .newShape()
    .setShapeType(univerAPI.Enum.ShapeTypeEnum.Rect)
    .setPosition(1, 1, 0, 0)
    .setWidth(240)
    .setHeight(120)
    .setShapeSolidFill("#e6f4ff")
    .setStrokeColor("#1677ff")
    .setStrokeWidth(2)
    .build();

  const inserted = await sheet.insertShape(shapeInfo);
  const shapes = sheet.getShapes();

  return {
    success: inserted,
    shapeCount: shapes.length,
    firstShapeId: shapes[0]?.getShapeId(),
    firstShapeType: shapes[0]?.getShapeType()
  };
}'
```

`ShapeTypeEnum.Rect` is a common rectangle type. Other shape values are available from `univerAPI.Enum.ShapeTypeEnum`.

## Shape Type Enum Values

Use `univerAPI.Enum.ShapeTypeEnum.<Name>` with `setShapeType()` when building shape metadata.

```javascript
const shapeInfo = sheet
  .newShape()
  .setShapeType(univerAPI.Enum.ShapeTypeEnum.RoundRect)
  .setPosition(1, 1, 0, 0)
  .build();
```

Available shape type enum values:

- Basic shapes: `None`, `Rect`, `RoundRect`, `Ellipse`, `Diamond`, `Triangle`, `RightTriangle`, `Parallelogram`, `Trapezoid`, `Hexagon`, `Heptagon`, `Octagon`, `Pentagon`, `Chevron`, `HomePlate`, `Plus`, `Can`, `Cube`, `Bevel`, `Donut`, `NoSmoking`, `BlockArc`, `Teardrop`, `PieWedge`, `Pie`, `Funnel`, `Cloud`, `Heart`, `Sun`, `Moon`, `SmileyFace`, `LightningBolt`.
- Rectangle variants: `Round1Rect`, `Round2SameRect`, `Round2DiagRect`, `Snip1Rect`, `SnipRoundRect`, `Snip2SameRect`, `Snip2DiagRect`, `NonIsoscelesTrapezoid`.
- Stars and seals: `Star4`, `Star5`, `Star6`, `Star7`, `Star8`, `Star10`, `Star12`, `Star16`, `Star24`, `Star32`, `IrregularSeal1`, `IrregularSeal2`.
- Frames, braces, tabs, and symbols: `Plaque`, `Frame`, `HalfFrame`, `Corner`, `DiagStripe`, `Chord`, `Arc`, `Gear6`, `Gear9`, `Decagon`, `Dodecagon`, `CornerTabs`, `PlaqueTabs`, `SquareTabs`, `LeftBrace`, `RightBrace`, `LeftBracket`, `RightBracket`, `BracePair`, `BracketPair`, `ChartPlus`, `ChartStar`, `ChartX`, `MathPlus`, `MathMinus`, `MathMultiply`, `MathDivide`, `MathEqual`, `MathNotEqual`.
- Block arrows: `LeftCircularArrow`, `LeftRightCircularArrow`, `SwooshArrow`, `LeftRightRibbon`, `RightArrow`, `LeftArrow`, `UpArrow`, `DownArrow`, `LeftRightArrow`, `UpDownArrow`, `QuadArrow`, `LeftRightUpArrow`, `BentArrow`, `UturnArrow`, `LeftUpArrow`, `BentUpArrow`, `CurvedRightArrow`, `CurvedLeftArrow`, `CurvedUpArrow`, `CurvedDownArrow`, `StripedRightArrow`, `NotchedRightArrow`, `CircularArrow`, `UpDownArrowCallout`.
- Arrow callouts: `RightArrowCallout`, `DownArrowCallout`, `LeftArrowCallout`, `UpArrowCallout`, `LeftRightArrowCallout`, `QuadArrowCallout`.
- Flowchart shapes: `FlowchartProcess`, `FlowchartAlternateProcess`, `FlowchartDecision`, `FlowChartInputOutput`, `FlowchartPredefinedProcess`, `FlowchartInternalStorage`, `FlowchartDocument`, `FlowchartMultiDocument`, `FlowchartTerminator`, `FlowchartPreparation`, `FlowchartManualInput`, `FlowchartManualOperation`, `FlowchartConnector`, `FlowchartOffPageConnector`, `FlowchartPunchedCard`, `FlowchartPunchedTape`, `FlowchartSummingJunction`, `FlowchartOr`, `FlowchartCollate`, `FlowchartSort`, `FlowchartExtract`, `FlowchartMerge`, `FlowchartOnlineStorage`, `FlowchartDelay`, `FlowchartMagneticTape`, `FlowchartMagneticDisk`, `FlowchartMagneticDrum`, `FlowchartDisplay`, `FlowChartOfflineStorage`.
- Callouts, ribbons, and scrolls: `WedgeRectCallout`, `WedgeRoundRectCallout`, `WedgeEllipseCallout`, `CloudCallout`, `BorderCallout1`, `BorderCallout2`, `BorderCallout3`, `AccentCallout1`, `AccentCallout2`, `AccentCallout3`, `Callout1`, `Callout2`, `Callout3`, `AccentBorderCallout1`, `AccentBorderCallout2`, `AccentBorderCallout3`, `Ribbon`, `Ribbon2`, `EllipseRibbon`, `EllipseRibbon2`, `VerticalScroll`, `HorizontalScroll`, `Wave`, `DoubleWave`, `FoldedCorner`.
- Action buttons: `ActionButtonBackPrevious`, `ActionButtonForwardNext`, `ActionButtonBeginning`, `ActionButtonEnd`, `ActionButtonHome`, `ActionButtonInformation`, `ActionButtonReturn`, `ActionButtonMovie`, `ActionButtonDocument`, `ActionButtonSound`, `ActionButtonHelp`, `ActionButtonBlank`.
- Lines and connectors: `Line`, `LineInv`, `StraightConnector1`, `BentConnector2`, `BentConnector3`, `BentConnector4`, `BentConnector5`, `CurvedConnector2`, `CurvedConnector3`, `CurvedConnector4`, `CurvedConnector5`.

Connector-only builders from `newConnector()` should use connector or line shape types such as `StraightConnector1`, `BentConnector3`, or `CurvedConnector3`.

## Shape Facade Enum Examples

The Shapes facade exposes fill, stroke, and connector enums through `univerAPI.Enum`.

```javascript
const shapeInfo = sheet
  .newShape()
  .setShapeType(univerAPI.Enum.ShapeTypeEnum.Rect)
  .setShapeGradientFill(
    univerAPI.Enum.ShapeGradientTypeEnum.Linear,
    [
      { position: 0, color: "#e6f4ff" },
      { position: 1, color: "#1677ff" }
    ],
    90
  )
  .setStrokeLineType(univerAPI.Enum.ShapeLineTypeEnum.SolidLine)
  .setStrokeLineDashType(univerAPI.Enum.ShapeLineDashEnum.Dash)
  .setStrokeLineCapType(univerAPI.Enum.ShapeLineCapEnum.Round)
  .setStrokeLineJoinType(univerAPI.Enum.ShapeLineJoinEnum.Round)
  .build();
```

Common shape facade enums:

| Facade enum                            | Example values                                                                                   | Typical use                                                                                                                         |
| -------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `univerAPI.Enum.ShapeFillEnum`         | `NoFill`, `SolidFill`, `GradientFill`, `PatternFill`, `PictureFill`                              | Readback in `getShapeData().fill`; builder helpers usually use `setNoneFill()`, `setShapeSolidFill()`, or `setShapeGradientFill()`. |
| `univerAPI.Enum.ShapeGradientTypeEnum` | `Linear`, `Radial`, `Angular`, `Diamond`                                                         | `setShapeGradientFill(type, colorStops, angle)`                                                                                     |
| `univerAPI.Enum.ShapeLineTypeEnum`     | `NoLine`, `SolidLine`, `GradientLine`                                                            | `setStrokeLineType(value)`                                                                                                          |
| `univerAPI.Enum.ShapeLineDashEnum`     | `Solid`, `RoundDot`, `SquareDot`, `Dash`, `DashDot`, `LongDash`, `LongDashDot`, `LongDashDotDot` | `setStrokeLineDashType(value)`                                                                                                      |
| `univerAPI.Enum.ShapeLineCapEnum`      | `Flat`, `Round`, `Square`                                                                        | `setStrokeLineCapType(value)`                                                                                                       |
| `univerAPI.Enum.ShapeLineJoinEnum`     | `Miter`, `Round`, `Bevel`                                                                        | `setStrokeLineJoinType(value)`                                                                                                      |
| `univerAPI.Enum.ShapeArrowTypeEnum`    | `None`, `Arrow`, `OpenArrow`, `DiamondArrow`, `StealthArrow`, `OvalArrow`                        | `setStartArrowType(value)`, `setEndArrowType(value)`                                                                                |
| `univerAPI.Enum.ShapeArrowSizeEnum`    | `Small`, `Medium`, `Large`                                                                       | `setStartArrowSize(value)`, `setEndArrowSize(value)`                                                                                |

## Shape Builder

`sheet.newShape()` returns a shape builder and `sheet.newConnector()` returns a connector builder. The builder only prepares shape metadata. `build()` does not draw anything by itself; insert a new shape with `insertShape(shapeInfo)` or update an existing shape with `updateShape(shapeInfo)`.

Core builder methods:

- `setShapeType(univerAPI.Enum.ShapeTypeEnum.Rect)` chooses the shape type.
- `setPosition(row, column, rowOffset, columnOffset)` anchors the shape to the grid.
- `setAbsolutePosition(x, y)` places the shape by absolute canvas coordinates.
- `setWidth(width)` and `setHeight(height)` set the rendered shape size.
- `build()` returns shape metadata for `insertShape(shapeInfo)` or `updateShape(shapeInfo)`.

Fill methods:

- `setShapeSolidFill(color, opacity)` sets a solid fill. Use hex or RGB colors when passing opacity.
- `setShapeGradientFill(univerAPI.Enum.ShapeGradientTypeEnum.Linear, colorStops, angle)` sets a gradient fill. Each color stop uses `{ position, color }`.
- `setNoneFill()` clears the fill.

Stroke methods:

- `setStrokeColor(color)` sets outline color.
- `setStrokeWidth(width)` sets outline width in pixels.
- `setStrokeOpacity(opacity)` sets outline opacity from `0` to `1`.
- `setStrokeLineType(univerAPI.Enum.ShapeLineTypeEnum.SolidLine)` sets the outline fill type.
- `setStrokeLineDashType(univerAPI.Enum.ShapeLineDashEnum.Dash)` sets dash style.
- `setStrokeLineCapType(univerAPI.Enum.ShapeLineCapEnum.Round)` sets line cap style.
- `setStrokeLineJoinType(univerAPI.Enum.ShapeLineJoinEnum.Round)` sets line join style.

`FConnectorShape` inherits the base shape builder methods above and adds connector-specific methods:

- `newConnector(existingShape)` creates or updates connector shapes.
- `setShapeType(univerAPI.Enum.ShapeTypeEnum.StraightConnector1)` chooses the connector geometry.
- `setStartArrowType(univerAPI.Enum.ShapeArrowTypeEnum.Arrow)` and `setEndArrowType(univerAPI.Enum.ShapeArrowTypeEnum.Arrow)` set arrow heads.
- `setStartArrowSize(univerAPI.Enum.ShapeArrowSizeEnum.Medium)` and `setEndArrowSize(univerAPI.Enum.ShapeArrowSizeEnum.Large)` set arrow head size.
- `build()` returns connector shape metadata for `insertShape(shapeInfo)` or `updateShape(shapeInfo)`.
- `getStartConnectInfo()` and `getEndConnectInfo()` read connector relation data.

Shape facade readback methods:

- `getShapeId()` returns the stable shape id.
- `getShapeType()` returns the current shape type enum value.
- `getShapeData()` returns public fill and stroke data.
- `getPosition()` returns absolute pixel position.
- `getSize()` returns width and height.
- `isLineShape()` returns whether the shape is a connector or line shape.
- `getConnectionSites()` returns attachable sites for basic shapes.
- `getAdjustPoints()` returns adjustable geometry handles when the shape exposes them.
- `getConnectorLinePoints()` returns line points for connector shapes.
- `getStartConnectInfo()` and `getEndConnectInfo()` read connector relation data.

## Connector Shapes

Use `newConnector()` for connector lines. Connector builders support the same position, size, stroke, and `build()` flow, plus connector-specific arrow settings.

```javascript
const connectorInfo = sheet
  .newConnector()
  .setShapeType(univerAPI.Enum.ShapeTypeEnum.StraightConnector1)
  .setPosition(2, 3, 0, 0)
  .setWidth(220)
  .setHeight(40)
  .setStartArrowType(univerAPI.Enum.ShapeArrowTypeEnum.Arrow)
  .setEndArrowType(univerAPI.Enum.ShapeArrowTypeEnum.Arrow)
  .setStrokeColor("#595959")
  .setStrokeWidth(2)
  .build();

await sheet.insertShape(connectorInfo);
```

`ShapeArrowTypeEnum.Arrow` is a common arrow style. Other arrow values are available from `univerAPI.Enum.ShapeArrowTypeEnum`.

## Connect Shapes

After inserting basic shapes and a connector, call `getShapes()` and use `isLineShape()` to find connector and non-connector shapes. Pass the facade objects to `connectShapes()`.

```bash
univer run ./diagram.univer --code 'async () => {
  const workbook = univerAPI.getActiveWorkbook();
  const sheet = workbook.getSheetByName("Sheet1");
  if (!sheet) return { success: false, error: "Sheet1 not found" };

  const leftInfo = sheet
    .newShape()
    .setShapeType(univerAPI.Enum.ShapeTypeEnum.RoundRect)
    .setPosition(1, 1, 0, 0)
    .setWidth(180)
    .setHeight(80)
    .setShapeSolidFill("#f6ffed")
    .setStrokeColor("#52c41a")
    .build();
  const rightInfo = sheet
    .newShape()
    .setShapeType(univerAPI.Enum.ShapeTypeEnum.Diamond)
    .setPosition(1, 5, 0, 0)
    .setWidth(180)
    .setHeight(120)
    .setShapeSolidFill("#fffbe6")
    .setStrokeColor("#faad14")
    .build();
  const connectorInfo = sheet
    .newConnector()
    .setShapeType(univerAPI.Enum.ShapeTypeEnum.StraightConnector1)
    .setPosition(2, 3, 0, 0)
    .setWidth(220)
    .setHeight(40)
    .setStartArrowType(univerAPI.Enum.ShapeArrowTypeEnum.Arrow)
    .setEndArrowType(univerAPI.Enum.ShapeArrowTypeEnum.Arrow)
    .setStrokeColor("#595959")
    .setStrokeWidth(2)
    .build();

  await sheet.insertShape(leftInfo);
  await sheet.insertShape(rightInfo);
  await sheet.insertShape(connectorInfo);

  const shapes = sheet.getShapes();
  const basicShapes = shapes.filter((shape) => !shape.isLineShape());
  const connector = shapes.find((shape) => shape.isLineShape());
  const connected = connector
    ? await sheet.connectShapes({
        connector,
        startTarget: { shape: basicShapes[0], connectionSiteIndex: 0 },
        endTarget: { shape: basicShapes[1], connectionSiteIndex: 2 }
      })
    : false;

  return {
    success: connected,
    shapeCount: shapes.length,
    lineShapeCount: shapes.filter((shape) => shape.isLineShape()).length
  };
}'
```

`connectShapes()` needs facade shape objects from the same worksheet. At least one of `startTarget` or `endTarget` must be provided.

## Readback And Maintenance

Use public facade APIs for stable command-line verification:

```javascript
const shapes = sheet.getShapes();
const basicShapes = shapes.filter((shape) => !shape.isLineShape());
const connector = shapes.find((shape) => shape.isLineShape());

return {
  shapeCount: shapes.length,
  basicShapeIds: basicShapes.map((shape) => shape.getShapeId()),
  connectorId: connector?.getShapeId(),
  connectorStart: connector?.getStartConnectInfo(),
  connectorEnd: connector?.getEndConnectInfo()
};
```

Useful shape readback methods include:

- `getShapeId()` returns the stable shape id.
- `getShapeType()` returns the enum value for the current shape type.
- `getShapeData()` returns public fill and stroke data.
- `getPosition()` returns absolute pixel position.
- `getSize()` returns width and height.
- `isLineShape()` returns whether the shape is a connector or line shape.
- `getConnectionSites()` returns attachable sites for basic shapes.
- `getStartConnectInfo()` and `getEndConnectInfo()` read connector relation data.

## Update Shape

To update a shape, initialize a builder from an existing facade shape with `newShape(existingShape)`, then call `updateShape(updatedShapeInfo)`.

```bash
univer run ./diagram.univer --code 'async () => {
  const workbook = univerAPI.getActiveWorkbook();
  const sheet = workbook.getSheetByName("Sheet1");
  if (!sheet) return { success: false, error: "Sheet1 not found" };

  const firstShape = sheet.getShapes().find((shape) => !shape.isLineShape());
  if (!firstShape) return { success: false, error: "No basic shape found" };

  const updatedShape = sheet
    .newShape(firstShape)
    .setStrokeColor("#ff4d4f")
    .setStrokeWidth(3)
    .setShapeSolidFill("#fff1f0")
    .build();

  const updated = await sheet.updateShape(updatedShape);

  return {
    success: updated,
    shapeId: firstShape.getShapeId(),
    shapeCount: sheet.getShapes().length
  };
}'
```

## Remove Shape

To remove a shape, pass the facade shape object back to the worksheet.

```bash
univer run ./diagram.univer --code 'async () => {
  const workbook = univerAPI.getActiveWorkbook();
  const sheet = workbook.getSheetByName("Sheet1");
  if (!sheet) return { success: false, error: "Sheet1 not found" };

  const firstShape = sheet.getShapes()[0];
  if (!firstShape) {
    return {
      success: true,
      removed: false,
      remaining: 0
    };
  }

  const removed = await sheet.removeShape(firstShape);

  return {
    success: true,
    removed,
    remaining: sheet.getShapes().length
  };
}'
```

## Headless And Viewer Boundary

Headless `univer run` scripts should verify shapes by reading facade state: `getShapes()`, `isLineShape()`, `getShapeId()`, `getShapeType()`, `getPosition()`, `getSize()`, `getStartConnectInfo()`, and `getEndConnectInfo()`.

Browser rendering belongs to `univer view`, where the readonly workbook viewer loads Shapes UI plugins and paints the visible shape surface.
