Skip to content
Merged
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
8 changes: 8 additions & 0 deletions .github/contributing/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ links:
---
```

Optional `keywords` feed the docs search and the MCP `search-components` tool. Use alternate names from other ecosystems, not words already in the title or description:

```yaml
keywords:
- segmented control
- button group
```

For Reka UI based components, add the Reka UI link:

```yaml
Expand Down
2 changes: 1 addition & 1 deletion .sync/dep-parity.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$note": "Upstream's pinned versions for every dependency both trees declare in the SAME section, snapshotted at `cursor`. The sync ports deltas, which is correct per commit and lets a one-time divergence become permanent: once a version is off upstream's line, every later `chore(deps)` batch skips it, because those ports bump only where this fork already matched upstream's pre-image. `prettier` sat at ^3.8.4 against upstream's ^3.9.6 for that reason, through four ported batches, until this file was written. Section-aware on purpose: 18 packages are declared on both sides but in different sections — the whole `@tiptap/*` family is a peer `^3` upstream and a dependency `^3.29.2` here, and `ai` is a peer there and a devDependency here. Those are structural divergences, not drift, and comparing a peer range against a dependency range says nothing. They are absent from this file by construction rather than by omission. Guarded by `test/utils/dep-parity.spec.ts`. Refresh with `node .sync/dep-parity.mjs <path-to-nuxt-ui-mirror> [cursor]`, which preserves `exceptions`.",
"cursor": "dd4bc8e85365d45190716655430835906e5acef6",
"cursor": "c6a756c57c71dee553f75a0e84f159e3baf07d5c",
"manifests": {
"package.json": {
"dependencies": {
Expand Down
107 changes: 107 additions & 0 deletions .sync/log/c6a756c57c71dee553f75a0e84f159e3baf07d5c.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Port: docs: fix broken links and outdated content

**Upstream:** `c6a756c57c71dee553f75a0e84f159e3baf07d5c` (nuxt/ui, #6867)
**Decision:** port — everything applicable, by maintainer decision

## Upstream change

101 files, +490/−248. A docs sweep mixing four different things: broken-link
fixes, front-matter `keywords` for docs search and the MCP `search-components`
tool, corrections where the documented API had drifted from the code, and
editorial rewording.

## Method

Applying the patch whole fails — our docs diverge too far. Instead it was applied
**hunk by hunk**: 154 hunks, each tried on its own. A hunk that applies proves
our text equalled upstream's pre-image, which is the only case where copying is
safe by construction.

- **47 hunks applied** cleanly.
- **107 rejected** — our text differs. Each was then judged on intent, not text.

The 15 files we lack (Carousel, Marquee, PricingTable, ChangelogVersion, Icon,
blog, migration v3/v4, MCP page, `figma.yml`, `community.yml`,
`src/runtime/components/Carousel.vue`) were excluded up front.

## Auto-applied, then audited

Applying cleanly is **not** sufficient: a hunk can replace text we shared with
text describing *upstream's* reality. Three did, and were corrected:

- **`4.contribution.md` directory tree** — upstream's version lists `blog/`,
which this fork does not have. Rewritten to our actual layout, naming our
landing pages (`index.yml`, `showcase.yml`, `templates.yml`).
- **`4.contribution.md` fences** — upstream normalised every ```` ```sh ```` to
```` ```bash ````; only some hunks applied here, leaving the file mixed.
Normalised the remaining four so the page is internally consistent.
- **`5.content.md`** — the added sentence said "**Nuxt UI** ships helpers".
Rebranded, per §1; the rest of that page says "Bitrix24 UI".

One auto-applied hunk is a genuine bug fix here: `3.color-mode/2.vue.md` set
`colorMode.preference` while the getter three lines above reads `colorMode.value`.
Our Vue integration uses `.value`, so the setter was simply wrong.

## API accuracy — verified against our source, not copied

The valuable third of the commit. Every claim was checked against this fork's
implementation before being written down.

**`use-toast.md` — 8 fixes**, all confirmed in `useToast.ts` / `Toast.vue`:

| documented | our source |
| --- | --- |
| `title` / `description`: `string \| VNode \| (() => VNode)` | `StringOrVNode` |
| `close`: `boolean \| Omit<ButtonProps, LinkPropsKeys>` | verbatim |
| `progress`: `boolean \| Pick<ProgressProps, 'color' \| 'b24ui'>` | verbatim — **`ui` → `b24ui`** per §1 |
| id is generated, and reusing one merges into that toast | `generateId()` + the `_duplicate` branch |
| `duration` defaults to `5000`, `0` keeps it open | `Toaster.vue:70` and the prop's own jsDoc |
| `update()` takes `Omit<Partial<Toast>, 'id'>` | verbatim |

One value deliberately diverges: upstream documents the toast colour default as
`primary`; ours is **`air-secondary`** (`theme/toast.ts`), and that is what the
page now says. Copying upstream's default would have been wrong.

**`define-shortcuts.md`** — upstream documents `meta`/`command` and
`alt`/`option` aliases, four more special keys, and a `handler` that receives the
event. All true here: the aliases are at `defineShortcuts.ts:295,298`, the key
map at `:59-64` carries `space`, `tab`, `backspace`, `delete`, and
`useCode = layoutIndependent || e.altKey` (`:144`) is exactly why the `space`
note about `layoutIndependent` holds. Our page had already been corrected ahead
of upstream on the signature and `MaybeRef` config, so only the aliases, keys and
`ShortcutConfig.handler` were missing.

**`use-overlay.md` — nothing to do.** Already matched upstream's post-fix text on
all three points.

## Links

Six URL changes upstream; **three are broken here too** and were fixed:
`tiptap.dev/.../floating-menu` → `floatingmenu`, and two `ai-sdk.dev/docs/guides/providers/*`
→ `providers/ai-sdk-providers/*` in `chat.md` (the page's other ai-sdk links were
already on the new form).

Not applied: `color-mode.nuxtjs.org/#usage` and the `unhead` link — absent or
already current here. And upstream's split of `/docs/getting-started/integrations/{color-mode,i18n}`
into `/nuxt` and `/vue`: `0.index.md` already uses the direct form, and in
`1.index.md` the bare paths are **not broken** — `nuxt.config.ts:361-362` redirects
them — where the fork's bullet list deliberately carries one link per feature.

## Keywords

18 component pages gained the `keywords` block upstream added, inserted after
`category:` to match the existing convention. `.github/contributing/documentation.md`
gained upstream's guidance on writing them.

## One regression caught by a guard

Upstream drops `title:` from front matter, deriving it from the filename. That
hunk applied to `error.md` — and `test/utils/skill-manifest.spec.ts` went red:
this fork's skill index resolves rows through `title`, so the page became
unreachable ("B24Error -> error.md (no such page)"). Title restored. Worth
recording because the page still built fine; only the guard noticed.

## Verify

`lint` · `typecheck` · `test` (7168 passed, 6 skipped, 314 files) ·
`docs:generate` (1262 routes) — all green. 54 files changed, +195/−85.
8 changes: 7 additions & 1 deletion .sync/nuxt-ui.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"upstream": "nuxt/ui",
"branch": "v4",
"cursor": "dd4bc8e85365d45190716655430835906e5acef6",
"cursor": "c6a756c57c71dee553f75a0e84f159e3baf07d5c",
"_cursor_note": "cursor = last upstream commit ported into b24ui. The sync is manual by decision: one commit at a time, oldest-first, each with a `.sync/log/<sha>.md` journal and an entry in `processed`. There is no dispatcher, no porter workflow and no kill-switch — `.sync/PORTING.md` is the whole procedure. `processed` is maintained per port (backfilled #68-#72 on 2026-06-09).",
"processed": {
"2799fa6f2b25ce3eb15e050f3ef7c57d0d9a2fdb": {
Expand Down Expand Up @@ -1637,6 +1637,12 @@
"b24ui_sha": "5a06163dcdbca4a79955c9dabff611b5141fd048",
"decision": "port",
"summary": "chore(deps): update tiptap to ^3.30.2 (nuxt/ui #6876) — PORT of the whole @tiptap/* family, all on our pre-image; batched with #6875 (§6 4b). Every @tiptap/* entry this fork declares sat at ^3.29.2 (upstream's exact pre-image), so all bump to ^3.30.2: root 18 packages (@tiptap/core, pm, starter-kit, vue-3, markdown, suggestion, and the extension-* set), plus docs/playgrounds @tiptap/extension-emoji and extension-text-align. Parity note: @tiptap/* are tracked because in the ROOT package.json both trees declare them as dependencies at the same version; the $note's peer-vs-dependency remark concerns other declarations that stay out of the snapshot. Verified via the shared gauntlet with #6875 (dev:prepare, lint, typecheck, test, build, docs:generate); pnpm-workspace.yaml unchanged."
},
"c6a756c57c71dee553f75a0e84f159e3baf07d5c": {
"pr": "pending-merge",
"b24ui_sha": "pending-merge",
"decision": "port",
"summary": "docs: fix broken links and outdated content (nuxt/ui #6867) — PORT of everything applicable, by maintainer decision. 101 files upstream mixing four things: broken links, front-matter keywords for docs search and the MCP search-components tool, corrections where the documented API had drifted from the code, and editorial rewording. Applying the patch whole fails since our docs diverge, so it went hunk by hunk: 154 hunks tried individually, 47 applied cleanly (proving our text equalled upstream's pre-image, the only case where copying is safe by construction) and 107 rejected, each then judged on intent. The 15 files we lack (Carousel, Marquee, PricingTable, ChangelogVersion, Icon, blog, migration v3/v4, MCP page, figma.yml, community.yml, Carousel.vue) were excluded up front. CLEAN APPLICATION IS NOT SUFFICIENT — a hunk can replace shared text with text describing upstream's reality, and three did: the 4.contribution.md directory tree listed a blog/ we do not have (rewritten to our layout, naming index.yml/showcase.yml/templates.yml), that same file was left with mixed ```sh and ```bash fences because only some hunks applied (normalised), and 5.content.md gained a sentence saying 'Nuxt UI ships helpers' (rebranded per §1). One auto-applied hunk is a real bug fix here: 3.color-mode/2.vue.md set colorMode.preference while the getter three lines above reads colorMode.value. API ACCURACY was verified against our source rather than copied. use-toast.md took 8 fixes, each confirmed in useToast.ts/Toast.vue: title/description are StringOrVNode, close is Omit<ButtonProps, LinkPropsKeys>, progress is Pick<ProgressProps, 'color'|'b24ui'> (ui->b24ui per §1), the id is generated and reusing one merges via the _duplicate branch, duration defaults to 5000 with 0 keeping it open (Toaster.vue:70), and update() takes Omit<Partial<Toast>,'id'>. One value deliberately diverges: upstream documents the colour default as primary, ours is air-secondary (theme/toast.ts), and that is what the page says — copying upstream's default would have been wrong. define-shortcuts.md gained the meta/command and alt/option aliases (defineShortcuts.ts:295,298), four more special keys (the key map at :59-64 carries space/tab/backspace/delete) and the handler that receives the event; the space note about layoutIndependent holds because useCode = layoutIndependent || e.altKey (:144). Our page had already been corrected ahead of upstream on the signature and MaybeRef config. use-overlay.md needed nothing — already matched upstream's post-fix text on all three points. LINKS: three of upstream's six are broken here too and were fixed (tiptap floating-menu -> floatingmenu, two ai-sdk docs/guides/providers -> providers/ai-sdk-providers in chat.md); the color-mode and unhead ones are absent or already current, and upstream's split of the integrations links does not apply since 0.index.md already uses the direct form while 1.index.md's bare paths are not broken — nuxt.config.ts:361-362 redirects them. KEYWORDS added to 18 component pages plus upstream's authoring guidance in .github/contributing/documentation.md. ONE REGRESSION CAUGHT BY A GUARD: upstream drops title: from front matter, deriving it from the filename; that hunk applied to error.md and skill-manifest.spec.ts went red because this fork's skill index resolves rows through title, making the page unreachable. Title restored — worth recording because the page still built fine and only the guard noticed. Verified: lint, typecheck, test (7168 passed, 6 skipped, 314 files), docs:generate (1262 routes); 54 files changed, +195/-85."
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ Import the CSS file in your entrypoint.

:::code-group{sync="vite"}

```ts [src/main.ts]{1}
```ts [src/main.ts (Vite)]{1}
import './assets/css/main.css'

import { createApp } from 'vue'
Expand Down
29 changes: 16 additions & 13 deletions docs/content/docs/1.getting-started/4.contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ The documentation lives in the `docs` folder as a Nuxt app using `@nuxt/content`
│ ├── composables/
│ └── ...
├── content/
│ ├── 1.getting-started
│ ├── 2.composables
│ └── 3.components # Components documentation
│ ├── docs/
│ │ ├── 1.getting-started
│ │ ├── 2.components # Components documentation
│ │ ├── 3.composables
│ │ └── 4.typography
│ └── ... # Landing pages (index.yml, showcase.yml, templates.yml)
```

### Module
Expand Down Expand Up @@ -77,45 +80,45 @@ To begin local development, follow these steps:

#### Clone the `@bitrix24/b24ui-nuxt` repository to your local machine

```sh
```bash
git clone https://github.com/bitrix24/b24ui.git
```

#### Enable [Corepack](https://github.com/nodejs/corepack)

```sh
```bash
corepack enable
```

#### Install dependencies

```sh
```bash
pnpm install
```

#### Generate type stubs

```sh
```bash
pnpm run dev:prepare
```

#### Start development

- To work on the **documentation** located in the `docs` folder, run:

```sh
```bash
pnpm run docs
```

- To test the Nuxt components using the **playground**, run:

```sh
```bash
pnpm run dev
```

- To test the Vue components using the **playground**, run:

```sh
```bash
pnpm run dev:vue
```

Expand Down Expand Up @@ -143,7 +146,7 @@ Since ESLint is already configured to format the code, there's no need for dupli

You can use the `lint` command to check for linting errors:

```sh
```bash
pnpm run lint # check for linting errors
pnpm run lint:fix # fix linting errors
```
Expand All @@ -152,15 +155,15 @@ pnpm run lint:fix # fix linting errors

We use TypeScript for type checking. You can use the `typecheck` command to check for type errors:

```sh
```bash
pnpm run typecheck
```

### Testing

Before submitting a PR, ensure that you run the tests:

```sh
```bash
pnpm run test
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ To remove the default classes from all components at once, use the `theme.unstyl

### `class` prop

The `class` prop allows you to override the classes of the `root` or `base` slot. This takes priority over both global config and resolved `variants`.
Use the `class` prop to override the classes of the `root` or `base` slot. This takes priority over both global config and resolved `variants`.

::component-code{slug="button"}
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const isDark = computed({
return colorMode.value === 'dark'
},
set(_isDark: boolean) {
colorMode.preference = _isDark ? 'dark' : 'light'
colorMode.value = _isDark ? 'dark' : 'light'
}
})
</script>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ const { locale } = useI18n()

Each locale has a `dir` property which will be used by the `App` component to set the directionality of all components.

In a multilingual application, you might want to set the `lang` and `dir` attributes on the `<html>` element dynamically based on the user's locale, which you can do with the [useHead](https://unhead.unjs.io/usage/composables/use-head) composable:
In a multilingual application, you might want to set the `lang` and `dir` attributes on the `<html>` element dynamically based on the user's locale, which you can do with the [useHead](https://unhead.unjs.io/docs/head/api/composables/use-head) composable:

```vue [App.vue]
<script setup lang="ts">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ Discover the full **Typography** system and explore all available prose componen

## Utils

Bitrix24 UI ships helpers to reshape the data returned by `@nuxt/content` into the format its components expect.

### `mapContentNavigation`

This util will map the navigation from `queryCollectionNavigation` and transform it recursively into an array of objects that can be used by various components.
Expand All @@ -168,7 +170,7 @@ This util will map the navigation from `queryCollectionNavigation` and transform
- `navigation`: The navigation tree (array of ContentNavigationItem).
- `options` (optional):
- `labelAttribute`: (string) Which field to use as label (`title` by default)
- `deep`: (number or undefined) Controls how many levels of navigation are included (`undefined` by default : includes all levels)
- `deep`: (number or undefined) Controls how many levels of navigation are included (`undefined` by default, includes all levels)

**Example:** As shown in the breadcrumb example below, it's commonly used to transform the navigation data into the correct format.

Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/1.getting-started/7.ai/2.llms-txt.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Bitrix24 UI provides specialized LLMs.txt files that you can reference in Cursor
1. **Direct reference**: Mention the LLMs.txt URLs when asking questions
2. Add these specific URLs to your project context using `@docs`

[Read more about Cursor Web and Docs Search](https://docs.cursor.com/en/context/@-symbols/@-docs)
[Read more about prompting and `@` mentions in Cursor](https://cursor.com/docs/agent/prompting)

### Windsurf

Expand Down
4 changes: 4 additions & 0 deletions docs/content/docs/2.components/avatar-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
title: AvatarGroup
description: Pile multiple avatars into a single group.
category: element
keywords:
- stacked avatars
- faces
- members
links:
- label: GitHub
iconName: GitHubIcon
Expand Down
4 changes: 4 additions & 0 deletions docs/content/docs/2.components/button.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
title: Button
description: A button capable of linking or performing an action.
category: element
keywords:
- cta
- action
- btn
links:
- label: GitHub
iconName: GitHubIcon
Expand Down
4 changes: 4 additions & 0 deletions docs/content/docs/2.components/calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
title: Calendar
description: A calendar tool for choosing individual dates, multiple dates, or date spans.
category: element
keywords:
- date picker
- datepicker
- schedule
links:
- label: GitHub
iconName: GitHubIcon
Expand Down
4 changes: 4 additions & 0 deletions docs/content/docs/2.components/card.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
title: Card
description: Render the content within a card component comprising a header, body, and footer section.
category: element
keywords:
- panel
- box
- container
links:
- label: GitHub
iconName: GitHubIcon
Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/2.components/chat.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default defineEventHandler(async (event) => {

### Reasoning

To enable [reasoning](https://ai-sdk.dev/docs/ai-sdk-ui/chatbot#reasoning), configure `providerOptions` for your provider ([Anthropic](https://ai-sdk.dev/docs/guides/providers/anthropic#reasoning), [Google](https://ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai#thinking), [OpenAI](https://ai-sdk.dev/docs/guides/providers/openai#reasoning)):
To enable [reasoning](https://ai-sdk.dev/docs/ai-sdk-ui/chatbot#reasoning), configure `providerOptions` for your provider ([Anthropic](https://ai-sdk.dev/providers/ai-sdk-providers/anthropic#reasoning), [Google](https://ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai#thinking), [OpenAI](https://ai-sdk.dev/providers/ai-sdk-providers/openai#reasoning)):

```ts [server/api/chat.post.ts]
import { streamText, convertToModelMessages } from 'ai'
Expand Down Expand Up @@ -114,7 +114,7 @@ export default defineEventHandler(async (event) => {

### Web Search

Some providers offer built-in web search tools: [Anthropic](https://ai-sdk.dev/docs/guides/providers/anthropic#web-search-tool), [Google](https://ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai#google-search), [OpenAI](https://ai-sdk.dev/providers/ai-sdk-providers/openai#web-search-tool).
Some providers offer built-in web search tools: [Anthropic](https://ai-sdk.dev/providers/ai-sdk-providers/anthropic#web-search-tool), [Google](https://ai-sdk.dev/providers/ai-sdk-providers/google#google-search), [OpenAI](https://ai-sdk.dev/providers/ai-sdk-providers/openai#web-search-tool).

::code-group

Expand Down
3 changes: 3 additions & 0 deletions docs/content/docs/2.components/checkbox-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
title: CheckboxGroup
description: Multi-select checklist using button controls.
category: form
keywords:
- multi select
- checklist
links:
- label: GitHub
iconName: GitHubIcon
Expand Down
Loading