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 cardselectedNodes: 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:
queryDatafor the current nodesstrategyfor pagination or infinite loading statecommands.nodefor per-node actionscommands.selectedNodesfor bulk actionsselectionto 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()anduseDriveViewConfig()when you are composing a custom grid, list, or hybrid Drive surface