# Core

Import these from `@grafloria/angular`.

## Functions

### `provideGrafloria`

The modern Angular configuration idiom:

```ts
bootstrapApplication(AppComponent, {
  providers: [provideGrafloria({ theme: DARK_THEME })],
});
```

```ts
function provideGrafloria(config: GrafloriaConfig): EnvironmentProviders
```

## Classes

### `AngularComponentAdapter`

Angular implementation of ComponentAdapter interface

Thin wrapper around ComponentRendererService that implements
framework-agnostic ComponentAdapter interface.

```ts
@Injectable({ providedIn: 'root' })
export class AngularComponentAdapter implements ComponentAdapter
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `framework` |  | `'angular'` | Framework identifier |

**Methods**

- `constructor(private componentRenderer: ComponentRendererService)`
- `registerComponent(nodeType: string, component: Type<any>): void` — Register Angular component for node type
- `hasComponent(nodeType: string): boolean` — Check if component is registered for node type
- `getComponent(nodeType: string): Type<any> | undefined` — Get registered component class
- `createComponentInstance(node: NodeModel, container: ViewContainerRef): ComponentRef<any>` — Create Angular component instance for node

Converts NodeModel to component inputs:
- Spreads node.data as inputs
- Passes positionX, positionY
- Passes nodeData (full node data object)
- `updateComponentInstance(instance: ComponentRef<any>, node: NodeModel): void` — Update component instance with new node data
- `destroyComponentInstance(instance: ComponentRef<any>): void` — Destroy component instance
- `getRegisteredTypes(): string[]` — Get list of all registered node types
- `destroyAll(): void` — Destroy all component instances
- `getActiveCount(): number` — Get count of active component instances

### `GrafloriaHandleDirective`

Directive to mark HTML elements as connection handles (React Flow style)

Usage:
```html
<div grafloriaHandle="source" handleId="output-1" handlePosition="right">
  Connect Here
</div>
```

The directive automatically:
- Registers the handle with HandleRegistryService on init
- Unregisters on destroy
- Allows DOM-based position queries for connections

Hybrid HTML+SVG Rendering

```ts
@Directive({
  selector: '[grafloriaHandle]',
  standalone: true,
})
export class GrafloriaHandleDirective implements AfterViewInit, OnDestroy
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `grafloriaHandle` | `'source' \| 'target'` |  | Handle type: 'source' (output) or 'target' (input) Required. |
| `handleId?` | `string` |  | Unique handle ID within the node If not provided, will be auto-generated |
| `handlePosition?` | `'top' \| 'right' \| 'bottom' \| 'left'` |  | Handle position relative to node Affects how connections are drawn |

**Methods**

- `ngAfterViewInit(): void`
- `ngOnDestroy(): void`

### `GrafloriaNodeDefDirective`

Declarative, Angular-native custom nodes — the template idiom:

```html
<grafloria-diagram-canvas [(nodes)]="nodes" [(edges)]="edges">
  <ng-template grafloriaNode="card" let-node let-data="data">
    <div class="card">
      <h4>{{ data['title'] }}</h4>
      <p>{{ data['subtitle'] }}</p>
    </div>
  </ng-template>
</grafloria-diagram-canvas>
```

A node whose `type` matches a template is rendered by THAT template in the
HTML layer — full Angular change detection, pipes, directives, and bindings,
no string micro-templates and no component registry required. In controlled
mode the canvas flags matching specs as `custom` automatically, so declaring
the template is the whole integration.

`grafloriaNode` with no value (`<ng-template grafloriaNode>`) is the
wildcard: it renders any HTML-layer node whose type has no exact template.

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

**Properties**

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

**Methods**

- `static ngTemplateContextGuard( _dir: GrafloriaNodeDefDirective, ctx: unknown ): ctx is GrafloriaNodeTemplateContext` (static)

### `ResponsiveCanvasDirective`

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

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `engine` | `IResponsiveCanvasEngine` |  |  |
| `maintainZoom` |  | `true` |  |
| `maintainCenter` |  | `true` |  |
| `enabled` |  | `true` |  |
| `autoEnable` |  | `true` |  |

**Methods**

- `constructor(private el: ElementRef<HTMLElement>)`
- `ngOnInit()`
- `ngOnChanges(changes: any)`
- `enable()` — Enable responsive behavior
- `disable()` — Disable responsive behavior
- `toggle()` — Toggle responsive behavior on/off
- `isEnabled(): boolean` — Check if responsive behavior is enabled
- `triggerResize()` — Manually trigger a resize operation
- `ngOnDestroy()`

## Constants

### `GRAFLORIA_CONFIG`

```ts
const GRAFLORIA_CONFIG: any
```

## Interfaces

### `GrafloriaConfig`

Application-wide Grafloria defaults, set once at bootstrap. Explicit inputs
on a specific `<grafloria-diagram-canvas>` always win over these.

```ts
interface GrafloriaConfig
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `theme?` | `Theme` |  | Default theme for every canvas that does not bind `[theme]` itself. |

### `GrafloriaNodeTemplateContext`

Template context for `<ng-template grafloriaNode>` custom-node templates.

`$implicit` is the live model, so `let-node` gives templates the full
NodeModel surface; `data` is the free-form user payload for the common case.

```ts
interface GrafloriaNodeTemplateContext
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `$implicit` | `NodeModel \| GroupModel` |  |  |
| `engine` | `DiagramEngine \| undefined` |  |  |
| `data` | `Record<string, unknown>` |  |  |

### `IResponsiveCanvasEngine`

```ts
interface IResponsiveCanvasEngine
```

**Members**

- `getCanvas?(): HTMLElement | null`
- `getZoom(): number`
- `setZoom?(zoom: number): void`
- `getPan(): { x: number; y: number }`
- `setPan(x: number, y: number): void`
- `repaint?(): void`
