Tulip Logo IconTulip
Storage

Drive

Build Drive views on top of Storage with shared table config and command slots.

Tulip Drive builds a file-manager-style experience on top of Storage. The low-level client view helpers live in @tulip-systems/drive/client and are useful when you want to compose your own Drive layouts while reusing Tulip's table config and command wiring.

Entry point

import {
  createDriveViewConfig,
  type DriveViewCommands,
  DriveViewConfigProvider,
  useDriveViewConfig,
} from "@tulip-systems/drive/client";

What these APIs solve

Drive views usually need two command contexts at once:

  • node: commands for a single file or folder card
  • selectedNodes: commands for the current multi-selection

createDriveViewConfig() keeps those command slots together with the shared table config that powers list and grid views.

createDriveViewConfig()

Use createDriveViewConfig() to assemble the shared config for a Drive screen.

import type { VisibilityState } from "@tanstack/react-table";
import type { TableColumnDef } from "@tulip-systems/core/data-tables";
import type { useInfiniteStrategy } from "@tulip-systems/core/data-tables/client";
import {
  createDriveViewConfig,
  type DriveViewCommands,
} from "@tulip-systems/drive/client";

type Node = { id: string; name: string; hidden?: boolean };

function createConfig({
  queryData,
  columns,
  strategy,
  commands,
  columnVisibility,
}: {
  queryData: Node[];
  columns: TableColumnDef<Node>[];
  strategy: ReturnType<typeof useInfiniteStrategy>;
  commands?: DriveViewCommands<Node>;
  columnVisibility?: VisibilityState;
}) {
  return createDriveViewConfig<Node>({
    queryData,
    columns,
    strategy,
    commands,
    columnVisibility,
  });
}

The returned config includes the normal table state plus the Drive-specific command slots.

DriveViewConfigProvider

Wrap your custom Drive layout with DriveViewConfigProvider so child components can read the shared config.

function DriveViewShell({ config, children }: { config: ReturnType<typeof createConfig>; children: React.ReactNode }) {
  return <DriveViewConfigProvider config={config}>{children}</DriveViewConfigProvider>;
}

Internally, the provider also forwards selectedNodes into Tulip's table command context. That makes bulk action menus work without duplicating selection wiring.

useDriveViewConfig()

Use useDriveViewConfig() inside list or grid components to read the assembled state.

function DriveGrid() {
  const { queryData, commands, selection, meta } = useDriveViewConfig<{
    id: string;
    name: string;
  }>();

  const selectedData = queryData.filter((node) => selection?.rowSelection?.[node.id] === true);

  return (
    <>
      {queryData.map((node) => (
        <div key={node.id}>{node.name}</div>
      ))}

      {commands?.selectedNodes && selectedData.length > 0 && (
        <div>{meta ? "bulk commands available" : "bulk commands available"}</div>
      )}
    </>
  );
}

In practice, custom views usually read:

  • queryData for the current nodes
  • strategy for pagination or infinite loading state
  • commands.node for per-node actions
  • commands.selectedNodes for bulk actions
  • selection to derive the selected node list

When to use this layer

  • use the built-in Drive providers when Tulip's default view structure already fits
  • use createDriveViewConfig() and useDriveViewConfig() when you are composing a custom grid, list, or hybrid Drive surface

On this page