npm package: @jack-pairce/react-org-chart-editor
Description: Interactive, editable organization chart component for React. Build, visualize, and edit hierarchical role structures with drag-and-drop, connectors, and an unassigned users list.
Author: JackPairce
Latest version: 0.9.6

# @jack-pairce/react-org-chart-editor

Interactive, editable organization chart component for React. Build, visualize, and edit hierarchical role structures with drag-and-drop, connectors, and an unassigned users list.

- Written in TypeScript
- Ships ESM/CJS typings from dist
- UI built with antd and tailwind (peer styles not required to consume the component)

## Install

- npm: npm i @jack-pairce/react-org-chart-editor antd
- pnpm: pnpm add @jack-pairce/react-org-chart-editor antd
- yarn: yarn add @jack-pairce/react-org-chart-editor antd

React 18+ is required.

## What you get

The package exports a single component:

- HierarchyPage — a fully featured org chart editor wrapped in internal context state.

Import path:

- ESM: import { HierarchyPage } from '@jack-pairce/react-org-chart-editor'

The build exposes types in dist/index.d.ts.

## Quick start

```tsx
import { useState } from 'react';
import { HierarchyPage } from '@jack-pairce/react-org-chart-editor';
import type { Role, User } from '@jack-pairce/react-org-chart-editor/dist/types';

const initialRoles: Role[] = [
  { id: 1, name: 'CEO', color: '#4F46E5', parent_id: null, is_responsable: true, can_sudo: true, users_limit: 1, users: [], level: 0, children: [] },
];

const initialUsers: User[] = [
  { id: 100, name: 'Alice', role_id: null },
  { id: 101, name: 'Bob', role_id: 1 },
];

export default function Demo() {
  const [roles, setRoles] = useState(initialRoles);
  const [users, setUsers] = useState(initialUsers);

  return (
    <HierarchyPage
      headerTitle="Company Structure"
      roles={roles}
      users={users}
      isLoading={false}
      initialEditMode="none"
      onChange={({ roles: nextRoles, users: nextUsers }) => {
        setRoles(nextRoles);
        setUsers(nextUsers);
      }}
      onSave={async ({ added, updated, deleted, usersChanged }) => {
        // Persist to your backend
        console.log({ added, updated, deleted, usersChanged });
      }}
    />
  );
}
```

## Props

HierarchyPage props are defined by HierarchyProps:

- headerTitle: string — Title displayed in the header toolbar.
- roles: Role[] — Flat list of roles. The component builds a tree internally (via parent_id).
- users: User[] — All users. Users with role_id === null appear in the Unassigned list.
- isLoading: boolean — Show a loading state.
- initialEditMode?: 'none' | 'reorder' | 'content' — Optional starting mode.
- onChange?: (next: { roles: Role[]; users: User[] }) => void — Fires whenever local state changes.
- onSave?: (payload: { added: Role[]; updated: Role[]; deleted: Role[]; usersChanged: User[] }) => Promise<void> | void — Called by UI save actions.

Types are available from the package types export, see below.

## Types

Minimal, framework-independent types are included:

- User (alias of DefaultUser)
  - id: number
  - name: string
  - family?: string
  - role_id: number | null
- Role
  - id: number
  - name: string
  - color: string
  - parent_id: number | null
  - is_responsable: boolean
  - can_sudo: boolean
  - users_limit: number
  - users: { id: number; name: string; icon?: string | ReactNode | (() => ReactNode) }[]
  - level: number
  - children: Role[]
  - Optional layout/runtime: x, y, isDragging, _new, _placeholder, _overlayed
- EditMode: 'none' | 'reorder' | 'content'

Note: The component computes layout coordinates (x,y) and connector paths internally. Provide roles as a flat array; the tree is built from parent_id relationships.

## Behavior overview

- Tree building and layout: roles are converted to a tree, levels are measured, and SVG connectors are rendered between parents and children.
- Drag-and-drop: move roles, reorder, and adjust levels. Height per level is computed dynamically.
- Unassigned users: fixed list for users with role_id = null; drag onto roles.
- Modes: editMode toggles behavior (reorder/content) while 'none' disables editing.
- onChange/onSave: wire these to persist changes.

## Styling

- The component includes minimal internal styles (src/components/style.css) and uses antd components. Consumers can override styles via global CSS. Tailwind is used in development but not required in your app.

## Development

- Dev preview: pnpm dev
- Build library: pnpm build (emits dist with types and JS)
- Bundle single entry via tsup: pnpm bundle

## Importing types

You can import types from the package root when using TypeScript:

```ts
import type { Role, User, EditMode } from '@jack-pairce/react-org-chart-editor/dist/types';
```

Alternatively, rely on inference by passing plain objects that match these shapes.

## License

MIT © JackPairce