Skip to content
Draft
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
10 changes: 8 additions & 2 deletions docs/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import * as fs from 'fs';
import { withDeploymentConfig } from '@mui/internal-docs-infra/withDocsInfra';
import transformMarkdownMetadata from '@mui/internal-docs-infra/pipeline/transformMarkdownMetadata';
import transformMarkdownRelativePaths from '@mui/internal-docs-infra/pipeline/transformMarkdownRelativePaths';
import transformMarkdownCode from '@mui/internal-docs-infra/pipeline/transformMarkdownCode';
import transformHtmlCodeBlock from '@mui/internal-docs-infra/pipeline/transformHtmlCodeBlock';
import transformHtmlCodeInline from '@mui/internal-docs-infra/pipeline/transformHtmlCodeInline';
import enhanceCodeInline from '@mui/internal-docs-infra/pipeline/enhanceCodeInline';
import nextMdx from '@next/mdx';
import rehypeExtractToc from '@stefanprobst/rehype-extract-toc';
import remarkGfm from 'remark-gfm';
import remarkTypography from 'remark-typography';
import { rehypeQuickNav } from 'docs/src/components/QuickNav/rehypeQuickNav.mjs';
import { rehypeConcatHeadings } from 'docs/src/components/QuickNav/rehypeConcatHeadings.mjs';
import { rehypeKbd } from 'docs/src/components/Kbd/rehypeKbd.mjs';
import { rehypeSyntaxHighlighting } from 'docs/src/syntax-highlighting/index.mjs';
import { rehypeSlug } from 'docs/src/components/QuickNav/rehypeSlug.mjs';
import { rehypeSubtitle } from 'docs/src/components/Subtitle/rehypeSubtitle.mjs';
import { ordering } from 'docs/src/utils/typeOrder.mjs';
Expand Down Expand Up @@ -45,9 +48,12 @@ const withMdx = nextMdx({
],
remarkTypography,
transformMarkdownRelativePaths,
transformMarkdownCode,
],
rehypePlugins: [
...rehypeSyntaxHighlighting,
transformHtmlCodeBlock,
transformHtmlCodeInline,
enhanceCodeInline,
rehypeSlug,
rehypeConcatHeadings,
rehypeExtractToc,
Expand Down
4 changes: 1 addition & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@date-fns/tz": "^1.4.1",
"@mdx-js/loader": "^3.1.1",
"@mdx-js/react": "^3.1.1",
"@mui/internal-docs-infra": "0.7.1-canary.0",
"@mui/internal-docs-infra": "https://pkg.pr.new/mui/mui-public/@mui/internal-docs-infra@a07c9b4",
"@next/mdx": "^16.1.6",
"@react-spring/web": "^10.0.3",
"@stefanprobst/rehype-extract-toc": "^3.0.0",
Expand Down Expand Up @@ -50,7 +50,6 @@
"react-error-boundary": "6.1.1",
"react-hook-form": "^7.71.2",
"react-is": "^19.2.4",
"rehype-pretty-code": "^0.14.3",
"remark": "^15.0.1",
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
Expand All @@ -60,7 +59,6 @@
"remark-typography": "0.7.3",
"scroll-into-view-if-needed": "3.1.0",
"server-only": "^0.0.1",
"shiki": "^4.0.2",
"to-vfile": "^8.0.0",
"unist-util-visit-parents": "^6.0.2",
"vfile-matter": "^5.0.1"
Expand Down
18 changes: 13 additions & 5 deletions docs/src/app/(docs)/react/components/alert-dialog/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { AlertDialog } from '@base-ui/react/alert-dialog';

In order to open a dialog using a menu, control the dialog state and open it imperatively using the `onClick` handler on the menu item.

```tsx {12-13,17-18,24-25,28-29} title="Connecting a dialog to a menu"
```tsx title="Connecting a dialog to a menu"
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixing the highlighted lines in this demo, and in Dialog and Menu as well since it's been broken since 5e474fe#diff-eb4681ff3f8398dcc2e093c4106508dcbdbd314339bb1ced876eab0b7e054633L59

import * as React from 'react';
import { AlertDialog } from '@base-ui/react/alert-dialog';
import { Menu } from '@base-ui/react/menu';
Expand All @@ -53,15 +53,19 @@ function ExampleMenu() {
<Menu.Portal>
<Menu.Positioner>
<Menu.Popup>
{/* @highlight-start */}
{/* Open the dialog when the menu item is clicked */}
<Menu.Item onClick={() => setDialogOpen(true)}>Open dialog</Menu.Item>
{/* @highlight-end */}
</Menu.Popup>
</Menu.Positioner>
</Menu.Portal>
</Menu.Root>

{/* @highlight-start */}
{/* Control the dialog state */}
<AlertDialog.Root open={dialogOpen} onOpenChange={setDialogOpen}>
{/* @highlight-end */}
<AlertDialog.Portal>
<AlertDialog.Backdrop />
<AlertDialog.Popup>
Expand Down Expand Up @@ -95,12 +99,12 @@ For simple, one-off interactions, place the `<AlertDialog.Trigger>` inside `<Ale
However, if defining the alert dialog's content next to its trigger is not practical, you can use a detached trigger.
This involves placing the `<AlertDialog.Trigger>` outside of `<AlertDialog.Root>` and linking them with a `handle` created by the `AlertDialog.createHandle()` function.

```jsx title="Detached triggers" {3,5} "handle={demoAlertDialog}"
```jsx title="Detached triggers"
const demoAlertDialog = AlertDialog.createHandle();

<AlertDialog.Trigger handle={demoAlertDialog}>Open</AlertDialog.Trigger>
<AlertDialog.Trigger handle={demoAlertDialog}>Open</AlertDialog.Trigger> {/* @highlight-text "handle={demoAlertDialog}" */}

<AlertDialog.Root handle={demoAlertDialog}>
<AlertDialog.Root handle={demoAlertDialog}> {/* @highlight-text "handle={demoAlertDialog}" */}
...
</AlertDialog.Root>
```
Expand Down Expand Up @@ -137,18 +141,22 @@ This is achieved by passing a `payload` to the `<AlertDialog.Trigger>` and using

The payload can be strongly typed by providing a type argument to the `createHandle()` function:

```jsx title="Detached triggers with payload" {1,3,7,12}
```jsx title="Detached triggers with payload"
{/* @highlight */}
const demoAlertDialog = AlertDialog.createHandle<{ message: string }>();

{/* @highlight */}
<AlertDialog.Trigger handle={demoAlertDialog} payload={{ message: 'Trigger 1' }}>
Trigger 1
</AlertDialog.Trigger>

{/* @highlight */}
<AlertDialog.Trigger handle={demoAlertDialog} payload={{ message: 'Trigger 2' }}>
Trigger 2
</AlertDialog.Trigger>

<AlertDialog.Root handle={demoAlertDialog}>
// @highlight
{({ payload }) => (
<AlertDialog.Portal>
<AlertDialog.Popup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,22 @@ Organize related options with `<Autocomplete.Group>` and `<Autocomplete.GroupLab

Groups are represented by an array of objects with an `items` property, which itself is an array of individual items for each group. An extra property, such as `value`, can be provided for the heading text when rendering the group label.

```tsx title="Example" {3,9,13}
```tsx title="Example"
interface ProduceGroupItem {
value: string;
// @highlight
items: string[];
}

const groups: ProduceGroupItem[] = [
{
value: 'Fruits',
// @highlight
items: ['Apple', 'Banana', 'Orange'],
},
{
value: 'Vegetables',
// @highlight
items: ['Carrot', 'Lettuce', 'Spinach'],
},
];
Expand Down
3 changes: 2 additions & 1 deletion docs/src/app/(docs)/react/components/button/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ import { Button } from '@base-ui/react/button';

The button can remain keyboard accessible while being rendered as another tag, such as a `<div>`, by specifying `nativeButton={false}`.

```jsx title="Custom tag button" "nativeButton"
```jsx title="Custom tag button"
import { Button } from '@base-ui/react/button';

// @highlight-text "nativeButton={false}"
<Button render={<div />} nativeButton={false}>
Button that can contain complex children
</Button>;
Expand Down
14 changes: 10 additions & 4 deletions docs/src/app/(docs)/react/components/checkbox-group/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,25 @@ Label the group with `aria-labelledby` and a sibling label element:

An enclosing `<label>` is the simplest labeling pattern for each checkbox:

```tsx title="Using an enclosing label to label a checkbox" {1,4}
```tsx title="Using an enclosing label to label a checkbox"
// @highlight
<label>
<Checkbox.Root value="http" />
HTTP
{/* @highlight */}
</label>
```

### Rendering as a native button

By default, `<Checkbox.Root>` renders a `<span>` element to support enclosing labels. Prefer rendering each checkbox as a native button when using sibling labels (`htmlFor`/`id`).

```tsx title="Sibling label pattern with a native button" "nativeButton" "render"
```tsx title="Sibling label pattern with a native button"
<div id="protocols-label">Allowed network protocols</div>
<CheckboxGroup aria-labelledby="protocols-label">
<div>
<label htmlFor="protocol-http">HTTP</label>
{/* @highlight-text "nativeButton" "render={<button />}" */}
<Checkbox.Root id="protocol-http" value="http" nativeButton render={<button />}>
<Checkbox.Indicator />
</Checkbox.Root>
Expand All @@ -65,18 +68,20 @@ By default, `<Checkbox.Root>` renders a `<span>` element to support enclosing la

Native buttons with wrapping labels are supported by using the `render` callback to avoid invalid HTML, so the hidden input is placed outside the label:

```tsx title="Render callback" {6-11}
```tsx title="Render callback"
<div id="protocols-label">Allowed network protocols</div>
<CheckboxGroup aria-labelledby="protocols-label">
<Checkbox.Root
value="http"
nativeButton
// @highlight-start
render={(buttonProps) => (
<label>
<button {...buttonProps} />
HTTP
</label>
)}
{/* @highlight-end */}
/>
</CheckboxGroup>
```
Expand All @@ -85,8 +90,9 @@ Native buttons with wrapping labels are supported by using the `render` callback

Use [Field](/react/components/field) and [Fieldset](/react/components/fieldset) for group labeling and form integration:

```tsx title="Using Checkbox Group in a form" {2}
```tsx title="Using Checkbox Group in a form"
<Form>
{/* @highlight */}
<Field.Root name="allowedNetworkProtocols">
<Fieldset.Root render={<CheckboxGroup />}>
<Fieldset.Legend>Allowed network protocols</Fieldset.Legend>
Expand Down
14 changes: 10 additions & 4 deletions docs/src/app/(docs)/react/components/checkbox/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,23 @@ import { Checkbox } from '@base-ui/react/checkbox';

An enclosing `<label>` is the simplest labeling pattern:

```tsx title="Wrapping a label around a checkbox" {1,4}
```tsx title="Wrapping a label around a checkbox"
// @highlight
<label>
<Checkbox.Root />
Accept terms and conditions
{/* @highlight */}
</label>
```

### Rendering as a native button

By default, `<Checkbox.Root>` renders a `<span>` element to support enclosing labels. Prefer rendering the checkbox as a native button when using sibling labels (`htmlFor`/`id`).

```tsx title="Sibling label pattern with a native button" "nativeButton" "render"
```tsx title="Sibling label pattern with a native button"
<div>
<label htmlFor="notifications-checkbox">Enable notifications</label>
{/* @highlight-text "nativeButton" "render={<button />}" */}
<Checkbox.Root id="notifications-checkbox" nativeButton render={<button />}>
<Checkbox.Indicator />
</Checkbox.Root>
Expand All @@ -54,24 +57,27 @@ By default, `<Checkbox.Root>` renders a `<span>` element to support enclosing la

Native buttons with wrapping labels are supported by using the `render` callback to avoid invalid HTML, so the hidden input is placed outside the label:

```tsx title="Render callback" {3-8}
```tsx title="Render callback"
<Checkbox.Root
nativeButton
// @highlight-start
render={(buttonProps) => (
<label>
<button {...buttonProps} />
Enable notifications
</label>
)}
{/* @highlight-end */}
/>
```

### Form integration

Use [Field](/react/components/field) to handle label associations and form integration:

```tsx title="Using Checkbox in a form" {2}
```tsx title="Using Checkbox in a form"
<Form>
{/* @highlight */}
<Field.Root name="stayLoggedIn">
<Field.Label>
<Checkbox.Root />
Expand Down
8 changes: 6 additions & 2 deletions docs/src/app/(docs)/react/components/combobox/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ import { DemoComboboxInputInsidePopup } from './demos/input-inside-popup';

Use `<Combobox.Label>` to provide a visible label for the combobox trigger in this pattern:

```tsx title="Using Combobox.Label to label a combobox" {2}
```tsx title="Using Combobox.Label to label a combobox"
<Combobox.Root>
{/* @highlight */}
<Combobox.Label>Favorite fruit</Combobox.Label>
{/* ... */}
</Combobox.Root>
Expand All @@ -127,19 +128,22 @@ Organize related options with `<Combobox.Group>` and `<Combobox.GroupLabel>` to

Groups are represented by an array of objects with an `items` property, which itself is an array of individual items for each group. An extra property, such as `value`, can be provided for the heading text when rendering the group label.

```tsx title="Example" {3,9,13}
```tsx title="Example"
interface ProduceGroupItem {
value: string;
// @highlight
items: string[];
}

const groups: ProduceGroupItem[] = [
{
value: 'Fruits',
// @highlight
items: ['Apple', 'Banana', 'Orange'],
},
{
value: 'Vegetables',
// @highlight
items: ['Carrot', 'Lettuce', 'Spinach'],
},
];
Expand Down
18 changes: 13 additions & 5 deletions docs/src/app/(docs)/react/components/dialog/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ It's also common to use `onOpenChange` if your app needs to do something when th

In order to open a dialog using a menu, control the dialog state and open it imperatively using the `onClick` handler on the menu item.

```tsx {12-13,17-18,24-25,28-29} title="Connecting a dialog to a menu"
```tsx title="Connecting a dialog to a menu"
import * as React from 'react';
import { Dialog } from '@base-ui/react/dialog';
import { Menu } from '@base-ui/react/menu';
Expand All @@ -114,15 +114,19 @@ function ExampleMenu() {
<Menu.Portal>
<Menu.Positioner>
<Menu.Popup>
{/* @highlight-start */}
{/* Open the dialog when the menu item is clicked */}
<Menu.Item onClick={() => setDialogOpen(true)}>Open dialog</Menu.Item>
{/* @highlight-end */}
</Menu.Popup>
</Menu.Positioner>
</Menu.Portal>
</Menu.Root>

{/* @highlight-start */}
{/* Control the dialog state */}
<Dialog.Root open={dialogOpen} onOpenChange={setDialogOpen}>
{/* @highlight-end */}
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup>
Expand Down Expand Up @@ -190,12 +194,12 @@ For simple, one-off interactions, place the `<Dialog.Trigger>` inside `<Dialog.R
However, if defining the dialog's content next to its trigger is not practical, you can use a detached trigger.
This involves placing the `<Dialog.Trigger>` outside of `<Dialog.Root>` and linking them with a `handle` created by the `Dialog.createHandle()` function.

```jsx title="Detached triggers" {3,5} "handle={demoDialog}"
```jsx title="Detached triggers"
const demoDialog = Dialog.createHandle();

<Dialog.Trigger handle={demoDialog}>Open</Dialog.Trigger>
<Dialog.Trigger handle={demoDialog}>Open</Dialog.Trigger> {/* @highlight-text "handle={demoDialog}" */}

<Dialog.Root handle={demoDialog}>
<Dialog.Root handle={demoDialog}> {/* @highlight-text "handle={demoDialog}" */}
...
</Dialog.Root>
```
Expand Down Expand Up @@ -232,18 +236,22 @@ This is achieved by passing a `payload` to the `<Dialog.Trigger>` and using the

The payload can be strongly typed by providing a type argument to the `createHandle()` function:

```jsx title="Detached triggers with payload" {1,3,7,12}
```jsx title="Detached triggers with payload"
{/* @highlight */}
const demoDialog = Dialog.createHandle<{ text: string }>();

{/* @highlight */}
<Dialog.Trigger handle={demoDialog} payload={{ text: 'Trigger 1' }}>
Trigger 1
</Dialog.Trigger>

{/* @highlight */}
<Dialog.Trigger handle={demoDialog} payload={{ text: 'Trigger 2' }}>
Trigger 2
</Dialog.Trigger>

<Dialog.Root handle={demoDialog}>
// @highlight
{({ payload }) => (
<Dialog.Portal>
<Dialog.Popup>
Expand Down
Loading
Loading