or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

category-organization.mdcomponent-bundling.mdcomponent-documentation.mdcontent-loading.mdindex.mdtheme-engine.mdtypedef-import.mdtypescript-support.md
tile.json

component-documentation.mddocs/

Component Documentation

Live preview system for React and Vue components with automatic prop extraction and interactive examples.

Capabilities

React Component Parsing

Extracts metadata from React components including props, types, and default values.

/**
 * Parses React component and extracts metadata
 * @param {string} filePath - Path to the React component file
 * @param {Object} doclet - JSDoc doclet containing component information
 * @returns {ComponentMetadata} Component metadata with props and display information
 */
function parseReact(filePath: string, doclet: Object): ComponentMetadata;

interface ComponentMetadata {
  /** Component display name */
  displayName: string;
  /** Path to component file */
  filePath: string;
  /** Component props information */
  props: PropInfo[];
  /** Component type (react or vue) */
  type: 'react' | 'vue';
  /** Vue-specific slots (only for Vue components) */
  slots?: SlotInfo[];
}

interface PropInfo {
  /** Property name */
  name: string;
  /** Property description from PropTypes or JSDoc */
  description?: string;
  /** Property type (string, number, boolean, etc.) */
  type: string;
  /** Whether the property is required */
  required: boolean;
  /** Default value if specified */
  defaultValue?: string;
}

Usage Example:

const { parseReact } = require('better-docs/component');

// Document a React component with @component tag
/**
 * Button component with customizable styling
 * @component
 * @example
 * return <Button variant="primary" size="large">Click me</Button>
 */
const Button = ({ variant = 'default', size = 'medium', children, onClick }) => {
  return (
    <button 
      className={`btn btn-${variant} btn-${size}`}
      onClick={onClick}
    >
      {children}
    </button>
  );
};

Button.propTypes = {
  variant: PropTypes.oneOf(['default', 'primary', 'secondary']),
  size: PropTypes.oneOf(['small', 'medium', 'large']),
  children: PropTypes.node.isRequired,
  onClick: PropTypes.func
};

Vue Component Parsing

Extracts metadata from Vue components including props, slots, and component options.

/**
 * Parses Vue component and extracts metadata
 * @param {string} filePath - Path to the Vue component file
 * @param {Object} doclet - JSDoc doclet containing component information
 * @returns {ComponentMetadata} Component metadata with props, slots, and display information
 */
function parseVue(filePath: string, doclet: Object): ComponentMetadata;

interface SlotInfo {
  /** Slot name */
  name: string;
  /** Slot description */
  description?: string;
}

Usage Example:

<script>
/**
 * Card component with header and footer slots
 * @component
 * @example
 * <Card title="My Card">
 *   <template #header>Custom Header</template>
 *   <p>Card content goes here</p>
 *   <template #footer>Card footer</template>
 * </Card>
 */
export default {
  name: 'Card',
  props: {
    title: {
      type: String,
      required: true,
      default: 'Default Title'
    },
    variant: {
      type: String,
      default: 'default',
      validator: value => ['default', 'primary', 'secondary'].includes(value)
    }
  }
}
</script>

Component Event Handlers

JSDoc event handlers for processing component documentation.

interface ComponentHandlers {
  /**
   * Processes Vue single-file components before parsing
   * @param {Object} e - Parse event
   */
  beforeParse(e: ParseEvent): void;
  
  /**
   * Processes doclets to handle @component tags
   * @param {Object} docletEvent - Doclet event with component information
   */
  newDoclet(docletEvent: DocletEvent): void;
}

interface ParseEvent {
  filename: string;
  source: string;
  componentInfo?: ComponentInfo;
}

interface DocletEvent {
  doclet: {
    tags?: Array<{
      title: string;
      value?: string;
    }>;
    component?: ComponentMetadata;
    kind?: string;
    memberof?: string;
    undocumented?: boolean;
  };
}

interface ComponentInfo {
  displayName: string;
  props?: Object;
  slots?: Object;
}

React Component Wrapper

Provides iframe-based rendering and code editing for React component previews.

/**
 * React wrapper component factory for live previews
 * @param {Object} props - Component props including example code and unique ID
 * @returns {React.Component} Wrapper component instance
 */
function ReactWrapper(props: WrapperProps): React.Component;

interface WrapperProps {
  /** Unique identifier for the component instance */
  uniqId: string;
  /** Example code to render */
  example?: string;
}

class Wrapper extends React.Component {
  constructor(props: WrapperProps);
  
  /**
   * Executes JavaScript code for component rendering
   * @param {string} source - JavaScript source code
   */
  executeScript(source: string): void;
  
  /**
   * Handles code changes in the editor
   * @param {string} code - Updated code
   */
  handleChange(code: string): void;
  
  /**
   * Computes iframe height based on content
   */
  computeHeight(): void;
  
  /**
   * Toggles code editor visibility
   * @param {Event} event - Click event
   */
  toggleEditor(event: Event): void;
  
  render(): React.Element;
}

Vue Component Wrapper

Provides component rendering and code editing for Vue component previews.

/**
 * Vue wrapper component definition for live previews
 */
interface VueWrapper {
  /** Vue component template */
  template: string;
  /** Component props definition */
  props: {
    defaultCode: StringConstructor;
  };
  /** Component data factory */
  data(): {
    code: string;
    userComponent: Object;
    isActive: boolean;
  };
  /** Child components */
  components: {
    editor: Object;
  };
  /** Lifecycle and utility methods */
  methods: {
    toggleEditor(): void;
    editorInit(): void;
    renderComponent(originalCode?: string): Object;
  };
}

Component Example Patterns

React Component with Examples

/**
 * Alert component for displaying messages
 * @component
 * @example <caption>Basic alert</caption>
 * return <Alert type="info">This is an informational message</Alert>
 * 
 * @example <caption>Error alert</caption>
 * return <Alert type="error">Something went wrong!</Alert>
 * 
 * @example <caption>Custom styling</caption>
 * return (
 *   <Alert 
 *     type="success" 
 *     dismissible={true}
 *     onDismiss={() => console.log('Alert dismissed')}
 *   >
 *     Operation completed successfully!
 *   </Alert>
 * )
 */
const Alert = ({ type, children, dismissible, onDismiss }) => {
  return (
    <div className={`alert alert-${type}`}>
      {children}
      {dismissible && (
        <button onClick={onDismiss} className="alert-close">×</button>
      )}
    </div>
  );
};

Alert.propTypes = {
  type: PropTypes.oneOf(['info', 'success', 'warning', 'error']).isRequired,
  children: PropTypes.node.isRequired,
  dismissible: PropTypes.bool,
  onDismiss: PropTypes.func
};

Vue Component with Examples

<script>
/**
 * Progress bar component
 * @component
 * @example <caption>Basic progress bar</caption>
 * <ProgressBar :value="50" :max="100" />
 * 
 * @example <caption>With custom styling</caption>
 * <ProgressBar 
 *   :value="75" 
 *   :max="100" 
 *   color="success"
 *   :show-percentage="true"
 * />
 * 
 * @example <caption>Multiple progress bars</caption>
 * {
 *   template: `
 *     <div>
 *       <ProgressBar :value="30" label="CPU Usage" />
 *       <ProgressBar :value="60" label="Memory Usage" color="warning" />
 *       <ProgressBar :value="90" label="Disk Usage" color="danger" />
 *     </div>
 *   `
 * }
 */
export default {
  name: 'ProgressBar',
  props: {
    value: {
      type: Number,
      required: true
    },
    max: {
      type: Number,
      default: 100
    },
    color: {
      type: String,
      default: 'primary',
      validator: value => ['primary', 'success', 'warning', 'danger'].includes(value)
    },
    showPercentage: {
      type: Boolean,
      default: false
    },
    label: {
      type: String
    }
  }
}
</script>

Component Mixing

You can use multiple documented components together in examples:

/**
 * Modal dialog component
 * @component
 * @example <caption>Modal with alert inside</caption>
 * return (
 *   <Modal isOpen={true} title="Confirm Action">
 *     <Alert type="warning">
 *       Are you sure you want to delete this item?
 *     </Alert>
 *     <Button variant="danger">Delete</Button>
 *     <Button variant="secondary">Cancel</Button>
 *   </Modal>
 * )
 */
const Modal = ({ isOpen, title, children, onClose }) => {
  if (!isOpen) return null;
  
  return (
    <div className="modal-overlay">
      <div className="modal">
        <div className="modal-header">
          <h3>{title}</h3>
          <button onClick={onClose}>×</button>
        </div>
        <div className="modal-body">
          {children}
        </div>
      </div>
    </div>
  );
};

Configuration

Enable component documentation in JSDoc configuration:

{
  "tags": {
    "allowUnknownTags": ["component"]
  },
  "plugins": [
    "node_modules/better-docs/component"
  ],
  "templates": {
    "better-docs": {
      "component": {
        "wrapper": "./path/to/wrapper-component.js",
        "entry": [
          "import 'babel-polyfill';",
          "import 'bulma/css/bulma.css';"
        ]
      }
    }
  }
}

Custom Wrapper Component

For React components that need specific context (Redux, Router, etc.):

// wrapper-component.js
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './store';

const WrapperComponent = ({ children }) => {
  return (
    <Provider store={store}>
      <BrowserRouter>
        <div className="component-preview">
          {children}
        </div>
      </BrowserRouter>
    </Provider>
  );
};

export default WrapperComponent;

Dependencies

The component plugin requires:

  • parcel-bundler - For bundling component previews
  • react and react-dom (peer dependencies for React components)
  • vue (for Vue components)
  • react-docgen - For parsing React PropTypes
  • vue-docgen-api - For parsing Vue component definitions