or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli.mdconfiguration.mdindex.mdplugins.mdtheme-api.mdutilities.md
tile.json

plugins.mddocs/

Plugin System

Plugin architecture for extending dumi functionality with custom tech stacks, content tabs, and asset processing through a comprehensive API system.

Capabilities

Tech Stack Registration

Register custom technology stacks for supporting additional frameworks beyond React.

/**
 * Register a new tech stack for parsing and rendering demos
 * @param fn - Function returning tech stack implementation
 */
interface IApi {
  registerTechStack: (fn: () => IDumiTechStack) => void;
}

/**
 * Abstract base class for implementing custom tech stacks
 */
abstract class IDumiTechStack {
  /** Tech stack name (e.g., 'react', 'vue', 'angular') */
  abstract name: string;
  
  /** Runtime options for browser rendering */
  abstract runtimeOpts?: {
    /** Path to component detection function */
    preflightPath?: string;
    /** Path to render/unmount function */
    rendererPath?: string;
    /** Path to runtime compile function */
    compilePath?: string;
    /** Path to runtime plugin */
    pluginPath?: string;
  };
  
  /**
   * Check if language/node is supported by this tech stack
   * @param node - HAST element node
   * @param lang - Code block language
   * @returns Whether this tech stack can handle the code
   */
  abstract isSupported(node: Element, lang: string): boolean;
  
  /**
   * Transform demo source code for compilation
   * @param raw - Raw source code
   * @param opts - Transformation options
   * @returns Transformed code ready for compilation
   */
  abstract transformCode(raw: string, opts: {
    type: 'external' | 'code-block';
    fileAbsPath: string;
  }): string;
  
  /**
   * Generate asset metadata for the demo
   * @param asset - Base asset data
   * @param opts - Generation context
   * @returns Enhanced asset metadata
   */
  abstract generateMetadata?(
    asset: ExampleBlockAsset,
    opts: {
      type: 'external' | 'code-block';
      mdAbsPath: string;
      fileAbsPath?: string;
      entryPointCode?: string;
    }
  ): Promise<ExampleBlockAsset> | ExampleBlockAsset;
  
  /**
   * Generate previewer component props
   * @param props - Base previewer props
   * @param opts - Generation context
   * @returns Enhanced previewer props
   */
  abstract generatePreviewerProps?(
    props: IDumiDemoProps['previewerProps'],
    opts: {
      type: 'external' | 'code-block';
      mdAbsPath: string;
      fileAbsPath?: string;
      entryPointCode?: string;
    }
  ): Promise<IDumiDemoProps['previewerProps']> | IDumiDemoProps['previewerProps'];
  
  /**
   * Transform code using esbuild onLoad callback
   * @param args - esbuild onLoad arguments
   * @returns Transformed code result or null to skip
   */
  abstract onBlockLoad?(args: {
    path: string;
    namespace?: string;
    suffix?: string;
    pluginData?: any;
    entryPointCode: string;
    filename: string;
  }): { content: string; loader: string } | null;
}

Usage:

// Vue.js tech stack implementation
export default (api: IApi) => {
  api.registerTechStack(() => ({
    name: 'vue',
    
    isSupported(node, lang) {
      return ['vue', 'vue3'].includes(lang);
    },
    
    transformCode(raw, { type, fileAbsPath }) {
      // Transform Vue SFC to executable code
      return `
        import { createApp } from 'vue';
        
        const component = ${raw};
        
        export default () => {
          const app = createApp(component);
          return app;
        };
      `;
    },
    
    runtimeOpts: {
      rendererPath: require.resolve('./vue-renderer'),
      compilePath: require.resolve('./vue-compiler'),
    },
  }));
};

Content Tab System

Add custom content tabs for enhanced page functionality.

/**
 * Add a content tab to documentation pages
 * @param fn - Function returning tab configuration
 */
interface IApi {
  addContentTab: (fn: () => IContentTab) => void;
}

interface IContentTab {
  /** Unique tab key and URL query parameter */
  key: string;
  /** Optional unique ID for tab conflicts */
  id?: string;
  /** Route pattern to apply tab (regex) */
  test?: RegExp;
  /** Tab display title */
  title?: string;
  /** Internationalization key for title */
  titleIntlId?: string;
  /** Path to tab React component */
  component: string;
}

Usage:

// Add playground tab for interactive demos
export default (api: IApi) => {
  api.addContentTab(() => ({
    key: 'playground',
    test: /\/components\//,
    title: 'Playground',
    component: require.resolve('./PlaygroundTab'),
  }));
};

// PlaygroundTab.tsx
import React from 'react';
import { useRouteMeta, useLiveDemo } from 'dumi/theme';

export default function PlaygroundTab() {
  const routeMeta = useRouteMeta();
  const { renderDemo } = useLiveDemo();
  
  return (
    <div>
      <h2>Interactive Playground</h2>
      {/* Custom playground implementation */}
    </div>
  );
}

Asset Metadata Management

Modify and access component/demo asset metadata.

/**
 * Modify assets metadata during build process
 * @param fn - Function to transform assets data
 */
interface IApi {
  modifyAssetsMetadata: (fn: (memo: AssetsPackage, args: null) => AssetsPackage) => void;
}

/**
 * Get current assets metadata (available during build)
 * @returns Promise resolving to complete assets package
 */
interface IApi {
  getAssetsMetadata?: () => Promise<AssetsPackage>;
}

interface AssetsPackage {
  /** Package name */
  name: string;
  /** Package version */
  version: string;
  /** Package description */
  description?: string;
  /** Package homepage */
  homepage?: string;
  /** Package keywords */
  keywords?: string[];
  /** Component/function assets */
  assets: {
    /** Atom assets by ID */
    atoms: Record<string, AtomAsset>;
    /** Example assets by ID */
    examples: Record<string, ExampleBlockAsset>;
  };
}

Usage:

// Enhance asset metadata with custom information
export default (api: IApi) => {
  api.modifyAssetsMetadata((assets) => {
    // Add custom package information
    assets.name = 'My Design System';
    assets.homepage = 'https://my-design-system.com';
    
    // Enhance component metadata
    Object.values(assets.assets.atoms).forEach((atom) => {
      if (atom.type === 'COMPONENT') {
        // Add design system category
        atom.category = getComponentCategory(atom.id);
        
        // Add accessibility information
        atom.a11y = getA11yInfo(atom.id);
      }
    });
    
    return assets;
  });
  
  // Access metadata during build
  api.onBuildComplete(async () => {
    const assets = await api.getAssetsMetadata?.();
    
    // Generate additional documentation files
    generateComponentCatalog(assets);
    generateA11yReport(assets);
  });
};

Theme Modification

Modify theme components and configuration.

/**
 * Modify theme data including components, layouts, and locales
 * @param fn - Function to transform theme data
 */
interface IApi {
  modifyTheme: (fn: (memo: IThemeLoadResult, args: null) => IThemeLoadResult) => void;
}

interface IThemeLoadResult {
  /** Built-in components (API, Badge, etc.) */
  builtins: Record<string, string>;
  /** Layout components (DocLayout, etc.) */
  layouts: Record<string, string>;
  /** Slot components (Header, Footer, etc.) */
  slots: Record<string, string>;
  /** Internationalization messages */
  locales: Record<string, {
    messages: Record<string, string>;
  }>;
  /** Global style files */
  globalStyles: string[];
  /** Custom theme configuration */
  [key: string]: any;
}

Usage:

// Customize theme with additional components and styling
export default (api: IApi) => {
  api.modifyTheme((memo) => {
    // Add custom built-in components
    memo.builtins.CustomAPI = require.resolve('./components/CustomAPI');
    memo.builtins.DesignTokens = require.resolve('./components/DesignTokens');
    
    // Override default slots
    memo.slots.Header = require.resolve('./components/CustomHeader');
    memo.slots.Footer = require.resolve('./components/CustomFooter');
    
    // Add custom internationalization
    memo.locales.en.messages.customWelcome = 'Welcome to our design system';
    memo.locales.zh.messages.customWelcome = '欢迎使用我们的设计系统';
    
    // Add global styles
    memo.globalStyles.push(require.resolve('./styles/custom.less'));
    
    return memo;
  });
};

Plugin Development Utilities

Utilities for building robust plugins.

/**
 * Plugin API interface extending Umi's plugin system
 */
interface IApi extends IUmiApi {
  /** Dumi-specific configuration */
  config: IDumiConfig & { [key: string]: any };
  /** User configuration */
  userConfig: IDumiUserConfig;
  /** Enhanced service with theme and parser data */
  service: IUmiApi['service'] & {
    themeData: IThemeLoadResult;
    atomParser: IAtomAssetsParser;
  };
}

/**
 * Language metadata parser for API documentation
 */
interface ILanguageMetaParser {
  /** Language identifier */
  language: string;
  /** Parse component/function metadata */
  parse(code: string, options: {
    filename: string;
    entryFile?: string;
  }): Promise<AtomAsset[]>;
}

/**
 * Options for creating API parsers
 */
interface IBaseApiParserOptions {
  /** Entry file for parsing */
  entryFile?: string;
  /** Custom resolver function */
  resolveFilter?: (args: {
    id: string;
    type: 'COMPONENT' | 'FUNCTION';
  }) => boolean;
}

Usage:

// Advanced plugin with custom API parser
export default (api: IApi) => {
  api.describe({ key: 'custom-plugin' });
  
  // Register custom methods
  api.registerMethod({ name: 'addCustomTab' });
  api.registerMethod({ name: 'enhanceMetadata' });
  
  // Hook into lifecycle events
  api.onStart(() => {
    console.log('Plugin starting...');
  });
  
  api.onBuildComplete(() => {
    console.log('Build completed, running custom tasks...');
  });
  
  // Access service data
  const { themeData, atomParser } = api.service;
  
  // Custom parsing logic
  api.modifyConfig((memo) => {
    memo.resolve.entryFile = './src/custom-entry.ts';
    return memo;
  });
};

Plugin Examples

Design System Plugin

// Complete design system enhancement plugin
export default (api: IApi) => {
  api.describe({ key: 'design-system-plugin' });
  
  // Add design tokens tab
  api.addContentTab(() => ({
    key: 'tokens',
    title: 'Design Tokens',
    component: require.resolve('./DesignTokensTab'),
  }));
  
  // Enhance theme with design system components
  api.modifyTheme((memo) => {
    memo.builtins.TokenTable = require.resolve('./TokenTable');
    memo.builtins.ColorPalette = require.resolve('./ColorPalette');
    memo.builtins.Typography = require.resolve('./Typography');
    return memo;
  });
  
  // Add design system metadata
  api.modifyAssetsMetadata((assets) => {
    assets.designSystem = {
      tokens: loadDesignTokens(),
      guidelines: loadDesignGuidelines(),
    };
    return assets;
  });
};

Multi-framework Support Plugin

// Plugin supporting React, Vue, and Angular
export default (api: IApi) => {
  // Register Vue tech stack
  api.registerTechStack(() => new VueTechStack());
  
  // Register Angular tech stack  
  api.registerTechStack(() => new AngularTechStack());
  
  // Add framework selector tab
  api.addContentTab(() => ({
    key: 'frameworks',
    title: 'Frameworks',
    component: require.resolve('./FrameworkSelector'),
  }));
};

class VueTechStack extends IDumiTechStack {
  name = 'vue';
  
  isSupported(node, lang) {
    return lang === 'vue';
  }
  
  transformCode(raw, opts) {
    return compileVueComponent(raw, opts);
  }
}

Analytics Plugin

// Plugin for tracking component usage and demos
export default (api: IApi) => {
  api.describe({ key: 'analytics-plugin' });
  
  // Track component views
  api.modifyTheme((memo) => {
    memo.builtins.TrackingPreviewer = require.resolve('./TrackingPreviewer');
    return memo;
  });
  
  // Generate usage reports
  api.onBuildComplete(async () => {
    const assets = await api.getAssetsMetadata?.();
    generateUsageReport(assets);
  });
};