Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions __tests__/e2e/markdown-extensions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,76 @@ export default config

:::

### Group Name Basic

::: code-group name=installs

```bash [npm]
npm install vitepress
```

```bash [pnpm]
pnpm add vitepress
```

:::

### Group Name Second Instance (Same Name for Sync Test)

::: code-group name=installs

```bash [npm]
npm run docs
```

```bash [pnpm]
pnpm run docs
```

:::

### Group Name with Hyphens and Underscores

::: code-group name=install_methods-v2

```bash [npm]
npm install vitepress@next
```

```bash [pnpm]
pnpm add vitepress@next
```

:::

### Group Name with Spaces (Should be Rejected)

::: code-group name="install methods"

```bash [npm]
npm install vitepress
```

```bash [yarn]
yarn add vitepress
```

:::

### Group Name with Invalid Characters (Should be Rejected)

::: code-group name=install@methods!

```bash [npm]
npm install vitepress
```

```bash [pnpm]
pnpm add vitepress
```

:::

## Markdown File Inclusion

<!--@include: ./foo.md-->
Expand Down
90 changes: 90 additions & 0 deletions __tests__/e2e/markdown-extensions/markdown-extensions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ describe('Table of Contents', () => {
"Code Groups",
"Basic Code Group",
"With Other Features",
"Group Name Basic",
"Group Name Second Instance (Same Name for Sync Test)",
"Group Name with Hyphens and Underscores",
"Group Name with Spaces (Should be Rejected)",
"Group Name with Invalid Characters (Should be Rejected)",
"Markdown File Inclusion",
"Region",
"Markdown At File Inclusion",
Expand Down Expand Up @@ -277,6 +282,91 @@ describe('Code Groups', () => {
await getClassList(blocks.nth(1).locator('code > span').nth(0))
).toContain('highlighted')
})

test('group-name basic', async () => {
const div = page.locator('#group-name-basic + div')

// Verify data attribute exists
const groupName = await div.getAttribute('data-group-name')
expect(groupName).toBe('installs')

// Verify tabs still work
const labels = div.locator('.tabs > label')
expect(await labels.count()).toBe(2)

// Verify clicking still switches tabs
await labels.nth(1).click()
const blocks = div.locator('.blocks > div')
expect(await getClassList(blocks.nth(1))).toContain('active')
})

test('group-name synchronization across groups', async () => {
// Clear localStorage to ensure clean test state
await page.evaluate(() => localStorage.clear())
await page.reload()
await page.waitForSelector('#group-name-basic + div')

const div1 = page.locator('#group-name-basic + div')
const div2 = page.locator(
'#group-name-second-instance-same-name-for-sync-test + div'
)

// Both groups should have the same group-name
expect(await div1.getAttribute('data-group-name')).toBe('installs')
expect(await div2.getAttribute('data-group-name')).toBe('installs')

// Initially, both should have first tab active
expect(await getClassList(div1.locator('.blocks > div').nth(0))).toContain(
'active'
)
expect(await getClassList(div2.locator('.blocks > div').nth(0))).toContain(
'active'
)

// Click second tab in first group
await div1.locator('.tabs > label').nth(1).click()

// Both groups should now have second tab active (synced)
expect(await getClassList(div1.locator('.blocks > div').nth(1))).toContain(
'active'
)
expect(await getClassList(div2.locator('.blocks > div').nth(1))).toContain(
'active'
)

// Click first tab in second group
await div2.locator('.tabs > label').nth(0).click()

// Both groups should now have first tab active again (synced back)
expect(await getClassList(div1.locator('.blocks > div').nth(0))).toContain(
'active'
)
expect(await getClassList(div2.locator('.blocks > div').nth(0))).toContain(
'active'
)
})

test('group-name with hyphens and underscores', async () => {
const div = page.locator('#group-name-with-hyphens-and-underscores + div')
const groupName = await div.getAttribute('data-group-name')
expect(groupName).toBe('install_methods-v2')
})

test('group-name with spaces should be rejected', async () => {
const div = page.locator('#group-name-with-spaces-should-be-rejected + div')
const groupName = await div.getAttribute('data-group-name')
// Quoted names with spaces should be rejected
expect(groupName).toBeNull()
})

test('group-name with invalid characters should be rejected', async () => {
const div = page.locator(
'#group-name-with-invalid-characters-should-be-rejected + div'
)
const groupName = await div.getAttribute('data-group-name')
// Should be rejected due to invalid characters
expect(groupName).toBeNull()
})
})

describe('Markdown File Inclusion', () => {
Expand Down
96 changes: 96 additions & 0 deletions docs/en/guide/markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,102 @@ You can also [import snippets](#import-code-snippets) in code groups:

:::

### Named Code Groups

You can name code groups to synchronize tab selections across multiple groups. When you have multiple code groups with the same name, selecting a tab in one will automatically select the corresponding tab in all other groups with the same name.

**Input**

````md
::: code-group name=package-managers

```bash [npm]
npm install vitepress
```

```bash [pnpm]
pnpm add vitepress
```

```bash [yarn]
yarn add vitepress
```

:::

<!-- Later in the same domain: -->

::: code-group name=package-managers

```bash [npm]
npm run docs
```

```bash [pnpm]
pnpm run docs
```

```bash [yarn]
yarn docs
```

:::
````

When you click on a tab (e.g., "pnpm") in one group, all other groups with `name=package-managers` will automatically switch to the same tab.

**Output**

::: code-group name=package-managers

```bash [npm]
npm install vitepress
```

```bash [pnpm]
pnpm add vitepress
```

```bash [yarn]
yarn add vitepress
```

:::

::: code-group name=package-managers

```bash [npm]
npm run docs
```

```bash [pnpm]
pnpm run docs
```

```bash [yarn]
yarn docs
```

:::

Try clicking different tabs above! Notice how both code groups switch together because they share the same `name`.

::: info
Your tab selection is automatically saved to localStorage. When you return to the page, your preferred tab for each name will be automatically selected.
:::

The `name` parameter accepts only alphanumeric characters, hyphens, and underscores. No whitespace is allowed.

Valid examples:
- `name=installs`
- `name=install-methods`
- `name=install_methods`
- `name=installMethods`

::: tip
This feature is especially useful in documentation where you show the same tool (like package managers or programming languages) in multiple places, providing a consistent experience for users.
:::

## Markdown File Inclusion

You can include a markdown file in another markdown file, even nested.
Expand Down
98 changes: 98 additions & 0 deletions docs/es/guide/markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,104 @@ También puede [importar _snippets_ de código](#import-code-snippets) en grupos

:::

<!-- TODO: Translate to Spanish -->
### Named Code Groups

You can name code groups to synchronize tab selections across multiple groups. When you have multiple code groups with the same name, selecting a tab in one will automatically select the corresponding tab in all other groups with the same name.

**Input**

````md
::: code-group name=package-managers

```bash [npm]
npm install vitepress
```

```bash [pnpm]
pnpm add vitepress
```

```bash [yarn]
yarn add vitepress
```

:::

<!-- Later in the same domain: -->

::: code-group name=package-managers

```bash [npm]
npm run docs
```

```bash [pnpm]
pnpm run docs
```

```bash [yarn]
yarn docs
```

:::
````

When you click on a tab (e.g., "pnpm") in one group, all other groups with `name=package-managers` will automatically switch to the same tab.

**Output**

::: code-group name=package-managers

```bash [npm]
npm install vitepress
```

```bash [pnpm]
pnpm add vitepress
```

```bash [yarn]
yarn add vitepress
```

:::

::: code-group name=package-managers

```bash [npm]
npm run docs
```

```bash [pnpm]
pnpm run docs
```

```bash [yarn]
yarn docs
```

:::

Try clicking different tabs above! Notice how both code groups switch together because they share the same `name`.

::: info
Your tab selection is automatically saved to localStorage. When you return to the page, your preferred tab for each name will be automatically selected.
:::

The `name` parameter accepts only alphanumeric characters, hyphens, and underscores. No whitespace is allowed.

Valid examples:
- `name=installs`
- `name=install-methods`
- `name=install_methods`
- `name=installMethods`

::: tip
This feature is especially useful in documentation where you show the same tool (like package managers or programming languages) in multiple places, providing a consistent experience for users.
:::
<!-- END TODO: Translate to Spanish -->

## Inclusión de Archivo Markdown {#markdown-file-inclusion}

Puede incluir un archivo markdown en otro archvo markdown, incluso anidado.
Expand Down
Loading