Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/IzumiSy/seizen-table/llms.txt

Use this file to discover all available pages before exploring further.

Seizen Table’s plugin system allows you to add custom UI components and functionality using a slot-based architecture. Plugins can render in multiple locations (slots) and integrate seamlessly with the table.

Plugin Architecture

Available Slots

Plugins can render components in these slots:
SlotDescriptionUse Cases
side-panelIDE-style vertical tab panel (left or right)Details, inspectors, navigation, bulk actions
headerBetween table header and body rowsSearch bars, filters, toolbars
footerBelow the tablePagination, summary statistics
cellCustom cell renderer for all columnsSpecial formatting, interactive cells
inline-rowBelow a specific row when openedRow details, nested data

Plugin Types

Seizen Table plugins are defined using TypeScript with full type safety:
import type { SeizenTablePlugin } from "@izumisy/seizen-table/plugin";

interface SeizenTablePlugin<TData = unknown> {
  id: string;                              // Unique plugin identifier
  name: string;                            // Display name (used in vertical tabs)
  slots: PluginSlots<TData>;              // Slot configurations
  contextMenuItems?: ContextMenuItemsSlot; // Context menu items
  _args?: unknown;                         // Plugin configuration (internal)
}

Creating a Plugin with definePlugin

The definePlugin function creates type-safe plugins with configuration validation using Zod schemas.

Basic Plugin Structure

1

Import dependencies

import { z } from "zod";
import { definePlugin, usePluginContext } from "@izumisy/seizen-table/plugin";
2

Define configuration schema

const MyPluginSchema = z.object({
  enableFeature: z.boolean().default(true),
  customLabel: z.string().optional(),
});
3

Create the plugin

const MyPlugin = definePlugin({
  id: "my-plugin",
  name: "My Plugin",
  args: MyPluginSchema,
  slots: {
    sidePanel: {
      position: "right-sider",
      render: () => <MyPluginPanel />,
    },
  },
});
4

Use the plugin

<SeizenTable
  plugins={[
    MyPlugin.configure({ enableFeature: true, customLabel: "Custom" })
  ]}
/>

Complete Plugin Example: Bulk Actions

Here’s a complete example of a side panel plugin with configuration:
import { z } from "zod";
import { definePlugin, usePluginContext, usePluginArgs } from "@izumisy/seizen-table/plugin";

// 1. Define configuration schema
const BulkActionsSchema = z.object({
  enableDelete: z.boolean().default(true),
  enableExport: z.boolean().default(true),
});

// 2. Create the panel component
function BulkActionsPanel() {
  const { selectedRows } = usePluginContext();
  const args = usePluginArgs<z.infer<typeof BulkActionsSchema>>();

  if (selectedRows.length === 0) {
    return <div className="p-4 text-gray-500">No rows selected</div>;
  }

  return (
    <div className="p-4 space-y-2">
      <div className="font-semibold">{selectedRows.length} rows selected</div>
      
      {args.enableDelete && (
        <button className="w-full btn-danger" onClick={() => handleDelete(selectedRows)}>
          Delete Selected
        </button>
      )}
      
      {args.enableExport && (
        <button className="w-full btn-primary" onClick={() => handleExport(selectedRows)}>
          Export Selected
        </button>
      )}
    </div>
  );
}

// 3. Define the plugin
const BulkActions = definePlugin({
  id: "bulk-actions",
  name: "Bulk Actions",
  args: BulkActionsSchema,
  slots: {
    sidePanel: {
      position: "right-sider",
      header: "Bulk Actions",
      render: () => <BulkActionsPanel />,
    },
  },
});

// 4. Usage
function App() {
  return (
    <SeizenTable
      data={users}
      columns={columns}
      plugins={[
        BulkActions.configure({ 
          enableDelete: true,
          enableExport: false 
        })
      ]}
    />
  );
}

Plugin Context and Hooks

usePluginContext

Access table state and methods from within plugin components:
import { usePluginContext } from "@izumisy/seizen-table/plugin";

function MyPluginComponent() {
  const context = usePluginContext();
  
  // Available context:
  context.selectedRows;        // Currently selected rows
  context.table;              // TanStack Table instance
  // ... and more
}

usePluginArgs

Access validated plugin configuration inside render functions:
import { usePluginArgs } from "@izumisy/seizen-table/plugin";

function MyPluginPanel() {
  const args = usePluginArgs<z.infer<typeof MyPluginSchema>>();
  
  return <div>{args.customLabel}</div>;
}

Slot Types Reference

SidePanel Slot

interface SidePanelSlot {
  position: "left-sider" | "right-sider";
  header?: string | ReactNode;
  render: () => ReactNode;
}
Example:
sidePanel: {
  position: "right-sider",
  header: "Details",
  render: () => <DetailsPanel />,
}

Header Slot

interface HeaderSlot {
  render: () => ReactNode;
}
Example:
header: {
  render: () => <SearchBar />,
}
interface FooterSlot {
  render: () => ReactNode;
}
Example:
footer: {
  render: () => <Pagination />,
}

Cell Slot

interface CellSlot<TData = unknown> {
  render: (
    cell: Cell<TData, unknown>,
    column: Column<TData, unknown>,
    row: Row<TData>
  ) => ReactNode;
}
Example:
cell: {
  render: (cell, column, row) => {
    if (column.id === "status") {
      return <StatusBadge status={cell.getValue()} />;
    }
    return flexRender(cell.column.columnDef.cell, cell.getContext());
  },
}

InlineRow Slot

interface InlineRowSlot<TData = unknown> {
  render: (row: Row<TData>) => ReactNode;
}
Example:
inlineRow: {
  render: (row) => <UserDetails user={row.original} />,
}

Multiple Slots Example

A plugin can use multiple slots:
const AdvancedPlugin = definePlugin({
  id: "advanced",
  name: "Advanced Features",
  args: z.object({}),
  slots: {
    sidePanel: {
      position: "right-sider",
      render: () => <AdvancedPanel />,
    },
    header: {
      render: () => <AdvancedToolbar />,
    },
    footer: {
      render: () => <AdvancedStats />,
    },
  },
});

Plugin Configuration Best Practices

Use Zod defaults: Provide sensible defaults in your schema so plugins work out of the box.
z.object({
  enabled: z.boolean().default(true),
  position: z.enum(["top", "bottom"]).default("top"),
})
Validate configuration: Always use Zod schemas to validate plugin configuration. This prevents runtime errors and provides better DX with TypeScript.

Exported Plugin Types

The plugin API exports these types from @izumisy/seizen-table/plugin:
// Core plugin types
export type {
  SeizenTablePlugin,
  PluginContext,
  PluginPosition,
  
  // Slot types
  SlotType,
  PluginSlots,
  SidePanelSlot,
  HeaderSlot,
  FooterSlot,
  CellSlot,
  InlineRowSlot,
  ContextMenuItemsSlot,
  
  // Define options
  DefinePluginOptions,
  DefinePluginSlots,
  DefineSlotPluginOptions,
};

// Core plugin functions
export {
  definePlugin,
  hasSidePanelSlot,
  getSidePanelSlot,
};

Next Steps

Context Menu

Add context menu items to your plugins

Custom Rendering

Take full control of table rendering