# Classes

Import these from `@grafloria/angular`.

## Classes

### `AutoToolbarDirective`

AutoToolbarDirective

Automatically shows/hides node toolbars based on node selection. Apply this directive to the diagram canvas container to enable automatic toolbar management.

```ts
@Directive({
  selector: '[grafloriaAutoToolbar]',
  standalone: true,
})
export class AutoToolbarDirective implements OnInit, OnDestroy
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `engine` | `DiagramEngine` |  |  |
| `viewport` | `{ x: number; y: number; width: number; height: number }` |  |  |
| `zoom` | `number` | `1.0` |  |
| `toolbarPosition` | `ToolbarPosition` | `'top'` |  |
| `toolbarAlignment` | `ToolbarAlignment` | `'center'` |  |
| `toolbarActions` | `ToolbarAction[]` | `[]` |  |
| `toolbarTemplate?` | `TemplateRef<any>` |  |  |
| `toolbarOffset?` | `number` |  |  |

**Methods**

- `constructor( private toolbarService: NodeToolbarService, private viewContainerRef: ViewContainerRef, private elementRef: ElementRef<HTMLElement>, private environmentInjector: EnvironmentInjector )`
- `ngOnInit()`
- `ngOnDestroy()`
- `updateViewport(viewport: { x: number; y: number; width: number; height: number })` — Update viewport (to be called when viewport changes)
- `updateZoom(zoom: number)` — Update zoom (to be called when zoom changes)

**Example**

```html
<div grafloriaAutoToolbar
     [engine]="diagramEngine"
     [viewport]="viewport"
     [zoom]="zoom"
     [toolbarPosition]="'top'"
     [toolbarActions]="actions">
  <grafloria-diagram-canvas [engine]="engine"></grafloria-diagram-canvas>
</div>
```

### `GrafloriaCommentPanelComponent`

`<grafloria-comment-panel>` — the conversation UI for a comment store:
thread list, unread markers, selection. Feed it the canvas's store:

```html
<grafloria-diagram-canvas #canvas [comments]="true" … />
<grafloria-comment-panel [store]="canvas.getCommentStore()"
                         (threadSelect)="focus($event)" />
```

```ts
@Component({
  selector: 'grafloria-comment-panel',
  template: '',
  styles: [':host { display: block; }'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GrafloriaCommentPanelComponent implements AfterViewInit, OnDestroy
```

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

**Inputs**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `store` | `CommentStore` |  |  |
| `options?` | `CommentPanelOptions` |  |  |

**Outputs**

- `threadSelect` — The selected thread id, or null when dismissed.

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `store` |  |  |  |
| `options` |  |  |  |
| `threadSelect` |  |  | The selected thread id, or null when dismissed. |

**Methods**

- `ngAfterViewInit(): void`
- `select(threadId: string | null): void` — Programmatic selection (e.g. from a pin click).
- `ngOnDestroy(): void`

### `GrafloriaDiagramComponent`

`<grafloria-diagram>` — the generic kit host. Any kit spec renders:

```ts
spec = erDiagram({ entities, relationships });        // or umlDiagram({...}),
```
```html
<grafloria-diagram [spec]="spec" (ready)="instance = $event" />
```

One component for every present and future kit — because every kit speaks
the same contract: a spec with nodes/edges/renderCustomNode/finalize that
`render()` mounts in one call.

```ts
@Component({
  selector: 'grafloria-diagram',
  template: '',
  styles: [':host { display: block; position: relative; }'],
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class GrafloriaDiagramComponent implements AfterViewInit, OnChanges, OnDestroy
```

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

**Inputs**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `spec` | `RenderSpec` |  | Any kit spec — `erDiagram(...)`, `umlDiagram(...)`, `dashboard(...)`, or DSL text. |
| `options?` | `RenderOptions` |  | Options passed through to the underlying `createDiagram`. |

**Outputs**

- `ready` — The live DiagramInstance after mount.

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `spec` |  |  | Any kit spec — `erDiagram(...)`, `umlDiagram(...)`, `dashboard(...)`, or DSL text. |
| `options` |  |  | Options passed through to the underlying `createDiagram`. |
| `ready` |  |  | The live DiagramInstance after mount. |

**Methods**

- `ngAfterViewInit(): void`
- `ngOnChanges(changes: SimpleChanges): void` — A CHANGED spec or options replaces the diagram; an equal new one does not.
- `getInstance(): DiagramInstance | undefined`
- `ngOnDestroy(): void`

### `GrafloriaWidgetDefDirective`

Declarative dashboard widgets — the node-template idiom applied to boards:

```html
<grafloria-dashboard [views]="views">
  <ng-template grafloriaWidget="orders" let-widget let-data="data">
    <app-orders-card [orders]="data['orders']" />
  </ng-template>
</grafloria-dashboard>
```

A widget whose `kind` matches a template renders through it — full Angular
change detection, components, pipes, and event handlers. Kinds without a
template fall back to the kit's built-in painters
(kpi / line / bar / donut / funnel / table). `grafloriaWidget` with no value
is the wildcard for any kind without an exact template.

```ts
@Directive({ selector: 'ng-template[grafloriaWidget]' })
export class GrafloriaWidgetDefDirective
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `kind` |  |  | Widget `kind` this template renders; empty string = wildcard fallback. |
| `templateRef` |  |  |  |

**Methods**

- `static ngTemplateContextGuard( _dir: GrafloriaWidgetDefDirective, ctx: unknown ): ctx is GrafloriaWidgetTemplateContext` (static)

### `NodeToolbarService`

NodeToolbarService

Manages the lifecycle of node toolbars in the diagram. Provides methods to show, hide, and update toolbars programmatically.

```ts
@Injectable({ providedIn: 'root' })
export class NodeToolbarService
```

**Methods**

- `setViewContainer(vcr: ViewContainerRef)` — Set the view container for creating toolbars
- `setEnvironmentInjector(injector: EnvironmentInjector)` — Set the environment injector for creating components
- `setCanvasElement(element: HTMLElement)` — Set global canvas element for all toolbars
- `setViewport(viewport: { x: number; y: number; width: number; height: number })` — Set global viewport for all toolbars
- `setZoom(zoom: number)` — Set global zoom for all toolbars
- `show( node: NodeModel, engine: DiagramEngine, config: ToolbarConfig = {} ): ComponentRef<NodeToolbarComponent>` — Show toolbar for a node
- `hide(nodeId: string)` — Hide toolbar for a node
- `hideAll()` — Hide all toolbars
- `get(nodeId: string): ComponentRef<NodeToolbarComponent> | undefined` — Get toolbar for a node
- `isShown(nodeId: string): boolean` — Check if toolbar is shown for a node
- `updatePosition(nodeId: string)` — Update toolbar position for a node
- `updateAllPositions()` — Update positions for all toolbars
- `updateConfig(nodeId: string, config: Partial<ToolbarConfig>)` — Update toolbar configuration
- `getCount(): number` — Get the number of active toolbars
- `getAll(): ComponentRef<NodeToolbarComponent>[]` — Get all toolbar component references

**Example**

```typescript
constructor(private toolbarService: NodeToolbarService) {}

ngOnInit() {
  this.toolbarService.setViewContainer(this.viewContainerRef);
}

showToolbar(node: NodeModel) {
  this.toolbarService.show(node, this.engine, {
    position: 'top',
    actions: this.actions
  });
}
```
