> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yoopta.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# CodeGroup

> Display multiple code files in tabbed interface

export const PluginPlayground = ({pluginSlug, height = 420}) => {
  const baseUrl = 'https://yoopta.dev';
  return <div className="not-prose my-6 rounded-xl border border-zinc-200 dark:border-zinc-800 overflow-hidden">
      <iframe title={`${pluginSlug} plugin demo`} src={`${baseUrl}/playground/plugin/${pluginSlug}`} className="w-full border-0 bg-white dark:bg-zinc-900" style={{
    height: typeof height === 'number' ? `${height}px` : height
  }} />
    </div>;
};

## Overview

The CodeGroup plugin allows you to create tabbed code blocks, perfect for showing the same code in different languages or displaying multiple related files. Each tab can have its own language and syntax highlighting.

<PluginPlayground pluginSlug="code-group" height={320} />

## Installation

```bash theme={null}
npm install @yoopta/code
```

## Basic Usage

Pass the plugin to `createYooptaEditor`; do not pass `plugins` to `<YooptaEditor>`.

```jsx theme={null}
import { useMemo } from 'react';
import YooptaEditor, { createYooptaEditor } from '@yoopta/editor';
import { CodeGroup } from '@yoopta/code';

const plugins = [CodeGroup];

export default function Editor() {
  const editor = useMemo(() => createYooptaEditor({ plugins, marks: [] }), []);
  return <YooptaEditor editor={editor} onChange={() => {}} />;
}
```

## Features

* **Multiple Tabs**: Display code in multiple tabs
* **Syntax Highlighting**: Powered by Shiki
* **Per-Tab Languages**: Each tab can have different language
* **Active Tab State**: Track which tab is active
* **Theme Support**: Consistent theming across tabs

## Structure

The CodeGroup plugin consists of nested elements:

```
code-group-container (props: activeTabId, theme)
├── code-group-list
│   └── code-group-item-heading (multiple tabs)
└── code-group-content (props: referenceId, language)
```

## Configuration

```jsx theme={null}
import { CodeGroup } from '@yoopta/code';

const plugins = [
  CodeGroup.extend({
    options: {
      theme: 'dracula',
    },
  }),
];
```

## Options

<ResponseField name="theme" type="string" default="github-dark">
  Shiki theme for all code blocks in the group
</ResponseField>

<ResponseField name="display" type="object">
  <Expandable title="properties">
    <ResponseField name="title" type="string" default="CodeGroup">
      Display title in UI
    </ResponseField>

    <ResponseField name="description" type="string">
      Description shown in menus
    </ResponseField>
  </Expandable>
</ResponseField>

## Element Props

### code-group-container

<ParamField path="activeTabId" type="string | null">
  ID of the currently active tab
</ParamField>

<ParamField path="theme" type="string" default="github-dark">
  Theme for all code blocks
</ParamField>

### code-group-content

<ParamField path="referenceId" type="string | null">
  ID linking content to its tab heading
</ParamField>

<ParamField path="language" type="string" default="typescript">
  Programming language for this code block
</ParamField>

## Commands

### addTabItem

Add a new tab to the code group.

```typescript theme={null}
import { CodeGroupCommands } from '@yoopta/code';

CodeGroupCommands.addTabItem(editor, blockId, { at: selection });
```

## Keyboard Behavior

* **Enter on Tab Heading**: Creates a new tab
* **Enter in Code Content**: Inserts newline (not a new block)
* **Backspace**: Prevents deletion at content start
* **Cmd/Ctrl+A**: Selects entire code content

## Initial Structure

When created, the plugin initializes with:

```typescript theme={null}
{
  'code-group-container': {
    activeTabId: 'generated-id',
    theme: 'github-dark',
  },
  tabs: [
    {
      heading: 'hello-world.ts',
      content: 'console.log("Hello World");',
      language: 'typescript',
    },
  ],
}
```

## Custom Rendering

```jsx theme={null}
import { CodeGroup } from '@yoopta/code';

const CustomCodeGroup = CodeGroup.extend({
  elements: {
    'code-group-container': {
      render: (props) => {
        const { activeTabId, theme } = props.element.props;

        return (
          <div className="my-code-group" data-theme={theme}>
            {props.children}
          </div>
        );
      },
    },
    'code-group-list': {
      render: (props) => (
        <div className="tabs-header" {...props.attributes}>
          {props.children}
        </div>
      ),
    },
    'code-group-item-heading': {
      render: (props) => {
        const isActive = props.element.id === getActiveTabId();

        return (
          <button className={`tab ${isActive ? 'active' : ''}`} {...props.attributes}>
            {props.children}
          </button>
        );
      },
    },
    'code-group-content': {
      render: (props) => {
        const { language } = props.element.props;

        return (
          <pre data-language={language} {...props.attributes}>
            {props.children}
          </pre>
        );
      },
    },
  },
});
```

## Use Cases

<CardGroup cols={2}>
  <Card title="Multi-Language Examples">Show same code in JavaScript, Python, Go, etc.</Card>
  <Card title="Related Files">Display multiple files that work together</Card>
  <Card title="Before/After">Show code before and after refactoring</Card>
  <Card title="API Responses">Different response formats (JSON, XML, etc.)</Card>
</CardGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Clear Tab Names">
    Use descriptive names for tabs (e.g., "package.json", "server.ts")
  </Accordion>

  <Accordion title="Consistent Languages">
    Group related code in logical language combinations
  </Accordion>

  <Accordion title="Limit Tabs">Keep number of tabs reasonable (2-5) for better UX</Accordion>

  <Accordion title="Match Content">
    Ensure code in different tabs is related or equivalent
  </Accordion>
</AccordionGroup>

## Related Plugins

* [Code Plugin](/plugins/code) - For single code blocks
* [Tabs Plugin](/plugins/tabs) - For general tabbed content
