Skip to content

Examples

Routes and organization

Open a canonical route, browse and pick hierarchical values, switch workspace tabs, and render an App-owned organization projection.

Public contractsNxCanonicalRoutePaneNxOrgChartNxColumnBrowserNxColumnPickerNxTabNav

Live preview

Live

Canonical route pane

The host keeps the management workspace mounted while a canonical route owns the record interaction.

NxCanonicalRoutePane

Hierarchy selection

Browse a hierarchy inline or reuse the same nodes in a selection dialog.

NxTabNav · NxColumnBrowser · NxColumnPicker
Operations

Organization projection

Apps provide neutral organization items and labels; the host owns layout, focus, and accessibility behavior.

NxOrgChart
2 of 2 visible
MKMin Kim

Copyable source

Code example
TSX
import { useState } from "react";
import {
    NxButton,
    NxCanonicalRoutePane,
    NxColumnBrowser,
    NxColumnPicker,
    NxOrgChart,
    NxTabNav,
    type NxOrgChartLabels,
} from "@nexia/sdk/host";

const WORKSPACE_ROOTS = [
    {
        value: "operations",
        label: "Operations",
        children: [
            { value: "production", label: "Production" },
            { value: "maintenance", label: "Maintenance" },
        ],
    },
    {
        value: "quality",
        label: "Quality",
        children: [
            { value: "incoming", label: "Incoming inspection" },
            { value: "final", label: "Final inspection" },
        ],
    },
];

const labels: NxOrgChartLabels = {
    canvas: "Organization chart",
    focusNode: (label) => `Focus ${label}`,
    clearFocus: "Show full organization",
    expandSubtree: (label) => `Expand ${label}`,
    collapseSubtree: (label) => `Collapse ${label}`,
    showAllMembers: "Show all members",
    hideAllMembers: "Hide all members",
    showMembers: (label, count) => `Show ${count} members in ${label}`,
    hideMembers: (label, count) => `Hide ${count} members in ${label}`,
    memberList: (label) => `${label} members`,
    arrangeCards: "Arrange cards",
    resetLayout: "Reset layout",
    moveCard: (label) => `Move ${label}`,
    addChild: (label) => `Add a team below ${label}`,
    addMember: (label) => `Add a member to ${label}`,
    editColor: (label) => `Edit ${label} color`,
    visibleCount: (visible, total) => `${visible} of ${total} visible`,
    truncated: (limit, total) => `Showing ${limit} of ${total}`,
    root: "Root organization",
    moveNode: (label) => `Move ${label}`,
    moveKeyboardHint: "Use arrow keys to choose a new parent.",
    movePreview: (moving, parent, position, total) =>
        `Move ${moving} under ${parent}, position ${position} of ${total}`,
};

export function RouteAndOrganizationExample() {
    const [paneOpen, setPaneOpen] = useState(false);
    const [pickerOpen, setPickerOpen] = useState(false);
    const [activeTab, setActiveTab] = useState("browse");
    const [selectedArea, setSelectedArea] = useState<string | null>(
        "production",
    );
    const [selectedOrganizationId, setSelectedOrganizationId] = useState<
        string | null
    >(null);

    return (
        <div className="grid gap-6" data-pane-path="/apps/quality/inspections">
            <section className="rounded-control border border-border-subtle p-4">
                <h2 className="font-medium">Open a canonical Resource route</h2>
                <p className="mt-1 text-sm text-text-secondary">
                    Keep the management workspace mounted while the owning
                    Resource route handles the write.
                </p>
                <NxButton className="mt-4" onClick={() => setPaneOpen(true)}>
                    Review inspection
                </NxButton>
                <NxCanonicalRoutePane
                    open={paneOpen}
                    route="/apps/quality/inspections/inspection-1042"
                    closeRoute="/apps/quality/inspections"
                    title="Inspection INS-1042"
                    onOpenChange={setPaneOpen}
                />
            </section>

            <section className="grid gap-4 rounded-control border border-border-subtle p-4">
                <NxTabNav
                    items={[
                        { id: "browse", label: "Browse areas" },
                        { id: "recent", label: "Recent", badge: 3 },
                    ]}
                    value={activeTab}
                    onChange={setActiveTab}
                    aria-label="Area views"
                />
                <NxColumnBrowser
                    roots={WORKSPACE_ROOTS}
                    value={selectedArea}
                    onSelect={(value) => setSelectedArea(value)}
                    searchable
                    searchPlaceholder="Search areas"
                    ariaLabel="Operational areas"
                    heightClassName="h-72"
                    renderPreview={(node) => (
                        <p className="text-sm text-text-secondary">
                            Selected area: {node.label}
                        </p>
                    )}
                />
                <div>
                    <NxButton
                        variant="secondary"
                        onClick={() => setPickerOpen(true)}
                    >
                        Choose in a dialog
                    </NxButton>
                </div>
                <NxColumnPicker
                    open={pickerOpen}
                    onClose={() => setPickerOpen(false)}
                    title="Choose an operational area"
                    roots={WORKSPACE_ROOTS}
                    value={selectedArea}
                    searchable
                    searchPlaceholder="Search areas"
                    onSelect={(value) => {
                        setSelectedArea(value);
                        setPickerOpen(false);
                    }}
                />
            </section>

            <section className="rounded-control border border-border-subtle p-4">
                <h2 className="font-medium">
                    Render an organization projection
                </h2>
                <div className="mt-4 h-[28rem]">
                    <NxOrgChart
                        items={[
                            {
                                id: "operations",
                                parentId: null,
                                label: "Operations",
                                description: "Seoul Plant",
                            },
                            {
                                id: "quality",
                                parentId: "operations",
                                label: "Quality",
                                members: [{ id: "min", label: "Min Kim" }],
                            },
                        ]}
                        labels={labels}
                        selectedId={selectedOrganizationId}
                        onSelect={setSelectedOrganizationId}
                    />
                </div>
            </section>
        </div>
    );
}