md-organization-chart spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
A tree of nodes with connectors. Renders a hierarchy — reporting lines, categories, taxonomies — as avatar cards joined by connector lines, with collapsible branches, optional single or multiple selection, and the full WAI-ARIA tree keyboard model.
<md-organization-chart label="Reporting structure" selection-mode="single"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
},
{
id: "be",
name: "Stephen Shaw",
title: "Backend Engineer"
}
]
}
]
}
];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
},
{
id: "be",
name: "Stephen Shaw",
title: "Backend Engineer"
}
]
}
]
}
];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
label="Reporting structure"
selection-mode="single"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
label="Reporting structure"
selection-mode="single"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
},
{
id: "be",
name: "Stephen Shaw",
title: "Backend Engineer"
}
]
}
]
}
];
}<script setup lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
},
{
id: "be",
name: "Stephen Shaw",
title: "Backend Engineer"
}
]
}
]
}
];
</script>
<template>
<md-organization-chart
:nodes="nodes"
label="Reporting structure"
selection-mode="single"
/>
</template><script lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
},
{
id: "be",
name: "Stephen Shaw",
title: "Backend Engineer"
}
]
}
]
}
];
</script>
<md-organization-chart
nodes={nodes}
label="Reporting structure"
selection-mode="single"
/>
Already installed? See the
Installation guide for one-time package setup
(core + tokens, fonts). Each tab below shows two patterns for using
md-organization-chart in your project: Option A registers every AWC UI
component at once (simplest), Option B imports only this component for
tree-shake-friendly bundles.
<!-- ─── Option A: global registration (all components) ─── -->
<script type="module">
import '@awc-ui/core/define';
</script>
<!-- ─── Option B: single import (tree-shake only md-organization-chart) ─── -->
<script type="module">
import '@awc-ui/core/components/md-organization-chart';
</script>
<md-organization-chart></md-organization-chart>// ─── Option A: typed React wrapper (registers all components) ───
// Importing from '@awc-ui/react' calls defineCustomElements() as a
// side effect, so every md-* element becomes available in the browser.
import { MdOrganizationChart } from '@awc-ui/react';
export function Example() {
return <MdOrganizationChart></MdOrganizationChart>;
}
// ─── Option B: single import (tree-shake to only md-organization-chart) ───
// Skip the wrapper and use the raw custom element. Smallest bundle,
// but you lose typed props/events on JSX.
import '@awc-ui/core/components/md-organization-chart';
export function ExampleTreeShaken() {
return <md-organization-chart></md-organization-chart>;
}// ─── Option A: schema module (any md-* element accepted) ───
// Pair with `defineCustomElements(window)` in main.ts.
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<md-organization-chart></md-organization-chart>`,
})
export class ExampleComponent {}
// ─── Option B: typed directive (tree-shake friendly) ───
// Pair with `import '@awc-ui/core/components/md-organization-chart'` in main.ts.
import { Component } from '@angular/core';
import { MdOrganizationChart } from '@awc-ui/angular';
@Component({
standalone: true,
imports: [MdOrganizationChart],
template: `<md-organization-chart></md-organization-chart>`,
})
export class ExampleTreeShakenComponent {}<!-- ─── Option A: typed Vue wrapper (registers all components) ─── -->
<script setup lang="ts">
import { MdOrganizationChart } from '@awc-ui/vue';
</script>
<template>
<MdOrganizationChart></MdOrganizationChart>
</template>
<!-- ─── Option B: single import (tree-shake to only md-organization-chart) ─── -->
<script setup lang="ts">
import '@awc-ui/core/components/md-organization-chart';
</script>
<template>
<md-organization-chart></md-organization-chart>
</template><!-- ─── Option A: global registration (done once in main entry) ─── -->
<!-- main.ts: -->
<!-- import { defineCustomElements } from '@awc-ui/svelte'; -->
<!-- defineCustomElements(window); -->
<md-organization-chart></md-organization-chart>
<!-- ─── Option B: single import (tree-shake to only md-organization-chart) ─── -->
<script lang="ts">
import '@awc-ui/core/components/md-organization-chart';
</script>
<md-organization-chart></md-organization-chart>| Situation | Use instead |
|---|---|
| A flat list | md-list |
| Tabular data | md-table |
| A file-tree navigation sidebar | md-list with indentation, or a tree control |
| Where-am-I in a path | md-breadcrumbs |
| Progressive disclosure of sections | md-accordion |
| Quantities or trends | The chart components |
| A very large graph (thousands of nodes) | A dedicated graph library |
| Need | Setting |
|---|---|
| Top-down chart | orientation="vertical" (default) |
| Left-to-right chart | orientation="horizontal" |
| Fold togglers on the cards | collapsible (default on) — pointer affordance only |
| Pick one node | selection-mode="single" |
| Pick several | selection-mode="multiple" |
| Preselect | selectedIds (array property) |
| Tighter rows | density="-1…-4" |
The whole chart is one prop. nodes is the tree; everything else on the
element is presentation.
const el = document.querySelector('md-organization-chart');el.nodes = [{ id: 'ceo', name: 'Ada Lovelace', title: 'CEO', avatar: '/u/ada.jpg', children: [{ id: 'cto', name: 'Grace Hopper', title: 'CTO' }] }];el.selectedIds = ['cto'];The attribute form is what makes the chart usable from plain markup — a CMS field, or a server-rendered template with no script to run:
<md-organization-chart nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO", "children":[{"id":"cto","name":"Grace Hopper","title":"CTO"}]}]'></md-organization-chart>That markup is the demo below — nothing feeds it, the attribute is the data:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdOrganizationChart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</template><script>
import '@awc-ui/core/define';
</script>
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>Node identity is id. selectedIds and every event payload key off it, so ids
must be unique across the whole tree, not just within a branch.
| Field | Type | Purpose |
|---|---|---|
id | string | Required. Stable identity for selection, expansion and events |
name | string | Required. Primary label, in the emphasis weight |
title | string | Secondary label, muted, under the name |
avatar | string | Avatar image URL |
avatarInitials | string | Explicit initials, overriding the name-derived ones |
accent | string | Reserved per-node accent colour — accepted, but currently has no visual effect |
expanded | boolean | Initial branch state — false starts collapsed |
selectable | boolean | false opts the node out of selection |
children | OrgChartNode[] | The branch below this node |
Everything except id and name is optional, so the terse form — an id, a name
and a children array — is a complete tree:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<md-organization-chart label="Category tree" nodes='[{"id":"all","name":"Catalogue","children":[{"id":"hw","name":"Hardware"},{"id":"sw","name":"Software"}]}]'></md-organization-chart>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<MdOrganizationChart label="Category tree" nodes='[{"id":"all","name":"Catalogue","children":[{"id":"hw","name":"Hardware"},{"id":"sw","name":"Software"}]}]'></MdOrganizationChart>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<md-organization-chart label="Category tree" nodes='[{"id":"all","name":"Catalogue","children":[{"id":"hw","name":"Hardware"},{"id":"sw","name":"Software"}]}]'></md-organization-chart><script setup>
import '@awc-ui/core/define';
</script>
<template>
<md-organization-chart label="Category tree" nodes='[{"id":"all","name":"Catalogue","children":[{"id":"hw","name":"Hardware"},{"id":"sw","name":"Software"}]}]'></md-organization-chart>
</template><script>
import '@awc-ui/core/define';
</script>
<md-organization-chart label="Category tree" nodes='[{"id":"all","name":"Catalogue","children":[{"id":"hw","name":"Hardware"},{"id":"sw","name":"Software"}]}]'></md-organization-chart>Two layouts, one ARIA model. orientation changes the visual flow only —
the tree semantics and the keyboard model are identical either way, so the
arrows still expand and collapse regardless of which direction the connectors
run.
| Value | Flow | Suits |
|---|---|---|
vertical | Top-down | Default. Wide, shallow trees — the classic org chart |
horizontal | Along the reading direction | Deep, narrow trees; long names |
horizontal flows from the reading start. Don’t force vertical when doing so
forces horizontal scrolling.
<md-organization-chart orientation="horizontal" label="Reporting structure" selection-mode="single"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "root",
name: "Ada Lovelace",
title: "CEO",
children: [
{
id: "a",
name: "Grace Hopper",
title: "CTO",
children: [
{
id: "a1",
name: "Alan Turing",
title: "Engineer"
}
]
},
{
id: "b",
name: "Katherine Johnson",
title: "CFO"
}
]
}
];
const selectedIds = ["a"];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes, selectedIds });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "root",
name: "Ada Lovelace",
title: "CEO",
children: [
{
id: "a",
name: "Grace Hopper",
title: "CTO",
children: [
{
id: "a1",
name: "Alan Turing",
title: "Engineer"
}
]
},
{
id: "b",
name: "Katherine Johnson",
title: "CFO"
}
]
}
];
const selectedIds = ["a"];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
selectedIds={selectedIds}
orientation="horizontal"
label="Reporting structure"
selection-mode="single"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
[selectedIds]="selectedIds"
orientation="horizontal"
label="Reporting structure"
selection-mode="single"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "root",
name: "Ada Lovelace",
title: "CEO",
children: [
{
id: "a",
name: "Grace Hopper",
title: "CTO",
children: [
{
id: "a1",
name: "Alan Turing",
title: "Engineer"
}
]
},
{
id: "b",
name: "Katherine Johnson",
title: "CFO"
}
]
}
];
selectedIds = ["a"];
}<script setup lang="ts">
const nodes = [
{
id: "root",
name: "Ada Lovelace",
title: "CEO",
children: [
{
id: "a",
name: "Grace Hopper",
title: "CTO",
children: [
{
id: "a1",
name: "Alan Turing",
title: "Engineer"
}
]
},
{
id: "b",
name: "Katherine Johnson",
title: "CFO"
}
]
}
];
const selectedIds = ["a"];
</script>
<template>
<md-organization-chart
:nodes="nodes"
:selectedIds="selectedIds"
orientation="horizontal"
label="Reporting structure"
selection-mode="single"
/>
</template><script lang="ts">
const nodes = [
{
id: "root",
name: "Ada Lovelace",
title: "CEO",
children: [
{
id: "a",
name: "Grace Hopper",
title: "CTO",
children: [
{
id: "a1",
name: "Alan Turing",
title: "Engineer"
}
]
},
{
id: "b",
name: "Katherine Johnson",
title: "CFO"
}
]
}
];
const selectedIds = ["a"];
</script>
<md-organization-chart
nodes={nodes}
selectedIds={selectedIds}
orientation="horizontal"
label="Reporting structure"
selection-mode="single"
/>nodes is an array, not a single root. Pass several and they render side by
side as independent trees inside one role="tree" — for a company with parallel
divisions, or a taxonomy with no single top term.
<md-organization-chart label="Regional structure"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "r1",
name: "Sales",
title: "Region West",
children: [
{
id: "r1a",
name: "Team A",
title: "6 people"
}
]
},
{
id: "r2",
name: "Sales",
title: "Region East",
children: [
{
id: "r2b",
name: "Team B",
title: "4 people"
}
]
}
];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "r1",
name: "Sales",
title: "Region West",
children: [
{
id: "r1a",
name: "Team A",
title: "6 people"
}
]
},
{
id: "r2",
name: "Sales",
title: "Region East",
children: [
{
id: "r2b",
name: "Team B",
title: "4 people"
}
]
}
];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
label="Regional structure"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
label="Regional structure"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "r1",
name: "Sales",
title: "Region West",
children: [
{
id: "r1a",
name: "Team A",
title: "6 people"
}
]
},
{
id: "r2",
name: "Sales",
title: "Region East",
children: [
{
id: "r2b",
name: "Team B",
title: "4 people"
}
]
}
];
}<script setup lang="ts">
const nodes = [
{
id: "r1",
name: "Sales",
title: "Region West",
children: [
{
id: "r1a",
name: "Team A",
title: "6 people"
}
]
},
{
id: "r2",
name: "Sales",
title: "Region East",
children: [
{
id: "r2b",
name: "Team B",
title: "4 people"
}
]
}
];
</script>
<template>
<md-organization-chart
:nodes="nodes"
label="Regional structure"
/>
</template><script lang="ts">
const nodes = [
{
id: "r1",
name: "Sales",
title: "Region West",
children: [
{
id: "r1a",
name: "Team A",
title: "6 people"
}
]
},
{
id: "r2",
name: "Sales",
title: "Region East",
children: [
{
id: "r2b",
name: "Team B",
title: "4 people"
}
]
}
];
</script>
<md-organization-chart
nodes={nodes}
label="Regional structure"
/>selection-mode is none by default — nodes rove focus but expose no
aria-selected. Keep it honest: only turn selection on when nodes really are
selectable.
| Mode | aria-selected | Behaviour |
|---|---|---|
none | Not exposed | Default. Nodes take focus; Enter toggles the branch instead |
single | On selectable nodes | One at a time; re-activating the sole selection clears it |
multiple | On selectable nodes | Accumulates; the tree gains aria-multiselectable |
<md-organization-chart selection-mode="single" label="Reporting structure"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes, selectedIds });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="single"
label="Reporting structure"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
[selectedIds]="selectedIds"
selection-mode="single"
label="Reporting structure"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
selectedIds = ["prod"];
}<script setup lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
</script>
<template>
<md-organization-chart
:nodes="nodes"
:selectedIds="selectedIds"
selection-mode="single"
label="Reporting structure"
/>
</template><script lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
</script>
<md-organization-chart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="single"
label="Reporting structure"
/><md-organization-chart selection-mode="multiple" label="Team picker"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "lead",
name: "Ada Lovelace",
title: "Team lead",
children: [
{
id: "m1",
name: "Grace Hopper",
title: "Engineer"
},
{
id: "m2",
name: "Alan Turing",
title: "Engineer"
},
{
id: "m3",
name: "Katherine Johnson",
title: "Analyst"
}
]
}
];
const selectedIds = ["m1", "m3"];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes, selectedIds });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "lead",
name: "Ada Lovelace",
title: "Team lead",
children: [
{
id: "m1",
name: "Grace Hopper",
title: "Engineer"
},
{
id: "m2",
name: "Alan Turing",
title: "Engineer"
},
{
id: "m3",
name: "Katherine Johnson",
title: "Analyst"
}
]
}
];
const selectedIds = ["m1", "m3"];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="multiple"
label="Team picker"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
[selectedIds]="selectedIds"
selection-mode="multiple"
label="Team picker"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "lead",
name: "Ada Lovelace",
title: "Team lead",
children: [
{
id: "m1",
name: "Grace Hopper",
title: "Engineer"
},
{
id: "m2",
name: "Alan Turing",
title: "Engineer"
},
{
id: "m3",
name: "Katherine Johnson",
title: "Analyst"
}
]
}
];
selectedIds = ["m1", "m3"];
}<script setup lang="ts">
const nodes = [
{
id: "lead",
name: "Ada Lovelace",
title: "Team lead",
children: [
{
id: "m1",
name: "Grace Hopper",
title: "Engineer"
},
{
id: "m2",
name: "Alan Turing",
title: "Engineer"
},
{
id: "m3",
name: "Katherine Johnson",
title: "Analyst"
}
]
}
];
const selectedIds = ["m1", "m3"];
</script>
<template>
<md-organization-chart
:nodes="nodes"
:selectedIds="selectedIds"
selection-mode="multiple"
label="Team picker"
/>
</template><script lang="ts">
const nodes = [
{
id: "lead",
name: "Ada Lovelace",
title: "Team lead",
children: [
{
id: "m1",
name: "Grace Hopper",
title: "Engineer"
},
{
id: "m2",
name: "Alan Turing",
title: "Engineer"
},
{
id: "m3",
name: "Katherine Johnson",
title: "Analyst"
}
]
}
];
const selectedIds = ["m1", "m3"];
</script>
<md-organization-chart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="multiple"
label="Team picker"
/>A node with selectable: false stays focusable and still takes the roving
tabindex — it simply never advertises or accepts a selection. Use it for group
headers and structural rows that exist to hold a branch, not to be picked.
<md-organization-chart selection-mode="single" label="Team picker"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "lead",
name: "Team Lead",
title: "Group",
selectable: false,
children: [
{
id: "locked",
name: "Locked Node",
title: "Read-only",
selectable: false
},
{
id: "open",
name: "Open Node",
title: "Selectable"
}
]
}
];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "lead",
name: "Team Lead",
title: "Group",
selectable: false,
children: [
{
id: "locked",
name: "Locked Node",
title: "Read-only",
selectable: false
},
{
id: "open",
name: "Open Node",
title: "Selectable"
}
]
}
];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
selection-mode="single"
label="Team picker"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
selection-mode="single"
label="Team picker"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "lead",
name: "Team Lead",
title: "Group",
selectable: false,
children: [
{
id: "locked",
name: "Locked Node",
title: "Read-only",
selectable: false
},
{
id: "open",
name: "Open Node",
title: "Selectable"
}
]
}
];
}<script setup lang="ts">
const nodes = [
{
id: "lead",
name: "Team Lead",
title: "Group",
selectable: false,
children: [
{
id: "locked",
name: "Locked Node",
title: "Read-only",
selectable: false
},
{
id: "open",
name: "Open Node",
title: "Selectable"
}
]
}
];
</script>
<template>
<md-organization-chart
:nodes="nodes"
selection-mode="single"
label="Team picker"
/>
</template><script lang="ts">
const nodes = [
{
id: "lead",
name: "Team Lead",
title: "Group",
selectable: false,
children: [
{
id: "locked",
name: "Locked Node",
title: "Read-only",
selectable: false
},
{
id: "open",
name: "Open Node",
title: "Selectable"
}
]
}
];
</script>
<md-organization-chart
nodes={nodes}
selection-mode="single"
label="Team picker"
/>avatar takes an image URL. Without one the node falls back to
avatarInitials, and without that to initials derived from name — so a node
never renders an empty or broken avatar.
| Node fields | What renders |
|---|---|
avatar: '/u/ada.jpg' | The image |
avatarInitials: 'AC' | AC |
Neither, name: 'Ada Lovelace' | AL |
<md-organization-chart label="Departments"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "org",
name: "Acme Corp",
title: "Group",
avatarInitials: "AC",
children: [
{
id: "d1",
name: "Ada Lovelace",
title: "Research"
},
{
id: "d2",
name: "Grace Hopper",
title: "Engineering"
}
]
}
];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "org",
name: "Acme Corp",
title: "Group",
avatarInitials: "AC",
children: [
{
id: "d1",
name: "Ada Lovelace",
title: "Research"
},
{
id: "d2",
name: "Grace Hopper",
title: "Engineering"
}
]
}
];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
label="Departments"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
label="Departments"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "org",
name: "Acme Corp",
title: "Group",
avatarInitials: "AC",
children: [
{
id: "d1",
name: "Ada Lovelace",
title: "Research"
},
{
id: "d2",
name: "Grace Hopper",
title: "Engineering"
}
]
}
];
}<script setup lang="ts">
const nodes = [
{
id: "org",
name: "Acme Corp",
title: "Group",
avatarInitials: "AC",
children: [
{
id: "d1",
name: "Ada Lovelace",
title: "Research"
},
{
id: "d2",
name: "Grace Hopper",
title: "Engineering"
}
]
}
];
</script>
<template>
<md-organization-chart
:nodes="nodes"
label="Departments"
/>
</template><script lang="ts">
const nodes = [
{
id: "org",
name: "Acme Corp",
title: "Group",
avatarInitials: "AC",
children: [
{
id: "d1",
name: "Ada Lovelace",
title: "Research"
},
{
id: "d2",
name: "Grace Hopper",
title: "Engineering"
}
]
}
];
</script>
<md-organization-chart
nodes={nodes}
label="Departments"
/>collapsible is on by default; each node’s initial state comes from its own
expanded field. Collapse deep branches by default — the component does not
virtualize, so a fully-expanded 500-node tree is slow and unreadable, and deep
trees are hard to navigate by keyboard.
<md-organization-chart label="Taxonomy"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "root",
name: "Catalogue",
title: "All products",
children: [
{
id: "c1",
name: "Hardware",
title: "12 items",
expanded: false,
children: [
{
id: "c1a",
name: "Laptops",
title: "5 items"
},
{
id: "c1b",
name: "Phones",
title: "7 items"
}
]
},
{
id: "c2",
name: "Software",
title: "8 items",
expanded: false,
children: [
{
id: "c2a",
name: "Licences",
title: "8 items"
}
]
}
]
}
];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "root",
name: "Catalogue",
title: "All products",
children: [
{
id: "c1",
name: "Hardware",
title: "12 items",
expanded: false,
children: [
{
id: "c1a",
name: "Laptops",
title: "5 items"
},
{
id: "c1b",
name: "Phones",
title: "7 items"
}
]
},
{
id: "c2",
name: "Software",
title: "8 items",
expanded: false,
children: [
{
id: "c2a",
name: "Licences",
title: "8 items"
}
]
}
]
}
];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
label="Taxonomy"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
label="Taxonomy"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "root",
name: "Catalogue",
title: "All products",
children: [
{
id: "c1",
name: "Hardware",
title: "12 items",
expanded: false,
children: [
{
id: "c1a",
name: "Laptops",
title: "5 items"
},
{
id: "c1b",
name: "Phones",
title: "7 items"
}
]
},
{
id: "c2",
name: "Software",
title: "8 items",
expanded: false,
children: [
{
id: "c2a",
name: "Licences",
title: "8 items"
}
]
}
]
}
];
}<script setup lang="ts">
const nodes = [
{
id: "root",
name: "Catalogue",
title: "All products",
children: [
{
id: "c1",
name: "Hardware",
title: "12 items",
expanded: false,
children: [
{
id: "c1a",
name: "Laptops",
title: "5 items"
},
{
id: "c1b",
name: "Phones",
title: "7 items"
}
]
},
{
id: "c2",
name: "Software",
title: "8 items",
expanded: false,
children: [
{
id: "c2a",
name: "Licences",
title: "8 items"
}
]
}
]
}
];
</script>
<template>
<md-organization-chart
:nodes="nodes"
label="Taxonomy"
/>
</template><script lang="ts">
const nodes = [
{
id: "root",
name: "Catalogue",
title: "All products",
children: [
{
id: "c1",
name: "Hardware",
title: "12 items",
expanded: false,
children: [
{
id: "c1a",
name: "Laptops",
title: "5 items"
},
{
id: "c1b",
name: "Phones",
title: "7 items"
}
]
},
{
id: "c2",
name: "Software",
title: "8 items",
expanded: false,
children: [
{
id: "c2a",
name: "Licences",
title: "8 items"
}
]
}
]
}
];
</script>
<md-organization-chart
nodes={nodes}
label="Taxonomy"
/>collapsible="false" removes the pointer affordance, not the folding. The
keyboard model is untouched — ← still collapses an expanded parent, → still
expands a collapsed one, and Enter / Space still toggles when nothing is
selectable — and a node authored expanded: false still starts collapsed. So a
branch folded that way has no visible toggler to reopen it: only the arrow keys
will. Use collapsible="false" for a tree small enough that no branch ships
folded, and leave every expanded field alone when you do.
Slot your own copy into empty rather than rendering a blank area. The
container carries role="status", so the message is announced when a tree
resolves to nothing.
<md-organization-chart label="Reporting structure"><div slot="empty">No people yet. Invite someone to get started.</div></md-organization-chart>
<script type="module">
const nodes = [];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
label="Reporting structure"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
label="Reporting structure"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [];
}<script setup lang="ts">
const nodes = [];
</script>
<template>
<md-organization-chart
:nodes="nodes"
label="Reporting structure"
/>
</template><script lang="ts">
const nodes = [];
</script>
<md-organization-chart
nodes={nodes}
label="Reporting structure"
/>This is also where a malformed nodes string lands: invalid JSON parses to
nothing rather than throwing, so a bad feed degrades into your empty copy
instead of a blank rectangle.
The chart doesn’t fetch or lazy-load anything — it renders exactly what you
give it. mdNodeToggle tells you a branch opened, which is where you load the
children and reassign nodes.
A branch with no children renders no toggler at all, so a lazy branch needs a
placeholder child to be openable. Open either branch below: the placeholder is
swapped for the fetched rows about half a second later.
<md-organization-chart label="Reporting structure"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
expanded: false,
children: [
{
id: "prod-pending",
name: "Loading…"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
expanded: false,
children: [
{
id: "eng-pending",
name: "Loading…"
}
]
}
]
}
];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes });
// Stands in for the network. Your version awaits a fetch.
const fetchReports = (id) => new Promise((resolve) => setTimeout(() => resolve({
prod: [
{ id: 'ux', name: 'Anna Fali', title: 'UX Designer' },
{ id: 'pm', name: 'Bernardo Dominic', title: 'Product Manager' },
],
eng: [
{ id: 'fe', name: 'Elwin Sharvill', title: 'Frontend Engineer' },
{ id: 'be', name: 'Stephen Shaw', title: 'Backend Engineer' },
],
}[id] || []), 500));
const loaded = new Set();
// Rebuild the branch rather than mutating it — a reassignment of 'nodes' is
// what re-renders. 'expanded' is re-read from the data every time, so every
// branch the user has already opened has to keep saying expanded: true.
const insertChildren = (list, id, children) => list.map((n) => {
const next = Object.assign({}, n, loaded.has(n.id) ? { expanded: true } : null);
if (n.id === id) next.children = children;
else if (n.children) next.children = insertChildren(n.children, id, children);
return next;
});
const onToggle = async (e) => {
const node = e.detail.node;
if (!e.detail.expanded || loaded.has(node.id)) return;
loaded.add(node.id);
el.nodes = insertChildren(el.nodes, node.id, await fetchReports(node.id));
};
el.addEventListener('mdNodeToggle', onToggle);
return () => el.removeEventListener('mdNodeToggle', onToggle);
</script>import { useEffect, useRef } from 'react';
import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
expanded: false,
children: [
{
id: "prod-pending",
name: "Loading…"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
expanded: false,
children: [
{
id: "eng-pending",
name: "Loading…"
}
]
}
]
}
];
export function Chart() {
const ref = useRef<HTMLMdOrganizationChartElement>(null);
// Imperative setup runs once the element exists.
useEffect(() => {
const el = ref.current;
if (!el) return;
// Stands in for the network. Your version awaits a fetch.
const fetchReports = (id) => new Promise((resolve) => setTimeout(() => resolve({
prod: [
{ id: 'ux', name: 'Anna Fali', title: 'UX Designer' },
{ id: 'pm', name: 'Bernardo Dominic', title: 'Product Manager' },
],
eng: [
{ id: 'fe', name: 'Elwin Sharvill', title: 'Frontend Engineer' },
{ id: 'be', name: 'Stephen Shaw', title: 'Backend Engineer' },
],
}[id] || []), 500));
const loaded = new Set();
// Rebuild the branch rather than mutating it — a reassignment of 'nodes' is
// what re-renders. 'expanded' is re-read from the data every time, so every
// branch the user has already opened has to keep saying expanded: true.
const insertChildren = (list, id, children) => list.map((n) => {
const next = Object.assign({}, n, loaded.has(n.id) ? { expanded: true } : null);
if (n.id === id) next.children = children;
else if (n.children) next.children = insertChildren(n.children, id, children);
return next;
});
const onToggle = async (e) => {
const node = e.detail.node;
if (!e.detail.expanded || loaded.has(node.id)) return;
loaded.add(node.id);
el.nodes = insertChildren(el.nodes, node.id, await fetchReports(node.id));
};
el.addEventListener('mdNodeToggle', onToggle);
return () => el.removeEventListener('mdNodeToggle', onToggle);
}, []);
return (
<MdOrganizationChart
ref={ref}
nodes={nodes}
label="Reporting structure"
/>
);
}import { Component, AfterViewInit, ElementRef, ViewChild } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart #chart
[nodes]="nodes"
label="Reporting structure"
></md-organization-chart>
`,
})
export class ChartComponent implements AfterViewInit {
nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
expanded: false,
children: [
{
id: "prod-pending",
name: "Loading…"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
expanded: false,
children: [
{
id: "eng-pending",
name: "Loading…"
}
]
}
]
}
];
@ViewChild('chart') chartRef!: ElementRef<HTMLMdOrganizationChartElement>;
// The view has to exist before the element can be set up.
ngAfterViewInit() {
const el = this.chartRef.nativeElement;
// Stands in for the network. Your version awaits a fetch.
const fetchReports = (id) => new Promise((resolve) => setTimeout(() => resolve({
prod: [
{ id: 'ux', name: 'Anna Fali', title: 'UX Designer' },
{ id: 'pm', name: 'Bernardo Dominic', title: 'Product Manager' },
],
eng: [
{ id: 'fe', name: 'Elwin Sharvill', title: 'Frontend Engineer' },
{ id: 'be', name: 'Stephen Shaw', title: 'Backend Engineer' },
],
}[id] || []), 500));
const loaded = new Set();
// Rebuild the branch rather than mutating it — a reassignment of 'nodes' is
// what re-renders. 'expanded' is re-read from the data every time, so every
// branch the user has already opened has to keep saying expanded: true.
const insertChildren = (list, id, children) => list.map((n) => {
const next = Object.assign({}, n, loaded.has(n.id) ? { expanded: true } : null);
if (n.id === id) next.children = children;
else if (n.children) next.children = insertChildren(n.children, id, children);
return next;
});
const onToggle = async (e) => {
const node = e.detail.node;
if (!e.detail.expanded || loaded.has(node.id)) return;
loaded.add(node.id);
el.nodes = insertChildren(el.nodes, node.id, await fetchReports(node.id));
};
el.addEventListener('mdNodeToggle', onToggle);
return () => el.removeEventListener('mdNodeToggle', onToggle);
}
}<script setup lang="ts">
import { onMounted, ref } from 'vue';
const chart = ref(null);
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
expanded: false,
children: [
{
id: "prod-pending",
name: "Loading…"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
expanded: false,
children: [
{
id: "eng-pending",
name: "Loading…"
}
]
}
]
}
];
onMounted(() => {
const el = chart.value;
// Stands in for the network. Your version awaits a fetch.
const fetchReports = (id) => new Promise((resolve) => setTimeout(() => resolve({
prod: [
{ id: 'ux', name: 'Anna Fali', title: 'UX Designer' },
{ id: 'pm', name: 'Bernardo Dominic', title: 'Product Manager' },
],
eng: [
{ id: 'fe', name: 'Elwin Sharvill', title: 'Frontend Engineer' },
{ id: 'be', name: 'Stephen Shaw', title: 'Backend Engineer' },
],
}[id] || []), 500));
const loaded = new Set();
// Rebuild the branch rather than mutating it — a reassignment of 'nodes' is
// what re-renders. 'expanded' is re-read from the data every time, so every
// branch the user has already opened has to keep saying expanded: true.
const insertChildren = (list, id, children) => list.map((n) => {
const next = Object.assign({}, n, loaded.has(n.id) ? { expanded: true } : null);
if (n.id === id) next.children = children;
else if (n.children) next.children = insertChildren(n.children, id, children);
return next;
});
const onToggle = async (e) => {
const node = e.detail.node;
if (!e.detail.expanded || loaded.has(node.id)) return;
loaded.add(node.id);
el.nodes = insertChildren(el.nodes, node.id, await fetchReports(node.id));
};
el.addEventListener('mdNodeToggle', onToggle);
return () => el.removeEventListener('mdNodeToggle', onToggle);
});
</script>
<template>
<md-organization-chart
ref="chart"
:nodes="nodes"
label="Reporting structure"
/>
</template><script lang="ts">
import { onMount } from 'svelte';
let chart;
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
expanded: false,
children: [
{
id: "prod-pending",
name: "Loading…"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
expanded: false,
children: [
{
id: "eng-pending",
name: "Loading…"
}
]
}
]
}
];
onMount(() => {
const el = chart;
// Stands in for the network. Your version awaits a fetch.
const fetchReports = (id) => new Promise((resolve) => setTimeout(() => resolve({
prod: [
{ id: 'ux', name: 'Anna Fali', title: 'UX Designer' },
{ id: 'pm', name: 'Bernardo Dominic', title: 'Product Manager' },
],
eng: [
{ id: 'fe', name: 'Elwin Sharvill', title: 'Frontend Engineer' },
{ id: 'be', name: 'Stephen Shaw', title: 'Backend Engineer' },
],
}[id] || []), 500));
const loaded = new Set();
// Rebuild the branch rather than mutating it — a reassignment of 'nodes' is
// what re-renders. 'expanded' is re-read from the data every time, so every
// branch the user has already opened has to keep saying expanded: true.
const insertChildren = (list, id, children) => list.map((n) => {
const next = Object.assign({}, n, loaded.has(n.id) ? { expanded: true } : null);
if (n.id === id) next.children = children;
else if (n.children) next.children = insertChildren(n.children, id, children);
return next;
});
const onToggle = async (e) => {
const node = e.detail.node;
if (!e.detail.expanded || loaded.has(node.id)) return;
loaded.add(node.id);
el.nodes = insertChildren(el.nodes, node.id, await fetchReports(node.id));
};
el.addEventListener('mdNodeToggle', onToggle);
return () => el.removeEventListener('mdNodeToggle', onToggle);
});
</script>
<md-organization-chart
bind:this={chart}
nodes={nodes}
label="Reporting structure"
/>| Event | Cancelable | Detail | Fires |
|---|---|---|---|
mdSelectionChange | no | OrgChartSelectionChangeDetail — { node, selectedIds } | A node’s selected state changes |
mdNodeToggle | no | OrgChartToggleDetail — { node, expanded } | A branch is expanded or collapsed |
interface OrgChartSelectionChangeDetail { node: OrgChartNode; // the node the user acted on selectedIds: string[]; // the WHOLE selection after the change}
interface OrgChartToggleDetail { node: OrgChartNode; expanded: boolean; // the state the branch has just taken}| You want to… | Listen to |
|---|---|
| Show a detail panel for the node just picked | mdSelectionChange — detail.node |
| Persist the current selection | mdSelectionChange — detail.selectedIds |
| Fetch a branch’s children on first open | mdNodeToggle — guard on detail.expanded |
| Remember which branches the user folded | mdNodeToggle |
Both events, live. Pick a node, pick it again to clear it, and fold a branch — every payload lands in the log:
<md-organization-chart id="org" selection-mode="single" label="Reporting structure">
<div slot="empty">No people yet.</div>
</md-organization-chart>
<script type="module">
const org = document.getElementById('org');
org.nodes = [{
id: 'ceo', name: 'Ada Lovelace', title: 'CEO',
children: [
{ id: 'cto', name: 'Grace Hopper', title: 'CTO',
children: [{ id: 'eng1', name: 'Alan Turing', title: 'Engineer' }] },
{ id: 'cfo', name: 'Katherine Johnson', title: 'CFO' },
],
}];
org.addEventListener('mdSelectionChange', (e) => {
console.log(e.detail.node.id, e.detail.selectedIds);
});
org.addEventListener('mdNodeToggle', (e) => {
console.log(e.detail.node.id, e.detail.expanded);
});
</script>import { MdOrganizationChart } from '@awc-ui/react';
const PEOPLE = [{
id: 'ceo', name: 'Ada Lovelace', title: 'CEO',
children: [
{ id: 'cto', name: 'Grace Hopper', title: 'CTO',
children: [{ id: 'eng1', name: 'Alan Turing', title: 'Engineer' }] },
{ id: 'cfo', name: 'Katherine Johnson', title: 'CFO' },
],
}];
export function OrgChart() {
// nodes is forwarded as a PROPERTY by the wrapper — pass the array as a prop
// and it re-forwards whenever it changes. No ref, no effect.
return (
<MdOrganizationChart
nodes={PEOPLE}
selectionMode="single"
label="Reporting structure"
onMdSelectionChange={(e) => console.log(e.detail.node.id, e.detail.selectedIds)}
onMdNodeToggle={(e) => console.log(e.detail.node.id, e.detail.expanded)}
>
<div slot="empty">No people yet.</div>
</MdOrganizationChart>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-org-chart',
// [nodes] is a property binding on the custom element, so the array lands
// as a property — no ViewChild, no ngAfterViewInit.
template: `
<md-organization-chart
[nodes]="people"
selection-mode="single"
label="Reporting structure"
(mdSelectionChange)="onSelect($event)"
(mdNodeToggle)="onToggle($event)"
>
<div slot="empty">No people yet.</div>
</md-organization-chart>
`,
})
export class OrgChartComponent {
people = [{
id: 'ceo', name: 'Ada Lovelace', title: 'CEO',
children: [
{ id: 'cto', name: 'Grace Hopper', title: 'CTO',
children: [{ id: 'eng1', name: 'Alan Turing', title: 'Engineer' }] },
{ id: 'cfo', name: 'Katherine Johnson', title: 'CFO' },
],
}];
onSelect(e: CustomEvent) { console.log(e.detail.node.id, e.detail.selectedIds); }
onToggle(e: CustomEvent) { console.log(e.detail.node.id, e.detail.expanded); }
}<script setup lang="ts">
const people = [{
id: 'ceo', name: 'Ada Lovelace', title: 'CEO',
children: [
{ id: 'cto', name: 'Grace Hopper', title: 'CTO',
children: [{ id: 'eng1', name: 'Alan Turing', title: 'Engineer' }] },
{ id: 'cfo', name: 'Katherine Johnson', title: 'CFO' },
],
}];
function onSelect(e: CustomEvent) { console.log(e.detail.node.id, e.detail.selectedIds); }
function onToggle(e: CustomEvent) { console.log(e.detail.node.id, e.detail.expanded); }
</script>
<template>
<md-organization-chart
:nodes="people"
selection-mode="single"
label="Reporting structure"
@mdSelectionChange="onSelect"
@mdNodeToggle="onToggle"
>
<div slot="empty">No people yet.</div>
</md-organization-chart>
</template><script lang="ts">
const people = [{
id: 'ceo', name: 'Ada Lovelace', title: 'CEO',
children: [
{ id: 'cto', name: 'Grace Hopper', title: 'CTO',
children: [{ id: 'eng1', name: 'Alan Turing', title: 'Engineer' }] },
{ id: 'cfo', name: 'Katherine Johnson', title: 'CFO' },
],
}];
function onSelect(e: CustomEvent) { console.log(e.detail.node.id, e.detail.selectedIds); }
function onToggle(e: CustomEvent) { console.log(e.detail.node.id, e.detail.expanded); }
</script>
<md-organization-chart
nodes={people}
selection-mode="single"
label="Reporting structure"
on:mdSelectionChange={onSelect}
on:mdNodeToggle={onToggle}
>
<div slot="empty">No people yet.</div>
</md-organization-chart>| Property | Attribute | Type | Default | Reflects |
|---|---|---|---|---|
nodes | JS only | NodeInput | [] | — |
selectionMode | selection-mode | 'none' | 'single' | 'multiple' | 'none' | Yes |
selectedIds | JS only | string[] | [] | — |
collapsible | collapsible | boolean | true | — |
orientation | orientation | 'vertical' | 'horizontal' | 'vertical' | Yes |
label | label | string | 'Organization chart' | — |
expandLabel | expand-label | string | 'Expand' | — |
collapseLabel | collapse-label | string | 'Collapse' | — |
density | density | 0 | -1 | -2 | -3 | -4 | 0 | Yes |
| Slot | Description |
|---|---|
empty | Custom empty-state content |
Style internal elements through shadow DOM with ::part():
| Part | Description |
|---|---|
state-layer | Hover / selected overlay |
avatar | The md-avatar |
name | Primary label |
title | Secondary label |
toggle | Expand / collapse affordance |
group | A role="group" child list |
viewport | Scroll/pan container |
empty | Empty-state container |
tree | The role="tree" root list |
avatar-image | The avatar's <img> (exported) |
role="tree" on the root
list, role="treeitem" nodes, a roving tabindex, Arrow / Home / End
navigation and Enter / Space to select (or to toggle when nothing is
selectable).label names the chart region. expand-label / collapse-label name the
branch toggles — translate all three.aria-level, aria-setsize and aria-posinset; parents
expose aria-expanded; selectable nodes expose aria-selected, and the tree
gains aria-multiselectable in multiple mode.selection-mode honest — use
none when nodes are not selectable.| Key | Action |
|---|---|
Tab | A single stop for the whole chart (roving tabindex); Tab again leaves it |
↓ / ↑ | Next / previous visible node, depth-first |
→ | Collapsed parent → expand it; expanded parent → move to its first child |
← | Expanded parent → collapse it; otherwise move to the parent node |
Home / End | First / last visible node |
Enter / Space | Select the focused node — or toggle it when nothing is selectable |
Tab into this chart and drive it entirely from the keyboard — one Tab stop, then the arrows walk the tree:
<md-organization-chart label="Company org chart" selection-mode="single"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes, selectedIds });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
selectedIds={selectedIds}
label="Company org chart"
selection-mode="single"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
[selectedIds]="selectedIds"
label="Company org chart"
selection-mode="single"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
selectedIds = ["prod"];
}<script setup lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
</script>
<template>
<md-organization-chart
:nodes="nodes"
:selectedIds="selectedIds"
label="Company org chart"
selection-mode="single"
/>
</template><script lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead",
children: [
{
id: "ux",
name: "Anna Fali",
title: "UX Designer"
},
{
id: "pm",
name: "Bernardo Dominic",
title: "Product Manager"
}
]
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead",
children: [
{
id: "fe",
name: "Elwin Sharvill",
title: "Frontend Engineer"
}
]
}
]
}
];
const selectedIds = ["prod"];
</script>
<md-organization-chart
nodes={nodes}
selectedIds={selectedIds}
label="Company org chart"
selection-mode="single"
/>RTL — both orientations mirror. Connectors and elbows are authored with
logical properties throughout, and the tree’s rows are flex containers, so the
inherited direction decides sibling order: a root with children [CTO, CFO]
paints CTO on the left in LTR and on the right in RTL. horizontal mirrors more
obviously, because its levels also advance along the reading direction — but a
vertical chart is not symmetric, it re-orders. See RTL.
The same charts in both directions. Nothing is re-authored between them —
only dir changes. Watch the CTO / CFO order flip in the vertical chart, and
the whole flow flip in the horizontal one:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
</div>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '20px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '2.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>ltr</span>
<div dir="ltr" style={{ display: 'flex', gap: '32px', flexWrap: 'wrap', alignItems: 'flex-start' }}>
<MdOrganizationChart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
<MdOrganizationChart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
</div>
<span style={{ inlineSize: '2.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>rtl</span>
<div dir="rtl" style={{ display: 'flex', gap: '32px', flexWrap: 'wrap', alignItems: 'flex-start' }}>
<MdOrganizationChart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
<MdOrganizationChart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ltr</span>
<div dir="ltr" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
<span style="inline-size:2.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">rtl</span>
<div dir="rtl" style="display:flex;gap:32px;flex-wrap:wrap;align-items:flex-start;">
<md-organization-chart label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<md-organization-chart orientation="horizontal" label="Reporting structure" nodes='[{"id":"ceo","name":"Ada Lovelace","title":"CEO","children":[{"id":"cto","name":"Grace Hopper","title":"CTO"},{"id":"cfo","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
</div>dir — never pin itThere is no mirror prop, because there is nothing per-node to mirror: the flow
follows the inherited direction. Pinning dir="ltr" on a horizontal chart
inside an RTL page is the one way to get it wrong — the tree then grows away
from the reading direction, and ← / → swap meaning relative to everything
around it. Both rows below sit inside the same dir="rtl" block:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="ltr">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<div dir="rtl" style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '20px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>correct</span>
<MdOrganizationChart orientation="horizontal" label="الهيكل التنظيمي" expandLabel="توسيع" collapseLabel="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></MdOrganizationChart>
<span style={{ inlineSize: '3.5rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>wrong</span>
<div dir="ltr">
<MdOrganizationChart orientation="horizontal" label="الهيكل التنظيمي" expandLabel="توسيع" collapseLabel="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></MdOrganizationChart>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="ltr">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="ltr">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div dir="rtl" style="display:grid;grid-template-columns:auto 1fr;gap:20px 16px;align-items:center;">
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">correct</span>
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
<span style="inline-size:3.5rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">wrong</span>
<div dir="ltr">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div>density is a local override of the inherited data-density. It tapers node
padding, the avatar, the name and title type scale, the toggler, and both the
level and sibling gaps — the whole tree contracts, not just the cards.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-organization-chart density="0" label="Density 0" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-organization-chart density="-1" label="Density -1" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-organization-chart density="-2" label="Density -2" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-organization-chart density="-3" label="Density -3" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-organization-chart density="-4" label="Density -4" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '24px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>0</span>
<MdOrganizationChart density="0" label="Density 0" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-1</span>
<MdOrganizationChart density="-1" label="Density -1" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-2</span>
<MdOrganizationChart density="-2" label="Density -2" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-3</span>
<MdOrganizationChart density="-3" label="Density -3" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>-4</span>
<MdOrganizationChart density="-4" label="Density -4" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></MdOrganizationChart>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-organization-chart density="0" label="Density 0" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-organization-chart density="-1" label="Density -1" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-organization-chart density="-2" label="Density -2" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-organization-chart density="-3" label="Density -3" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-organization-chart density="-4" label="Density -4" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-organization-chart density="0" label="Density 0" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-organization-chart density="-1" label="Density -1" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-organization-chart density="-2" label="Density -2" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-organization-chart density="-3" label="Density -3" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-organization-chart density="-4" label="Density -4" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">0</span>
<md-organization-chart density="0" label="Density 0" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-1</span>
<md-organization-chart density="-1" label="Density -1" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-2</span>
<md-organization-chart density="-2" label="Density -2" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-3</span>
<md-organization-chart density="-3" label="Density -3" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">-4</span>
<md-organization-chart density="-4" label="Density -4" nodes='[{"id":"r","name":"Ada Lovelace","title":"CEO","children":[{"id":"a","name":"Grace Hopper","title":"CTO"},{"id":"b","name":"Katherine Johnson","title":"CFO"}]}]'></md-organization-chart>
</div>The two are independent signals, so they compose without any extra wiring — a
right-to-left horizontal tree at rung -2, with one node’s branch folded:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div dir="rtl" data-density="-2">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج","expanded":false,"children":[{"id":"u","name":"آنا فالي","title":"مصممة تجربة"}]},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<div dir="rtl" data-density="-2">
<MdOrganizationChart orientation="horizontal" label="الهيكل التنظيمي" expandLabel="توسيع" collapseLabel="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج","expanded":false,"children":[{"id":"u","name":"آنا فالي","title":"مصممة تجربة"}]},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></MdOrganizationChart>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div dir="rtl" data-density="-2">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج","expanded":false,"children":[{"id":"u","name":"آنا فالي","title":"مصممة تجربة"}]},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div dir="rtl" data-density="-2">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج","expanded":false,"children":[{"id":"u","name":"آنا فالي","title":"مصممة تجربة"}]},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div dir="rtl" data-density="-2">
<md-organization-chart orientation="horizontal" label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"الرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج","expanded":false,"children":[{"id":"u","name":"آنا فالي","title":"مصممة تجربة"}]},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>Density — density="-1…-4" locally overrides the inherited data-density
rung, tapering node padding, the avatar, both type sizes, the toggler and both
gaps at once. See Density.
i18n — node name and title come from your data; label, expand-label
and collapse-label are the only strings the component authors, and shipping
their English defaults is a bug in a localized app. dir and lang are
inherited from any ancestor, so a localized subtree needs no chart-specific
wiring. See RTL.
| Prop | Default | Names |
|---|---|---|
label | Organization chart | The role="tree" region |
expand-label | Expand | The toggler on a collapsed branch |
collapse-label | Collapse | The toggler on an expanded branch |
Plus the empty slot content, which is entirely yours.
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">de</span>
<md-organization-chart label="Organigramm" expand-label="Erweitern" collapse-label="Reduzieren" nodes='[{"id":"c","name":"Amy Elsner","title":"Gründerin und CEO","children":[{"id":"p","name":"Asiya Javayant","title":"Produktleitung"},{"id":"e","name":"Onyama Limba","title":"Technische Leitung"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ar</span>
<div dir="rtl">
<md-organization-chart label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"المؤسِّسة والرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '24px 16px', alignItems: 'center' }}>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>de</span>
<MdOrganizationChart label="Organigramm" expandLabel="Erweitern" collapseLabel="Reduzieren" nodes='[{"id":"c","name":"Amy Elsner","title":"Gründerin und CEO","children":[{"id":"p","name":"Asiya Javayant","title":"Produktleitung"},{"id":"e","name":"Onyama Limba","title":"Technische Leitung"}]}]'></MdOrganizationChart>
<span style={{ inlineSize: '2rem', opacity: '.65', fontSize: '.75rem', fontFamily: 'ui-monospace,monospace' }}>ar</span>
<div dir="rtl">
<MdOrganizationChart label="الهيكل التنظيمي" expandLabel="توسيع" collapseLabel="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"المؤسِّسة والرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></MdOrganizationChart>
</div>
</div>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">de</span>
<md-organization-chart label="Organigramm" expand-label="Erweitern" collapse-label="Reduzieren" nodes='[{"id":"c","name":"Amy Elsner","title":"Gründerin und CEO","children":[{"id":"p","name":"Asiya Javayant","title":"Produktleitung"},{"id":"e","name":"Onyama Limba","title":"Technische Leitung"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ar</span>
<div dir="rtl">
<md-organization-chart label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"المؤسِّسة والرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div><script setup>
import '@awc-ui/core/define';
</script>
<template>
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">de</span>
<md-organization-chart label="Organigramm" expand-label="Erweitern" collapse-label="Reduzieren" nodes='[{"id":"c","name":"Amy Elsner","title":"Gründerin und CEO","children":[{"id":"p","name":"Asiya Javayant","title":"Produktleitung"},{"id":"e","name":"Onyama Limba","title":"Technische Leitung"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ar</span>
<div dir="rtl">
<md-organization-chart label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"المؤسِّسة والرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div>
</template><script>
import '@awc-ui/core/define';
</script>
<div style="display:grid;grid-template-columns:auto 1fr;gap:24px 16px;align-items:center;">
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">de</span>
<md-organization-chart label="Organigramm" expand-label="Erweitern" collapse-label="Reduzieren" nodes='[{"id":"c","name":"Amy Elsner","title":"Gründerin und CEO","children":[{"id":"p","name":"Asiya Javayant","title":"Produktleitung"},{"id":"e","name":"Onyama Limba","title":"Technische Leitung"}]}]'></md-organization-chart>
<span style="inline-size:2rem;opacity:.65;font-size:.75rem;font-family:ui-monospace,monospace;">ar</span>
<div dir="rtl">
<md-organization-chart label="الهيكل التنظيمي" expand-label="توسيع" collapse-label="طي" nodes='[{"id":"c","name":"إيمي إلسنر","title":"المؤسِّسة والرئيس التنفيذي","children":[{"id":"p","name":"آسيا جافايانت","title":"قائدة المنتج"},{"id":"e","name":"أونياما ليمبا","title":"قائد الهندسة"}]}]'></md-organization-chart>
</div>
</div>Longer names widen nodes; --md-org-chart-node-max-width caps them, and the
name and title truncate with an ellipsis rather than reflowing the tree.
| Custom property | Purpose | Default |
|---|---|---|
--md-org-chart-connector-color / -connector-width | Connector lines | outline-variant / 1.5px |
--md-org-chart-node-color | Node surface | surface-container-low |
--md-org-chart-node-outline-color / -outline-width | Node border | outline-variant / 1px |
--md-org-chart-node-shape | Node corner radius | shape-corner-medium |
--md-org-chart-node-min-width / -max-width | Node width bounds | 176px / 260px |
--md-org-chart-selected-color | Selected node accent | primary |
--md-org-chart-state-layer-color | Hover / press overlay | on-surface |
--md-org-chart-focus-ring-color | Focus ring | secondary |
--md-org-chart-level-gap / -sibling-gap | Spacing between generations and siblings | Density-derived |
--md-org-chart-toggle-size | Expand / collapse affordance | Density-derived |
--md-org-chart-duration | Expand / collapse timing | motion-duration-medium2 (300ms) |
<md-organization-chart selection-mode="single" label="Reporting structure" style="--md-org-chart-connector-color: #7c4dff; --md-org-chart-node-outline-color: #7c4dff; --md-org-chart-node-shape: 20px; --md-org-chart-selected-color: #7c4dff; --md-org-chart-sibling-gap: 24px;"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["prod"];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes, selectedIds });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["prod"];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="single"
label="Reporting structure"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
[selectedIds]="selectedIds"
selection-mode="single"
label="Reporting structure"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
selectedIds = ["prod"];
}<script setup lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["prod"];
</script>
<template>
<md-organization-chart
:nodes="nodes"
:selectedIds="selectedIds"
selection-mode="single"
label="Reporting structure"
/>
</template><script lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["prod"];
</script>
<md-organization-chart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="single"
label="Reporting structure"
/>Every default resolves through an md-sys-color role, so a chart that sets no
custom properties follows the theme on its own. Switch this page between light
and dark — the chart below is untouched markup:
<md-organization-chart selection-mode="single" label="Reporting structure"></md-organization-chart>
<script type="module">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["eng"];
const el = document.querySelector("md-organization-chart");
Object.assign(el, { nodes, selectedIds });
</script>import { MdOrganizationChart } from '@awc-ui/react';
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["eng"];
export function Chart() {
return (
<MdOrganizationChart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="single"
label="Reporting structure"
/>
);
}import { Component } from '@angular/core';
@Component({
selector: 'app-chart',
template: `
<md-organization-chart
[nodes]="nodes"
[selectedIds]="selectedIds"
selection-mode="single"
label="Reporting structure"
></md-organization-chart>
`,
})
export class ChartComponent {
nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
selectedIds = ["eng"];
}<script setup lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["eng"];
</script>
<template>
<md-organization-chart
:nodes="nodes"
:selectedIds="selectedIds"
selection-mode="single"
label="Reporting structure"
/>
</template><script lang="ts">
const nodes = [
{
id: "ceo",
name: "Ada Lovelace",
title: "Founder & CEO",
children: [
{
id: "prod",
name: "Grace Hopper",
title: "Product Lead"
},
{
id: "eng",
name: "Alan Turing",
title: "Engineering Lead"
}
]
}
];
const selectedIds = ["eng"];
</script>
<md-organization-chart
nodes={nodes}
selectedIds={selectedIds}
selection-mode="single"
label="Reporting structure"
/>CSS Parts reach inside the shadow root for what custom properties do not cover — the type treatment of a label, or a selected node’s ring:
<!-- index.html — register the AWC UI elements once -->
<script type="module">
import '@awc-ui/core/define';
</script>
<style>
.parts-org::part(name) { text-transform: uppercase; letter-spacing: .06em; }
.parts-org::part(title) { font-style: italic; opacity: .8; }
.parts-org::part(node-selected) { box-shadow: 0 0 0 3px var(--md-sys-color-tertiary); }
</style>
<md-organization-chart class="parts-org" selection-mode="single"></md-organization-chart>import { MdOrganizationChart } from '@awc-ui/react';
export function Demo() {
return (
<>
<style>
.parts-org::part(name) { text-transform: uppercase; letter-spacing: .06em; }
.parts-org::part(title) { font-style: italic; opacity: .8; }
.parts-org::part(node-selected) { box-shadow: 0 0 0 3px var(--md-sys-color-tertiary); }
</style>
<MdOrganizationChart className="parts-org" selectionMode="single"></MdOrganizationChart>
</>
);
}// app.module.ts — register the AWC UI elements once
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AwcUiModule } from '@awc-ui/angular';
@NgModule({
imports: [AwcUiModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
<!-- app.component.html -->
<style>
.parts-org::part(name) { text-transform: uppercase; letter-spacing: .06em; }
.parts-org::part(title) { font-style: italic; opacity: .8; }
.parts-org::part(node-selected) { box-shadow: 0 0 0 3px var(--md-sys-color-tertiary); }
</style>
<md-organization-chart class="parts-org" selection-mode="single"></md-organization-chart><script setup>
import '@awc-ui/core/define';
</script>
<template>
<style>
.parts-org::part(name) { text-transform: uppercase; letter-spacing: .06em; }
.parts-org::part(title) { font-style: italic; opacity: .8; }
.parts-org::part(node-selected) { box-shadow: 0 0 0 3px var(--md-sys-color-tertiary); }
</style>
<md-organization-chart class="parts-org" selection-mode="single"></md-organization-chart>
</template><script>
import '@awc-ui/core/define';
</script>
<style>
.parts-org::part(name) { text-transform: uppercase; letter-spacing: .06em; }
.parts-org::part(title) { font-style: italic; opacity: .8; }
.parts-org::part(node-selected) { box-shadow: 0 0 0 3px var(--md-sys-color-tertiary); }
</style>
<md-organization-chart class="parts-org" selection-mode="single"></md-organization-chart>CSS parts — viewport, tree, group, node, node-selected,
state-layer, avatar, avatar-image, name, title, toggle, empty.
Slot — empty.
md-organization-chart.compact { --md-org-chart-node-max-width: 180px; --md-org-chart-level-gap: 24px; --md-org-chart-connector-color: var(--md-sys-color-outline-variant);}md-list ·
md-accordion ·
md-breadcrumbs ·
md-avatar ·
md-tooltip ·
md-icon-button
md-organization-chartTwo artefacts to give your AI agent so it generates correct UI with this component. The per-component spec answers "how do I use this exact tag?". The main-llm spec answers "which tag should I pick in the first place?".
md-organization-chart spec card
Identity · when to use / when NOT · decision cues · behavioural contract · do/don't · anti-patterns · full API. Paste into your agent when you're implementing with this component.
System-prompt preamble · decision matrix · token reference · page recipes · anti-patterns. Paste into the system prompt at the start of a piece of work.