# @microsoft/powerbi-core-visual-schema

Static **visual capabilities catalog**, **VCO (Visual Container Object) catalog**, and **instance selector catalog** for Power BI report authoring. All metadata is precomputed at build time and shipped as JSON inside the package, so lookups are local, synchronous, and have **zero runtime dependencies**.

## 💡 What can you do?

- **📋 Enumerate visual types** — list every registered Power BI visual identifier (e.g. `barChart`, `lineChart`, `card`, `actionButton`)
- **🔍 Look up visual capabilities** — retrieve a visual's data roles, formatting objects, behavioral flags (selection, highlight, keyboard focus, …) and more
- **🧩 Inspect VCOs** — browse the shared container-level formatting objects (title, subTitle, background, border, dropShadow, padding, …) along with each one's properties and types
- **🎯 Look up instance selectors** — discover which visuals (and non-visual elements like `filterCard`) expose **state-keyed** formatting buckets (`default`/`hover`/`selected`/`disabled`/…) and which formatting objects each state applies to

## 📦 Installation

```bash
npm install @microsoft/powerbi-core-visual-schema
# or
pnpm add @microsoft/powerbi-core-visual-schema
```

The package is **ESM-only** (Node ≥ 20.10) and ships full TypeScript types.

## 🚀 Quick start

```ts
import {
    // Visual catalog
    listVisualTypes,
    getCapabilities,

    // VCO catalog
    listVcoKeys,
    getVcoCapabilities,

    // Instance selector catalog
    listInstanceSelectorKeys,
    getInstanceSelectors,
    getSelectorHints,
} from '@microsoft/powerbi-core-visual-schema';

// 1. All visual types
const types = listVisualTypes();
// → ['actionButton', 'areaChart', 'barChart', 'card', ...]  (~55 entries)

// 2. Full capabilities for one visual
const lineChart = getCapabilities('lineChart');
// → { dataRoles: [...], objects: { dataPoint: {...}, ... }, ... } | undefined

// 3. All visual container objects
const vcoKeys = listVcoKeys();
// → ['title', 'subTitle', 'divider', 'background', 'border', 'dropShadow', ...]

const titleVco = getVcoCapabilities('title');
// → { displayName: 'Title', properties: { show: {...}, text: {...}, fontColor: {...} } }

// 4. Instance selector catalog
const selectorKeys = listInstanceSelectorKeys();
// → ['actionButton', 'advancedSlicer', 'bookmarkNavigator', 'cardVisual',
//    'filterCard', 'pageNavigator', 'pivotTable', 'shape']

const buttonSelectors = getInstanceSelectors('actionButton');
// → { fill: ['default','hover','selected','disabled'], outline: [...], text: [...], ... }

const filterCardSelectors = getInstanceSelectors('filterCard');
// → { filterCard: ['Available', 'Applied'] }

const hints = getSelectorHints('actionButton', ['fill', 'text']);
// → [
//     { objectName: 'fill', selectorIds: ['default','hover','selected','disabled'] },
//     { objectName: 'text', selectorIds: ['default','hover','selected','disabled'] },
//   ]
```

## 🛠️ Public API

All exports come from the package root.

### Visual capabilities

| Export | Returns | Description |
|---|---|---|
| `listVisualTypes()` | `string[]` | Sorted list of all registered visual type identifiers |
| `getCapabilities(visualType)` | `VisualCapabilities \| undefined` | Full capabilities descriptor, or `undefined` if not registered |

Image-typed visual properties expose the serialized ImageDefinition value shape under `type.image.subProperties`:

```ts
const imageProperty = getCapabilities('actionButton')?.objects?.fill.properties.image;
const imageSubProperties = imageProperty?.type?.image?.subProperties;
// → {
//     name: { type: 'expr', required: true },
//     url: { type: 'expr', required: true },
//     scaling: { type: 'expr', required: false },
//   }
```

### VCO catalog (Visual Container Objects)

| Export | Returns | Description |
|---|---|---|
| `listVcoKeys()` | `string[]` | All registered VCO object names |
| `getVcoCapabilities(name)` | `VcoCatalogEntry \| undefined` | Full descriptor for one VCO, or `undefined` if not registered |

### Instance selectors

| Export | Returns | Description |
|---|---|---|
| `listInstanceSelectorKeys()` | `string[]` | Sorted list of every instance-selector key (visuals **and** non-visual elements like `filterCard`) |
| `getInstanceSelectors(key)` | `VisualSelectorMap \| undefined` | Map of `objectName → state IDs[]`, or `undefined` if not registered |
| `getSelectorHints(key, names)` | `SelectorHint[]` | Convenience: hints only for the requested object names |

> **Note:** All `get*` functions return `undefined` for unknown identifiers — no exceptions are thrown for missing data. This keeps consumer code simple (no try/catch noise).

### Types

```ts
import type {
    // Visual capabilities
    VisualType,
    VisualCapabilities,
    CapabilitiesByVisualType,
    DataRoleDescriptor,
    DataRoleKind,
    CartesianKind,
    ObjectDescriptor,
    ObjectPropertyDescriptor,
    PropertyTypeDescriptor,
    EnumMember,
    ImageSubPropertyDescriptor,
    ImageTypeDescriptor,

    // VCOs
    VcoKey,
    VcoCatalog,
    VcoCatalogEntry,
    VcoProperty,
    VcoPropertyType,
    VcoEnumMember,

    // Instance selectors
    InstanceSelectorCatalog,
    VisualSelectorMap,
    SelectorHint,
} from '@microsoft/powerbi-core-visual-schema';
```

## 📁 Package contents

```
@microsoft/powerbi-core-visual-schema/
├── index.{js,d.ts}                  # Public API
├── lib/
│   ├── visual-catalog.{js,d.ts}     # listVisualTypes, getCapabilities
│   ├── vco-catalog.{js,d.ts}        # listVcoKeys, getVcoCapabilities
│   └── instance-selectors.{js,d.ts} # listInstanceSelectorKeys, getInstanceSelectors, getSelectorHints
├── types/index.d.ts                 # All public type definitions
└── data/
    ├── capabilities.json            # ~55 visuals, ~850 KB
    ├── vco-capabilities.json        # 15 VCOs, ~18 KB
    └── instance-selectors.json      # 8 selector keys, ~3 KB
```

## 🧠 Three independent catalogs

The package exposes three orthogonal catalogs because the underlying data is genuinely orthogonal:

- **Visual capabilities** describe what a chart/visual can *do*: which data roles it accepts, which formatting objects it has, whether it supports highlight/selection/etc.
- **VCO descriptors** describe the **container chrome** that wraps every visual (title, background, border, …) — these properties live one level above the visual.
- **Instance selectors** describe **state-keyed formatting buckets** for elements that have multiple variants of the same property (e.g. an action button has different `fill` colors for `default`/`hover`/`selected`/`disabled`). Most selector keys are visual identifiers, but some are non-visual chrome elements like `filterCard`.

Each catalog is queried independently, so consumers can pick the right one for the question they're asking.
