Design
Style @memoir/tree with CSS variables, stable selectors, and custom cards.
@memoir/tree ships one small stylesheet. It sets the Memoir look: warm canvas, light cards, sharp corners, black outlines, black shadows, and root-node focus styling.
Import Styles
import "@memoir/tree/styles.css";The package never auto-imports CSS. Consumers opt in explicitly.
Theme
Use theme only to pick a built-in preset:
<FamilyTree people={people} subject="alex" relationships={relationships} theme="system" />memoir: the default cream canvas and outlined cards.system: neutral system colors.
For custom colors, use CSS variables through className or style.
The package also exports treeStylePresets and getTreeStyleName(theme) for wrappers that need to inspect or normalize preset names.
CSS Variables
<FamilyTree
className="my-tree"
people={people}
subject="alex"
relationships={relationships}
/>.my-tree {
--tree-canvas-bg: #fff7df;
--tree-card-bg: #ffffff;
--tree-card-border: #17120f;
--tree-card-shadow: 5px 5px 0 #17120f;
--tree-edge: #17120f;
--tree-edge-width: 2;
}Useful variables:
--tree-surface-bg--tree-canvas-bg--tree-card-bg--tree-card-fg--tree-card-border--tree-card-shadow--tree-card-radius--tree-edge--tree-edge-width--tree-muted-fg
Styled Family Card
Use StyledFamilyCard when you want a quick configurable card without writing custom markup:
import { FamilyTree, StyledFamilyCard } from "@memoir/tree";
<FamilyTree
card={StyledFamilyCard}
cardProps={{
radius: "round",
outlined: true,
shadow: "flat",
avatar: "round",
}}
people={people}
subject="alex"
relationships={relationships}
/>radius accepts square, soft, round, pill, or any CSS radius value. shadow accepts none, flat, soft, or any CSS shadow value. avatar accepts auto, hidden, square, soft, or round.
Stable Selectors
Shared selectors:
[data-tree-surface][data-tree-canvas][data-tree-card][data-tree-edge][data-person-id][data-selected][data-focused]
Family selectors:
[data-family-tree][data-family-canvas][data-family-card][data-family-edge][data-relation][data-generation][data-side]
Org selectors:
[data-org-chart][data-org-card][data-org-edge][data-depth][data-parent-id]
[data-family-card][data-relation="self"] {
background: var(--tree-accent);
}
[data-family-edge][data-edge-kind="adoptive"],
[data-family-edge][data-edge-kind="guardian"],
[data-family-edge][data-edge-status="former"] {
stroke-dasharray: 4 4;
}Family edge kinds come from the modeled relationship. The default family renderer passes a dashed stroke for adoptive, guardian, and former edges. Other kinds and statuses are still exposed through edge data attributes for custom CSS.
Card Root
Custom cards should spread the provided props onto the card root:
function ProfileCard({ focused, person, relation, ...rootProps }: FamilyCardProps<Person>) {
return (
<article {...rootProps}>
<strong>{person.name}</strong>
<small>{relation.label}</small>
</article>
);
}Those props carry accessibility metadata, click handlers, keyboard handlers, and styling hooks.
Interaction Hooks
The default interactionMode is "pan", so users can drag the canvas and non-interactive card surfaces with mouse, touch, or pen. Use "pan-page-scroll" when mouse or horizontal touch should drag the tree and vertical touch should scroll the page. Native controls inside cards keep their own pointer behavior. Add data-tree-drag-ignore to any custom card element that should not start panning.