# Core

Import these from `@grafloria/element`.

## Functions

### `defineGrafloriaFlow`

Register the element. Idempotent, and safe to call on the server (where
`customElements` does not exist) — which is what lets a bundle be imported
from an SSR entry point without a `typeof window` dance at every call site.

```ts
function defineGrafloriaFlow(tagName = 'grafloria-flow'): void
```

### `fromDocument`

Turn a saved document back into something `render()` can mount.

```ts
const json = JSON.stringify(new DiagramSerializer().serialize(api.getModel()));
// …later, in a fresh page:
render(fromDocument(json), host);
```

Accepts the flat serializer form, the portable envelope, or the JSON string
of either.

```ts
function fromDocument(
  document: SavedDiagram,
  options: FromDocumentOptions = {}
): LoadedDiagramSpec
```

### `getNodeType`

```ts
function getNodeType(type: string): NodeTypeRenderer | undefined
```

### `hasNodeType`

```ts
function hasNodeType(type: string): boolean
```

### `registeredNodeTypes`

Every registered type name.

```ts
function registeredNodeTypes(): string[]
```

### `registerNodeType`

Register (or replace) a node type globally.

```ts
function registerNodeType(type: string, renderer: NodeTypeRenderer): void
```

### `render`

Mount `spec` into `target` and return the live instance.

`target` may be an element or a CSS selector. Custom nodes (`custom: true`)
are rendered by the types registered with {@link registerNodeType}.

SCOPE, stated plainly: `spec` is data (an object or its JSON), not a Mermaid-
style text DSL. The engine does have a DSL, but wiring it in is a separate
card — `render()` is the embedding surface, not a parser.

```ts
function render(
  spec: RenderSpec,
  target: HTMLElement | string,
  options: RenderOptions = {}
): DiagramInstance
```

### `renderFromTemplate`

Render a node from a slotted `<template data-node-type="...">`.

Clones the template's content into `element` and substitutes `node.data` into
every `[data-field="key"]` descendant's text. Values are written with
`textContent`, never `innerHTML`: a diagram's `data` is frequently
user-supplied, and a template engine that injected raw HTML here would be an
XSS vector in every host that embeds us.

```ts
function renderFromTemplate(
  template: HTMLTemplateElement,
  node: NodeModel,
  element: HTMLElement
): void
```

### `renderStatic`

Server-side render. Re-exported so the tiny API is self-contained.

```ts
function renderStatic(options: StaticRenderOptions = {}): StaticRenderResult
```

### `unregisterNodeType`

Drop a registration (mostly for tests).

```ts
function unregisterNodeType(type: string): void
```

## Classes

### `GrafloriaFlowElement`

Also has every member of `HTMLElement`, `Element`, `Node`, `ARIAMixin`, `GlobalEventHandlers`, listed on their own entries.

```ts
class GrafloriaFlowElement extends HTMLElementBase
```

Use it as `<grafloria-flow>` in a template.

**Props**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `nodes?` |  |  |  |
| `edges?` |  |  |  |
| `theme?` |  |  |  |
| `fit-view` |  |  |  |
| `readonly?` |  |  |  |
| `zoom?` |  |  |  |
| `min-zoom` |  |  |  |
| `max-zoom` |  |  |  |
| `pan?` |  |  |  |
| `wheel-zoom` |  |  |  |
| `highlight-connected` |  |  |  |

**Events**

- `grafloria-ready`
- `grafloria-nodes-change`
- `grafloria-edges-change`
- `grafloria-selection-change`
- `grafloria-connect`
- `grafloria-node-click`
- `grafloria-edge-click`
- `grafloria-viewport-change`

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `nextElementSibling` | `Element \| null` |  | Returns the first following sibling that is an element, and null otherwise. |
| `previousElementSibling` | `Element \| null` |  | Returns the first preceding sibling that is an element, and null otherwise. |
| `childElementCount` | `number` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/childElementCount) |
| `children` | `HTMLCollection` |  | Returns the child elements. |
| `firstElementChild` | `Element \| null` |  | Returns the first child that is an element, and null otherwise. |
| `lastElementChild` | `Element \| null` |  | Returns the last child that is an element, and null otherwise. |
| `assignedSlot` | `HTMLSlotElement \| null` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/assignedSlot) |
| `attributeStyleMap` | `StylePropertyMap` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/attributeStyleMap) |
| `contentEditable` | `string` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/contentEditable) |
| `enterKeyHint` | `string` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/enterKeyHint) |
| `inputMode` | `string` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/inputMode) |
| `isContentEditable` | `boolean` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/isContentEditable) |
| `autofocus` | `boolean` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/autofocus) |
| `dataset` | `DOMStringMap` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dataset) |
| `nonce?` | `string` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/nonce) |
| `tabIndex` | `number` |  | [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/tabIndex) |

**Methods**

- `static get observedAttributes(): string[]` (static)
- `get nodes(): NodeSpec[]`
- `set nodes(value: NodeSpec[])`
- `get edges(): EdgeSpec[]`
- `set edges(value: EdgeSpec[])`
- `get diagram(): DiagramInstance | null` — The headless instance — the escape hatch to everything else.
- `connectedCallback(): void`
- `disconnectedCallback(): void`
- `attributeChangedCallback(name: string, previous: string | null, next: string | null): void`
- `fitView(padding?: number): void`
- `dispatchEvent(event: Event): boolean` — The **`dispatchEvent()`** method of the EventTarget sends an Event to the object, (synchronously) invoking the affected event listeners in the appropriate order.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/dispatchEvent)
- `animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation` — [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animate)
- `getAnimations(options?: GetAnimationsOptions): Animation[]` — [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAnimations)
- `after(...nodes: (Node | string)[]): void` — Inserts nodes just after node, while replacing strings in nodes with equivalent Text nodes.

Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/after)
- `before(...nodes: (Node | string)[]): void` — Inserts nodes just before node, while replacing strings in nodes with equivalent Text nodes.

Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/before)
- `remove(): void` — Removes node.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/remove)
- `replaceWith(...nodes: (Node | string)[]): void` — Replaces node with nodes, while replacing strings in nodes with equivalent Text nodes.

Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/replaceWith)
- `append(...nodes: (Node | string)[]): void` — Inserts nodes after the last child of node, while replacing strings in nodes with equivalent Text nodes.

Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/append)
- `prepend(...nodes: (Node | string)[]): void` — Inserts nodes before the first child of node, while replacing strings in nodes with equivalent Text nodes.

Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/prepend)
- `querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null` — Returns the first element that is a descendant of node that matches selectors.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/querySelector)
- `querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>` — Returns all element descendants of node that match selectors.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll)
- `replaceChildren(...nodes: (Node | string)[]): void` — Replace all children of node with nodes, while replacing strings in nodes with equivalent Text nodes.

Throws a "HierarchyRequestError" DOMException if the constraints of the node tree are violated.

[MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/replaceChildren)
- `blur(): void` — [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/blur)
- `focus(options?: FocusOptions): void` — [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/focus)

## Constants

### `Grafloria`

The namespace object, for `import { Grafloria }` and for `<script>` globals.

```ts
const Grafloria: { render: (spec: RenderSpec, target: string | HTMLElement, options?: RenderOptions) => DiagramInstance; renderStatic: (options?: StaticRenderOptions) => StaticRenderResult; registerNodeType: (type: string, renderer: NodeTypeRenderer) => void; registeredNodeTypes: () => string[]; define: (tagName?: string) => void; }
```

### `GRAFLORIA_EVENTS`

Events emitted on the element. All bubble and cross shadow boundaries.

```ts
const GRAFLORIA_EVENTS: { readonly ready: "grafloria-ready"; readonly nodesChange: "grafloria-nodes-change"; readonly edgesChange: "grafloria-edges-change"; readonly selectionChange: "grafloria-selection-change"; readonly connect: "grafloria-connect"; readonly nodeClick: "grafloria-node-click"; readonly edgeClick: "grafloria-edge-click"; readonly viewportChange: "grafloria-viewport-change"; }
```

## Interfaces

### `DiagramSpec`

What `Grafloria.render()` accepts: an object spec, or the JSON string of one.

```ts
interface DiagramSpec
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `nodes?` | `NodeSpec[]` |  |  |
| `edges?` | `EdgeSpec[]` |  |  |
| `groups?` | `GroupSpec[]` |  | Zones around some boxes, each with its own frame and caption. See `GroupSpec`. |
| `layout?` | `'architecture'` |  | `'architecture'`: compose the drawing — zones as regions, boxes sized to their words in rows, straight lines where boxes line up. Positions are not needed. |

### `FromDocumentOptions`

```ts
interface FromDocumentOptions
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `renderWidget?` | `WidgetRenderer` |  | The app's own widget painter — the same function it passed to `dashboard({ renderWidget })`. A board authored with a custom painter must be RELOADED with it, or the reload silently drops the app's chrome. |
| `renderCustomNode?` | `(node: NodeModel, host: HTMLElement) => void` |  | Full override of the custom-node painter. Outranks everything. |
| `interactive?` | `boolean` |  | Re-attach kit interaction wiring (row selection, in-canvas editing, the dashboard grid binder). Default true — a loaded diagram should behave like the one that was saved. Pass false for a read-only viewer. |

### `LoadedDiagramSpec`

What {@link fromDocument} returns: a `render()` spec, plus the way back in.

```ts
interface LoadedDiagramSpec
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `nodes` | `NodeModel[]` |  |  |
| `edges` | `LinkModel[]` |  |  |
| `renderCustomNode` | `(node: NodeModel, host: HTMLElement) => void` |  |  |
| `finalize` | `(api: unknown) => void` |  |  |
| `model` | `DiagramModel` |  | The deserialized model — the escape hatch, available before any render. |
| `boards` | `Map<string, DashboardGridHandle>` |  | Live grid binders for the boards `finalize()` re-attached, keyed by group id. Empty for a document that is not a dashboard. |
| `handle` | `DashboardHandle` |  | The dashboard toolbar handle over the reloaded board(s) — the SAME `DashboardHandle` `dashboard()` returns, built by the one shared builder so it cannot drift from the authoring surface: addWidget/showView/setSizing/ setColumns/toJSON/exportIds and the widget handles, all live on the reload. |
| `renderOptions?` | `{ minZoom?: number; maxZoom?: number }` |  | Instance options the loaded spec asks `render()` to apply (a fluid board pins zoom). |

## Types

### `NodeTypeRenderer`

Fills `element` with the visual for `node`. Called once per mounted node.

```ts
type NodeTypeRenderer = (node: NodeModel, element: HTMLElement) => void;
```

### `RenderOptions`

Also has every member of `CreateDiagramOptions`, `DomEventBinderOptions`, listed on their own entries.

```ts
type RenderOptions = Omit<CreateDiagramOptions, 'nodes' | 'edges'>;
```

### `RenderSpec`

```ts
type RenderSpec = DiagramSpec | DashboardSpec | KitDiagramSpec | string;
```

**Members**

- `toString(): string` — Returns a string representation of a string.
- `valueOf(): string` — Returns the primitive value of the specified object.

### `SavedDiagram`

Anything `DiagramSerializer.deserialize()` accepts, or the JSON string of it.

```ts
type SavedDiagram =
  | SerializedDiagramData
  | DiagramDocumentEnvelope
  | Record<string, unknown>
  | string;
```

**Members**

- `toString(): string` — Returns a string representation of a string.
- `valueOf(): string` — Returns the primitive value of the specified object.
