# Mui X > title: Date and Time Pickers - Accessibility --- # Source: https://mui.com/x/react-data-grid/accessibility.md # Source: https://mui.com/x/react-tree-view/accessibility.md # Source: https://mui.com/x/react-date-pickers/accessibility.md --- productId: x-date-pickers title: Date and Time Pickers - Accessibility githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Accessibility Learn how the Date and Time Pickers implement accessibility features and guidelines, including keyboard navigation that follows international standards. ## 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://employment-social-affairs.ec.europa.eu/policies-and-activities/social-protection-social-inclusion/persons-disabilities/union-equality-strategy-rights-persons-disabilities-2021-2030/european-accessibility-act_en) (European Accessibility Act) WCAG 2.1 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 we aim to support. The WAI-ARIA Authoring Practices includes examples on [Date Picker Dialog](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/) and [Date Picker Spin Button](https://www.w3.org/WAI/ARIA/apg/patterns/spinbutton/examples/datepicker-spinbuttons/) patterns, which provide valuable information on how to optimize the accessibility of these components. ### Dialog considerations Both `Desktop` and `Mobile` Date and Time Pickers are using `role="dialog"` to display their interactive view parts and thus they should follow [Modal accessibility guidelines](/material-ui/react-modal/#accessibility). This behavior is automated as much as possible, ensuring that the Date and Time Pickers are accessible in most cases. A correct `aria-labelledby` value is assigned to the dialog component based on the following rules: - Use `toolbar` ID if the toolbar is visible - Use the ID of the input label if the toolbar is hidden :::info Make sure to provide an `aria-labelledby` prop to `popper` and/or `mobilePaper` slots in case you are using Date and Time Pickers component with **hidden toolbar** and **without a label**. ::: ## Screen reader compatibility Date and Time Pickers use ARIA roles and robust focus management across the interactive elements to convey the necessary information to users, being optimized for use with assistive technologies. ## Keyboard support The Date and Time Pickers consist of different associations of Field, Calendar, and Clock components. Each of these components is designed to respond intuitively to keyboard interactions, providing extensive keyboard navigation support. ### Fields The following table describes the keyboard support for all [field components](/x/react-date-pickers/fields/): | Keys | Description | | --------------------------------------------------------------------: | :---------------------------------------- | | Arrow Left, Arrow Right | Moves focus among date/time sections | | Arrow Up | Increases focused section value by 1 | | Arrow Down | Decreases focused section value by 1 | | Page Up | Increases focused section value by 5 | | Page Down | Decreases focused section value by 5 | | Home | Sets focused section to the minimal value | | End | Sets focused section to the maximal value | ### Date Calendar Among the [available view components](https://mui.com/x/react-date-pickers/date-calendar/#views), `day` is the only one that implements specific keyboard support: | Keys | Description | | -------------------------------: | :-------------------------------------------------------------- | | Page Up | Moves calendar to next month, keeping focus on the same day | | Page Down | Moves calendar to previous month, keeping focus on the same day | | Home | Moves focus to the first day of the week | | End | Moves focus to the last day of the week | ### Date Picker The [Date Picker](/x/react-date-pickers/date-picker/) combines the functionalities of the Date Field and Date Calendar components. Depending on which component is in focus, the Picker will provide the corresponding keyboard support, either from [Date Field](/x/react-date-pickers/accessibility/#fields) or [Date Calendar](/x/react-date-pickers/accessibility/#date-calendar). ### Date Range Calendar The [Date Range Calendar](/x/react-date-pickers/date-range-calendar/) implements similar keyboard support as the day view of the [Date Calendar](/x/react-date-pickers/accessibility/#date-calendar) component, with a difference in the navigation between the previous and next months that must be achieved using the arrows in the calendar header. | Keys | Description | | --------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------- | | Arrow Up, Arrow Down,
Arrow Left, Arrow Right | Moves focus among the available values | | Page Up | Moves focus to the last day of the month | | Page Down | Moves focus to the first day of the month | | Home | Moves focus to the first day of the week within the current month | | End | Moves focus to the last day of the week within the current month | ### Date Range Picker When interacting with the keyboard, the [Date Range Picker](/x/react-date-pickers/date-range-picker/) keeps the focus on the Field component, thereby offering the same keyboard navigation support as the [Date Range Field](/x/react-date-pickers/accessibility/#fields), having the changes consistently updated on the calendar component. --- # Source: https://mui.com/x/react-date-pickers/adapters-locale.md --- productId: x-date-pickers title: Date and Time Pickers - Date format and localization components: LocalizationProvider githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Date format and localization Date and Time Pickers support formats from different locales. ## Getting started The default locale of MUI X is English (United States). If you want to use other locales, follow the instructions below. :::warning This page focuses on date format localization. If you need to translate text inside a component, check out the [Translated components](/x/react-date-pickers/localization/) page. ::: ## Set a custom locale ### With `dayjs` For `dayjs`, import the locale and then pass its name to `LocalizationProvider`: ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import 'dayjs/locale/de'; {children} ; ``` ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import 'dayjs/locale/de'; import 'dayjs/locale/en-gb'; import 'dayjs/locale/zh-cn'; import Stack from '@mui/material/Stack'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; import { TimeField } from '@mui/x-date-pickers/TimeField'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; const locales = ['en', 'en-gb', 'zh-cn', 'de']; type LocaleKey = (typeof locales)[number]; export default function LocalizationDayjs() { const [locale, setLocale] = React.useState('en'); return ( { if (newLocale != null) { setLocale(newLocale); } }} > {locales.map((localeItem) => ( {localeItem} ))} ); } ``` ### With `date-fns` For `date-fns`, import the locale and pass it to `LocalizationProvider`: :::info We support `date-fns` package v2.x, v3.x, and v4.x major versions. A single adapter cannot work for all `date-fns` versions, because the way functions are exported has been changed in v3.x. To use `date-fns` v2.x, you need to import the adapter from `@mui/x-date-pickers/AdapterDateFnsV2` instead of `@mui/x-date-pickers/AdapterDateFns`. ::: ```tsx // with date-fns v3.x or v4.x import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; // with date-fns v2.x import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV2'; // with date-fns v3.x or v4.x import { de } from 'date-fns/locale/de'; // with date-fns v2.x import de from 'date-fns/locale/de'; {children} ; ``` ```tsx import * as React from 'react'; import { de, enGB, zhCN } from 'date-fns/locale'; import Stack from '@mui/material/Stack'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import { DateField } from '@mui/x-date-pickers/DateField'; import { TimeField } from '@mui/x-date-pickers/TimeField'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; const locales = { 'en-us': undefined, 'en-gb': enGB, 'zh-cn': zhCN, de }; type LocaleKey = keyof typeof locales; export default function LocalizationDateFns() { const [locale, setLocale] = React.useState('en-us'); return ( { if (newLocale != null) { setLocale(newLocale); } }} > {Object.keys(locales).map((localeItem) => ( {localeItem} ))} ); } ``` ### With `luxon` For `luxon`, pass the locale name to `LocalizationProvider`: ```tsx import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon'; {children} ; ``` ```tsx import * as React from 'react'; import { DateTime } from 'luxon'; import Stack from '@mui/material/Stack'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon'; import { DateField } from '@mui/x-date-pickers/DateField'; import { TimeField } from '@mui/x-date-pickers/TimeField'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; const locales = ['en-us', 'en-gb', 'zh-cn', 'de']; type LocaleKey = (typeof locales)[number]; export default function LocalizationLuxon() { const [locale, setLocale] = React.useState('en-us'); return ( { if (newLocale != null) { setLocale(newLocale); } }} > {locales.map((localeItem) => ( {localeItem} ))} ); } ``` :::warning `AdapterLuxon` does not support `Settings.throwOnInvalid = true` [setting](https://moment.github.io/luxon/api-docs/index.html#settingsthrowoninvalid). 👍 Upvote [issue #11853](https://github.com/mui/mui-x/issues/11853) if you need support for it. Don't hesitate to leave feedback on how you would like the data entry to behave. ::: ### With `moment` For `moment`, import the locale and then pass its name to `LocalizationProvider`: ```tsx import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment'; import 'moment/locale/de'; {children} ; ``` ```tsx import * as React from 'react'; import moment from 'moment'; import 'moment/locale/de'; import 'moment/locale/en-gb'; import 'moment/locale/zh-cn'; import Stack from '@mui/material/Stack'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment'; import { DateField } from '@mui/x-date-pickers/DateField'; import { TimeField } from '@mui/x-date-pickers/TimeField'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; const locales = ['en-us', 'en-gb', 'zh-cn', 'de']; type LocaleKey = (typeof locales)[number]; export default function LocalizationMoment() { const [locale, setLocale] = React.useState('en-us'); if (moment.locale() !== locale) { moment.locale(locale); } return ( { if (newLocale != null) { setLocale(newLocale); } }} > {locales.map((localeItem) => ( {localeItem} ))} ); } ``` ## Meridiem — 12h/24h format All the time and datetime components will automatically adjust to the locale's time setting, that is the 12-hour or 24-hour format. You can override the default setting with the `ampm` prop: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import 'dayjs/locale/de'; import 'dayjs/locale/en-gb'; import Stack from '@mui/material/Stack'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { TimePicker } from '@mui/x-date-pickers/TimePicker'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; const locales = ['en', 'en-gb', 'de']; type LocaleKey = (typeof locales)[number]; export default function AmPMCustomization() { const [locale, setLocale] = React.useState('en'); return ( { if (newLocale != null) { setLocale(newLocale); } }} > {locales.map((localeItem) => ( {localeItem} ))} ); } ``` ## Custom formats The format received by the props described below depends on the date library you are using. Please refer to each library's documentation for the full format table: - [Day.js](https://day.js.org/docs/display/format) - [date-fns](https://date-fns.org/docs/format) - [Luxon](https://moment.github.io/luxon/#/formatting?id=table-of-tokens) - [Moment.js](https://momentjs.com/docs/#/displaying/format/) ### Custom field format The fields have a default format that depends on the picker being used, the views enabled, and the 12h/24h format. If this default format does not suit you, you can customize it using the `format` prop: :::info This prop is available on all fields and pickers. ::: ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function CustomFieldFormat() { return ( ); } ``` :::info You can control the field format spacing using the [formatDensity](/x/react-date-pickers/custom-field/#change-the-format-density) prop. ::: ### Field-supported formats Some formats might not yet be supported by the fields. For example, they don't support day of the year or quarter. Here is the list of the currently supported formats: - The year - ✅ 2-digits values (for example, `23`) - ✅ 4-digits values (for example, `2023`) - ❌ Values with ordinal (for example, `2023th`) - The month - ✅ 1-based digit (for example, `08`) - ✅ Multi-letter values (for example, `Aug`, `August`) - ❌ 1-letter values (for example, `A`) because several months are represented with the same letter - The day of the month - ✅ 1-based digit values (for example, `24`) - ✅ 1-based digit values with ordinal (for example, `24th`) - The day of the week - ✅ 0-based digit values (for example, `03`) - ✅ 1-based digit values (for example, `04`) - ✅ Multi-letter values (for example, `Tue`, `Tuesday`) - ❌ 1-letter values (for example, `T`) because several days of the week are represented with the same letter - The hours - ✅ 0-based 12-hours values (for example, `03`) - ✅ 0-based 24-hours values (for example, `15`) - ❌ 1-based values (for example, `24` instead of `00`) - The minutes - The seconds - The meridiem If you need to use some format that is not yet supported, please [open an issue](https://github.com/mui/mui-x/issues/new/choose) describing what is your exact use case. Some new formats might be supported in the future, depending on the complexity of the implementation. ### Respect leading zeros in fields By default, the value rendered in the field always contains digit zeros, even if your format says otherwise. You can force the field to respect your format information by setting the `shouldRespectLeadingZeros` prop to `true`. :::warning When `shouldRespectLeadingZeros={true}`, the field will add an invisible character on the sections containing a single digit to make sure `onChange` is fired. If you need to get the clean value from the input, you can remove this character using `input.value.replace(/\u200e/g, '')`. ::: :::warning Luxon is not able to respect the leading zeroes when using macro tokens (for example "DD"), so `shouldRespectLeadingZeros={true}` might lead to inconsistencies when using `AdapterLuxon`. ::: ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function RespectLeadingZerosFieldFormat() { return ( ); } ``` ### Custom field placeholder When a section is empty, the field displays its placeholder instead of an empty value. For example, if you did not fill any value for the `year` section, the field will render the year placeholder. These placeholders are based on your current component localization, not on your date localization. ```tsx import 'dayjs/locale/de'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { deDE } from '@mui/x-date-pickers/locales'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; const germanLocale = deDE.components.MuiLocalizationProvider.defaultProps.localeText; export default function FieldPlaceholder() { return ( ); } ``` For more information on how to define your component localization, check out the [Translated components](/x/react-date-pickers/localization/) page. :::warning Placeholders translations depend on locale. Some locales might keep using English placeholders, because that format is commonly used in a given locale. ::: You can customize the specific placeholder section translation to your needs. All the available placeholder translation methods and their parameters are available in [the source file](https://github.com/mui/mui-x/blob/HEAD/packages/x-date-pickers/src/locales/utils/pickersLocaleTextApi.ts). You can override them using the `localeText` prop defined on the `LocalizationProvider` or on a specific Picker component if you need more fine-grained control. A common use case is to change the placeholder of the month section to a short letter form (Jan, Feb, etc.). The default translation implementation might not be what you want, so you can override it: ```tsx params.contentType === 'digit' ? 'MM' : params.format, }} > ``` ### Custom toolbar format To customize the format used in the toolbar, use the `toolbarFormat` prop of the `toolbar` slot. :::info This prop is available on all pickers. ::: ```tsx import dayjs from 'dayjs'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; export default function CustomToolbarFormat() { return ( ); } ``` ### Custom day of week format Use `dayOfWeekFormatter` to customize day names in the calendar header. This prop takes two parameters, `day` (a string with the name of the day) and `date` (the day in the format of your date library), and returns the formatted string to display. The default formatter only keeps the first letter of the name and capitalizes it. :::warning The first parameter `day` will be removed in v7 in favor of the second parameter `date` for more flexibility. ::: :::info This prop is available on all components that render a day calendar, including the Date Calendar as well as all Date Pickers, Date Time Pickers, and Date Range Pickers. ::: The example below adds a dot at the end of each day in the calendar header: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function CustomDayOfWeekFormat() { const [value, setValue] = React.useState(dayjs('2022-04-17')); return ( setValue(newValue)} dayOfWeekFormatter={(weekday) => `${weekday.format('dd')}.`} /> ); } ``` ### Custom calendar header format To customize the format used on the calendar header, use the `format` prop of the `calendarHeader` slot. :::info This prop is available on all components that render a day calendar, including the Date Calendar as well as all Date Pickers, Date Time Pickers, and Date Range Pickers. ::: ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; export default function CustomCalendarHeaderFormat() { return ( ); } ``` ## Custom start of week The Date and Time Pickers are using the week settings provided by your date libraries. Each adapter uses its locale to define the start of the week. If the default start of the week defined in your adapter's locale is not the one you want, you can override it as shown in the following examples. :::warning If you want to update the start of the week after the first render of a component, you will have to manually remount your component to apply the new locale configuration. ::: ### With `dayjs` For `dayjs`, use the `updateLocale` plugin: ```ts import updateLocale from 'dayjs/plugin/updateLocale'; dayjs.extend(updateLocale); // Replace "en" with the name of the locale you want to update. dayjs.updateLocale('en', { // Sunday = 0, Monday = 1. weekStart: 1, }); ``` ### With `date-fns` For `date-fns`, override the `options.weekStartsOn` of the used locale: ```ts import { Locale } from 'date-fns'; // with date-fns v3.x or v4.x import { enUS } from 'date-fns/locale/en-US'; // with date-fns v2.x import enUS from 'date-fns/locale/en-US'; const customEnLocale: Locale = { ...enUS, options: { ...enUS.options, // Sunday = 0, Monday = 1. weekStartsOn: 1, }, }; ``` ### With `luxon` For `luxon`, use the `Settings.defaultWeekSettings` object: ```ts import { Settings, Info } from 'luxon'; Settings.defaultWeekSettings = { // Sunday = 7, Monday = 1. firstDay: 1, // Makes sure we don't lose the other information from `defaultWeekSettings` minimalDays: Info.getMinimumDaysInFirstWeek(), weekend: Info.getWeekendWeekdays(), }; ``` :::warning The [browser API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/getWeekInfo) used by Luxon to determine the start of the week in the current locale is not yet supported by Firefox. Users on this browser will always see Monday as the start of the week. If you want to have the same start of week on all browsers, you will have to manually override the `defaultWeekSettings` to set the `firstDay` corresponding to your locale. For example, when using the `en-US` locale: ```ts Settings.defaultWeekSettings = { firstDay: 7, minimalDays: Info.getMinimumDaysInFirstWeek(), weekend: Info.getWeekendWeekdays(), }; ``` ::: ### With `moment` For `moment`, use the `moment.updateLocale` method: ```ts import moment from 'moment'; // Replace "en" with the name of the locale you want to update. moment.updateLocale('en', { week: { // Sunday = 0, Monday = 1. dow: 1, }, }); ``` ## RTL Support Right-to-left languages such as Arabic, Persian, or Hebrew are supported. Follow [this guide](/material-ui/customization/right-to-left/) to use them. The example below demonstrates how to use an RTL language (Arabic) with some of the Date and Time Pickers components. ```tsx import * as React from 'react'; import { prefixer } from 'stylis'; import rtlPlugin from '@mui/stylis-plugin-rtl'; import createCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; import dayjs from 'dayjs'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; // Create rtl cache const cacheRtl = createCache({ key: 'pickers-rtl-demo', stylisPlugins: [prefixer, rtlPlugin], }); export default function PickersRTL() { // Inherit the theme from the docs site (dark/light mode) const existingTheme = useTheme(); const theme = React.useMemo( () => createTheme(existingTheme, { direction: 'rtl' }), [existingTheme], ); return (
`, you can skip it. slotProps={{ desktopPaper: { dir: 'rtl', }, mobilePaper: { dir: 'rtl', }, }} />
); } ``` --- # Source: https://mui.com/x/react-data-grid/server-side-data/aggregation.md # Source: https://mui.com/x/react-data-grid/aggregation.md --- title: Data Grid - Aggregation --- # Data Grid - Aggregation [](/x/introduction/licensing/#premium-plan 'Premium plan') Add aggregation functions to the Data Grid to let users combine row values. The Data Grid Premium provides tools to give end users the ability to aggregate and compare row values. It includes [built-in functions](#built-in-functions) to cover common use cases such as sum, average, minimum, and maximum, as well as the means to [create custom functions](#creating-custom-functions) for all other needs. End users can aggregate rows through the Data Grid interface by opening the column menu and selecting from the items under **Aggregation**. The aggregated values are rendered in a footer row at the bottom of the Grid. ```tsx import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; export default function AggregationInitialState() { const data = useMovieData(); return (
); } ``` :::info This document covers client-side implementation. For aggregation on the server side, see [Server-side aggregation](/x/react-data-grid/server-side-data/aggregation/). ::: ## Structure of the model The aggregation model is an object. The keys correspond to the columns, and the values are the names of the aggregation functions. ## Initializing aggregation To initialize aggregation without controlling its state, provide the model to the `initialState` prop, as shown below: ```tsx import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; export default function AggregationInitialState() { const data = useMovieData(); return (
); } ``` ## Controlled aggregation Use the `aggregationModel` prop to control aggregation passed to the Data Grid. Use the `onAggregationModelChange` prop to listen to changes to aggregation and update the prop accordingly. ```tsx import * as React from 'react'; import { DataGridPremium, GridAggregationModel, GridColDef, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; export default function AggregationControlled() { const data = useMovieData(); const [aggregationModel, setAggregationModel] = React.useState({ gross: 'sum', }); return (
setAggregationModel(newModel)} />
); } ``` ## Disabling aggregation ### For all columns To disable aggregation, set the `disableAggregation` prop to `true`. This will disable all features related to aggregation, even if a model is provided. ```tsx import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; export default function AggregationDisabled() { const data = useMovieData(); return (
); } ``` ### For specific columns To disable aggregation on a specific column, set the `aggregable` property on its column definition (`GridColDef`) to `false`. In the example below, the **Year** column is not aggregable since its `aggregable` property is set to `false`. ```tsx import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false, aggregable: false, }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, { field: 'year', headerName: 'Year', type: 'number', aggregable: false, }, ]; export default function AggregationColDefAggregable() { const data = useMovieData(); return (
); } ``` ## Aggregating non-aggregable columns To apply aggregation programmatically on non-aggregable columns (columns with `aggregable: false` in the [column definition](/x/api/data-grid/grid-col-def/)), you can provide the aggregation model in one of the following ways: - Pass `aggregation.model` to the `initialState` prop. This initializes aggregation with the provided model. - Provide the `aggregationModel` prop. This controls aggregation with the provided model. - Call the API method `setAggregationModel()`. This applies an aggregation with the provided model. In the following demo, even though the **Year** column is not aggregable, it's still aggregated in read-only mode by providing an initial aggregation model as described above. ```tsx import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false, aggregable: false, }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, { field: 'year', headerName: 'Year', type: 'number', aggregable: false, }, ]; export default function AggregationColDefNonAggregable() { const data = useMovieData(); return (
); } ``` ## Usage with row grouping When [row grouping](/x/react-data-grid/row-grouping/) is enabled, aggregated values can be displayed in the grouping rows as well as the top-level footer. In the example below, the sum and the count of `true` values for each row group are aggregated and displayed in that group's row, while the total sum and count of `true` values for all rows are displayed in the footer. ```tsx import { DataGridPremium, useGridApiRef, useKeepGroupedColumnsHidden, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function AggregationRowGrouping() { const apiRef = useGridApiRef(); const { data } = useDemoData({ dataSet: 'Employee', visibleFields: ['country', 'name', 'salary', 'isAdmin'], rowLength: 10000, }); console.log(data); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { ...data.initialState, rowGrouping: { model: ['country'], }, aggregation: { model: { salary: 'sum', isAdmin: 'sizeTrue', }, }, }, }); return (
); } ``` You can use the `getAggregationPosition` prop to customize this behavior. This function takes the current group node as an argument (or `null` for the root group) and returns the position of the aggregated value. The position can be one of three values: - `"footer"`—the Data Grid adds a footer to the group to aggregate its rows. - `"inline"`—the Data Grid disables aggregation on the grouping row. - `null`—the Data Grid doesn't aggregate the group. The following snippets build on the demo above to show various use cases for the `getAggregationPosition` prop: ```tsx // Aggregate the root group in the top-level footer // and the other groups in their grouping row // (default behavior) getAggregationPosition={(groupNode) => (groupNode.depth === -1 ? 'footer' : 'inline')} // Aggregate all the groups in their grouping row; // the root will not be aggregated getAggregationPosition={(groupNode) => groupNode == null ? null : 'inline'} // Only aggregate the company groups in the grouping row; // director groups and root will not be aggregated getAggregationPosition={(groupNode) => groupNode?.groupingField === 'company' ? 'inline' : null} // Only aggregate the company group "Universal Pictures" in the grouping row getAggregationPosition={(groupNode) => (groupNode?.groupingField === 'company' && groupNode?.groupingKey === 'Universal Pictures') ? 'inline' : null } // Only aggregate the root group in the top-level footer getAggregationPosition={(groupNode) => groupNode == null ? 'footer' : null} ``` The demo below shows the sum aggregation in the footer of each group but not in the top-level footer: ```tsx import { DataGridPremium, GridColDef, useGridApiRef, useKeepGroupedColumnsHidden, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'company', headerName: 'Company', width: 200, }, { field: 'director', headerName: 'Director', width: 200, }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; export default function AggregationGetAggregationPosition() { const data = useMovieData(); const apiRef = useGridApiRef(); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { rowGrouping: { model: ['company', 'director'], }, aggregation: { model: { gross: 'sum', }, }, }, }); return (
groupNode.depth === -1 ? null : 'footer' } />
); } ``` ## Usage with tree data When working with [tree data](/x/react-data-grid/tree-data/), aggregated values can be displayed in the footer and in grouping rows. :::info If an aggregated value is displayed in a grouping row, it always takes precedence over any existing row data. This means that even if the dataset explicitly provides group values, they will be ignored in favor of the aggregated values calculated by the Data Grid. ::: In the demo below, the max values of the **Last modification** column and the sums of the **Size** column values are displayed in both the grouping rows and the footer: ```tsx import { DataGridPremium, GridColDef, GridRowsProp, DataGridPremiumProps, GridGroupingColDefOverride, isAutogeneratedRow, } from '@mui/x-data-grid-premium'; interface File { hierarchy: string[]; size?: number; updatedAt: string; } const rows: GridRowsProp = [ { hierarchy: ['.gitignore'], updatedAt: '2022-04-08T07:29:49.228Z', }, { hierarchy: ['README.md'], size: 1671, updatedAt: '2022-04-11T08:05:44.590Z', }, { hierarchy: ['next-env.d.ts'], size: 201, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['next.config.js'], size: 88, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['package.json'], size: 766, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['pages', '_app.tsx'], size: 1105, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['pages', '_document.tsx'], size: 2715, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['pages', 'about.tsx'], size: 1034, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['pages', 'index.tsx'], size: 911, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['public', 'favicon.ico'], size: 25931, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['src', 'Copyright.tsx'], size: 428, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['src', 'Link.tsx'], size: 2851, updatedAt: '2022-04-08T07:29:49.228Z', }, { hierarchy: ['src', 'ProTip.tsx'], size: 927, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['src', 'createEmotionCache.ts'], size: 331, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['src', 'theme.ts'], size: 332, updatedAt: '2022-03-28T11:53:29.298Z', }, { hierarchy: ['tsconfig.json'], size: 550, updatedAt: '2022-03-28T11:53:29.298Z', }, ]; const columns: GridColDef[] = [ { field: 'size', headerName: 'Size', type: 'number', valueGetter: (value, row) => { if (value == null) { return isAutogeneratedRow(row) ? null : 0; } const sizeInKb = value / 1024; // Round to 2 decimal places return Math.round(sizeInKb * 100) / 100; }, valueFormatter: (value) => `${Math.round(value * 100) / 100} Kb`, }, { field: 'updatedAt', headerName: 'Last modification', type: 'dateTime', width: 200, valueGetter: (value) => { if (value == null) { return null; } return new Date(value); }, }, ]; const getTreeDataPath: DataGridPremiumProps['getTreeDataPath'] = (row) => row.hierarchy; const getRowId: DataGridPremiumProps['getRowId'] = (row) => row.hierarchy.join('/'); const groupingColDef: GridGroupingColDefOverride = { headerName: 'Files', width: 350, }; export default function AggregationTreeData() { return (
); } ``` ## Filtering By default, aggregation only uses filtered rows. To use all rows, set the `aggregationRowsScope` prop to `"all"`. In the example below, the movie _Avatar_ doesn't pass the filters but is still used for the max aggregation of the **Gross** column: ```tsx import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; export default function AggregationFiltering() { const data = useMovieData(); return (
); } ``` ## Aggregation functions ### Basic structure An aggregation function is an object that describes how to combine a given set of values. ```ts const minAgg: GridAggregationFunction = { // Aggregates the `values` into a single value. apply: ({ values }) => Math.min(...values.filter((value) => value != null)), // This aggregation function is only compatible with numerical values. columnTypes: ['number'], }; ``` You can find full typing details in the [`GridAggregationFunction` API reference](/x/api/data-grid/grid-aggregation-function/). ### Built-in functions The `@mui/x-data-grid-premium` package comes with a set of built-in aggregation functions to cover common use cases: | Name | Behavior | Supported column types | | :------------ | :--------------------------------------------------------- | :--------------------------- | | `sum` | Returns the sum of all values in the group | `number` | | `avg` | Returns the non-rounded average of all values in the group | `number` | | `min` | Returns the smallest value of the group | `number`, `date`, `dateTime` | | `max` | Returns the largest value of the group | `number`, `date`, `dateTime` | | `size` | Returns the number of cells in the group | all | | `size(true)` | Returns the number of cells with value `true` | `boolean` | | `size(false)` | Returns the number of cells with value `false` | `boolean` | ### Removing a built-in function #### From all columns To remove specific aggregation functions from all columns, pass a filtered object to the `aggregationFunctions` prop. In the example below, the sum function has been removed: ```tsx import { DataGridPremium, GRID_AGGREGATION_FUNCTIONS, GridColDef, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; export default function AggregationRemoveFunctionAllColumns() { const data = useMovieData(); return (
name !== 'sum', ), )} initialState={{ aggregation: { model: { gross: 'max', }, }, }} />
); } ``` #### From a specific column To limit the aggregation options in a given column, pass the `availableAggregationFunctions` property to the column definition. This lets you specify which options are available to the end user: ```ts const column = { field: 'year', type: 'number', availableAggregationFunctions: ['max', 'min'], }; ``` In the example below, you can only aggregate the **Year** column using the max and min functions, whereas all functions are available for the **Gross** column: ```tsx import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, { field: 'year', headerName: 'Year', type: 'number', availableAggregationFunctions: ['max', 'min'], }, ]; export default function AggregationRemoveFunctionOneColumn() { const data = useMovieData(); return (
); } ``` ### Creating custom functions An aggregation function is an object with the following shape: ```ts const firstAlphabeticalAggregation: GridAggregationFunction = { // The `apply` method takes the values to aggregate and returns the aggregated value apply: (params) => { if (params.values.length === 0) { return null; } const sortedValue = params.values.sort((a = '', b = '') => a.localeCompare(b)); return sortedValue[0]; }, // The `label` property defines the label displayed in the column header // when this aggregation is being used. label: 'firstAlphabetical', // The `types` property defines which type of columns can use this aggregation function. // Here, we only want to propose this aggregation function for `string` columns. // If not defined, aggregation will be available for all column types. columnTypes: ['string'], }; ``` To provide custom aggregation functions, pass them to the `aggregationFunctions` prop on the Data Grid Premium. In the example below, the Grid has two custom functions for `string` columns: `firstAlphabetical` and `lastAlphabetical`: ```tsx import { DataGridPremium, GRID_AGGREGATION_FUNCTIONS, GridAggregationFunction, GridColDef, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false, aggregable: false, }, { field: 'director', headerName: 'Director', width: 200, }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; const firstAlphabeticalAggregation: GridAggregationFunction = { apply: (params) => { if (params.values.length === 0) { return null; } const sortedValue = params.values.sort((a = '', b = '') => a.localeCompare(b)); return sortedValue[0]; }, label: 'first alphabetical', columnTypes: ['string'], }; const lastAlphabeticalAggregation: GridAggregationFunction = { apply: (params) => { if (params.values.length === 0) { return null; } const sortedValue = params.values.sort((a = '', b = '') => a.localeCompare(b)); return sortedValue[sortedValue.length - 1]; }, label: 'last alphabetical', columnTypes: ['string'], }; export default function AggregationCustomFunction() { const data = useMovieData(); return (
); } ``` ### Aggregating data from multiple row fields By default, the `apply` method of the aggregation function receives an array of values that represent a single field value from each row. In the example below, the sum function receives the values of the `gross` field. The values in the `profit` column are derived from the `gross` and `budget` fields of the row: ```tsx { field: 'profit', type: 'number', valueGetter: (value, row) => { if (!row.gross || !row.budget) { return null; } return (row.gross - row.budget) / row.budget; } } ``` To aggregate the `profit` column, you would have to calculate the sum of the `gross` and `budget` fields separately, and then use the formula from the example above to calculate the aggregated `profit` value. To do this, you can use the `getCellValue()` callback on the aggregation function to transform the data being passed to the `apply()` method: ```tsx const profit: GridAggregationFunction<{ gross: number; budget: number }, number> = { label: 'profit', getCellValue: ({ row }) => ({ budget: row.budget, gross: row.gross }), apply: ({ values }) => { let budget = 0; let gross = 0; values.forEach((value) => { if (value) { gross += value.gross; budget += value.budget; } }); return (gross - budget) / budget; }, columnTypes: ['number'], }; ``` ```tsx import { DataGridPremium, GridAggregationFunction, GridColDef, GRID_AGGREGATION_FUNCTIONS, useGridApiRef, useKeepGroupedColumnsHidden, } from '@mui/x-data-grid-premium'; import { useMovieData, Movie } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); function calculateProfit(gross: number, budget: number) { return (gross - budget) / budget; } const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'company', headerName: 'Company', width: 200, }, { field: 'profit', headerName: 'Profit', type: 'number', width: 70, groupable: false, valueGetter: (value, row) => { if (!row.gross || !row.budget) { return null; } return calculateProfit(row.gross, row.budget); }, valueFormatter: (value) => { if (!value) { return null; } return `${Math.round(value * 100)}%`; }, }, { field: 'gross', headerName: 'Gross', type: 'number', minWidth: 140, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, { field: 'budget', headerName: 'Budget', type: 'number', minWidth: 140, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; const profit: GridAggregationFunction<{ gross: number; budget: number }, number> = { label: 'profit', getCellValue: ({ row }) => ({ budget: row.budget, gross: row.gross }), apply: ({ values }) => { let budget = 0; let gross = 0; values.forEach((value) => { if (value) { gross += value.gross; budget += value.budget; } }); return calculateProfit(gross, budget); }, columnTypes: ['number'], }; export default function AggregationMultipleRowFields() { const data = useMovieData(); const apiRef = useGridApiRef(); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { rowGrouping: { model: ['company'], }, aggregation: { model: { gross: 'sum', budget: 'sum', profit: 'profit', }, }, }, }); return (
); } ``` ### Custom value formatter By default, an aggregated cell uses the value formatter of its corresponding column. But for some columns, the format of the aggregated value might differ from that of the column values. You can provide a `valueFormatter()` method to the aggregation function to override the column's default formatting: ```ts const aggregationFunction: GridAggregationFunction = { apply: () => { /* */ }, valueFormatter: (params) => { /* format the aggregated value */ }, }; ``` ```tsx import { DataGridPremium, GRID_AGGREGATION_FUNCTIONS, GridAggregationFunction, GridColDef, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'director', headerName: 'Director', width: 200, }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; const firstAlphabeticalAggregation: GridAggregationFunction = { apply: (params) => { if (params.values.length === 0) { return null; } const sortedValue = params.values.sort((a = '', b = '') => a.localeCompare(b)); return sortedValue[0]; }, label: 'first alphabetical', valueFormatter: (value) => `Agg: ${value}`, columnTypes: ['string'], }; export default function AggregationValueFormatter() { const data = useMovieData(); return (
); } ``` ### Including pinned rows in the aggregation By default, pinned rows are not included in the top-level aggregation calculation. The demo below overrides the default aggregation functions to include values from the pinned rows in the top-level total aggreagation. ```tsx import * as React from 'react'; import { DataGridPremium, GridColDef, GRID_AGGREGATION_FUNCTIONS, GridAggregationFunction, isAutogeneratedRow, gridColumnLookupSelector, GridRowEntry, GridInitialState, GRID_ROOT_GROUP_ID, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; import { gridPinnedRowsSelector } from '@mui/x-data-grid/internals'; import { gridPivotActiveSelector } from '@mui/x-data-grid-pro/internals'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'year', headerName: 'Year', width: 100, groupable: true }, { field: 'gross', headerName: 'Gross', type: 'number', width: 150, groupable: false, valueFormatter: (value) => { if (!value) { return value; } return currencyFormatter.format(value); }, }, ]; const getValuesFromRows = ( rows: GridRowEntry[], aggregationFunction: GridAggregationFunction, field: GridColDef['field'], isPivotActive: boolean, valueGetter: (row: any) => any, ) => { const cellValues: any[] = []; rows.forEach((rowEntry) => { const row = rowEntry.model; if (isAutogeneratedRow(row)) { // Do not include the pinned aggregation row return; } if (!row) { return; } let value; if (typeof aggregationFunction.getCellValue === 'function') { value = aggregationFunction.getCellValue({ field, row }); } else if (isPivotActive) { // Since we know that pivoted fields are flat, we can use the row directly, and save lots of processing time value = row[field]; } else { value = valueGetter(row); } if (typeof value !== 'undefined') { cellValues.push(value); } }); return cellValues; }; const aggregationFunctionsWithPinnedRows: Record = {}; Object.keys(GRID_AGGREGATION_FUNCTIONS).forEach((name) => { const aggFunc = GRID_AGGREGATION_FUNCTIONS[name as keyof typeof GRID_AGGREGATION_FUNCTIONS]; const apply: GridAggregationFunction['apply'] = (params, api) => { if (params.groupId !== GRID_ROOT_GROUP_ID) { // Pinned rows can only impact top-level aggregation return aggFunc.apply(params); } if (!api) { return aggFunc.apply(params); } const apiRef = { current: api }; const pinnedRows = gridPinnedRowsSelector(apiRef); if (pinnedRows.top.length === 0 && pinnedRows.bottom.length === 0) { return aggFunc.apply(params); } let values = params.values; const isPivotActive = gridPivotActiveSelector(apiRef); const columnsLookup = gridColumnLookupSelector(apiRef); const column = columnsLookup[params.field]; const valueGetter = (row: any) => apiRef.current.getRowValue(row, column); if (pinnedRows.top) { const topCellValues = getValuesFromRows( pinnedRows.top, aggFunc, params.field, isPivotActive, valueGetter, ); if (topCellValues.length > 0) { values = topCellValues.concat(values); } } if (pinnedRows.bottom) { const bottomCellValues = getValuesFromRows( pinnedRows.bottom, aggFunc, params.field, isPivotActive, valueGetter, ); if (bottomCellValues.length > 0) { values = values.concat(bottomCellValues); } } return aggFunc.apply({ ...params, values }); }; aggregationFunctionsWithPinnedRows[name] = { ...aggFunc, apply, }; }); export default function AggregationPinnedRows() { const data = useMovieData(); const [includePinnedRows, setIncludePinnedRows] = React.useState(true); const initialState = React.useMemo(() => { return { aggregation: { model: { gross: 'sum', }, }, }; }, []); const { rows, topRows, bottomRows } = React.useMemo(() => { const nonPinnedRows = [...data.rows]; return { topRows: [nonPinnedRows.shift()], rows: nonPinnedRows, bottomRows: [nonPinnedRows.pop()], }; }, [data.rows]); return (
setIncludePinnedRows(ev.target.checked)} /> } label="Aggregate pinned rows" />
); } ``` ## Custom rendering If the column used to display aggregation has a `renderCell()` property, then the aggregated cell calls it with a `params.aggregation` object to let you decide how you want to render it. This object contains a `hasCellUnit` property to indicate whether the current aggregation has the same unit as the rest of the column's data—for instance, if the column is in `$`, is the aggregated value is also in `$`? In the example below, all the aggregation functions are rendered with the rating UI aside from `size`, because it's not a valid rating: ```tsx import * as React from 'react'; import { DataGridPremium, GridColDef } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; import Rating from '@mui/material/Rating'; const COLUMNS: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 200, groupable: false }, { field: 'imdbRating', headerName: 'Rating', type: 'number', width: 180, availableAggregationFunctions: ['min', 'max', 'avg', 'size'], display: 'flex', // Imdb rating is on a scale from 0 to 10, the MUI rating component is on a scale from 0 to 5 renderCell: (params) => { if (params.aggregation && !params.aggregation.hasCellUnit) { return params.formattedValue; } return ( ); }, }, ]; export default function AggregationRenderCell() { const data = useMovieData(); // We take movies with the highest and lowest rating to have a visual difference const rows = React.useMemo(() => { return [...data.rows].sort((a, b) => b.imdbRating - a.imdbRating); }, [data.rows]); return (
); } ``` ## Selectors {{"component": "modules/components/SelectorsDocs.js", "category": "Aggregation"}} ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) - [GridAggregationFunction](/x/api/data-grid/grid-aggregation-function/) --- # Source: https://mui.com/x/api/data-grid/ai-assistant-panel-trigger.md # AiAssistantPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - AI Assistant Panel component 🚧 ## Import ```jsx import { AiAssistantPanelTrigger } from '@mui/x-data-grid-premium/components'; // or import { AiAssistantPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/aiAssistantPanel/AiAssistantPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/aiAssistantPanel/AiAssistantPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/components/ai-assistant-panel.md --- title: Data Grid - AI Assistant Panel component productId: x-data-grid components: AiAssistantPanelTrigger packageName: '@mui/x-data-grid-premium' githubLabel: 'scope: data grid' --- # Data Grid - AI Assistant Panel component [](/x/introduction/licensing/#premium-plan 'Premium plan') 🚧 Customize the Data Grid's AI assistant panel. :::warning This component is incomplete. Currently, the AI Assistant Panel Trigger is the only part of the AI Assistant Panel component available. Future versions of the AI Assistant Panel component will make it possible to compose each of its parts for full customization. ::: The AI assistant panel is part of the [AI Assistant feature](/x/react-data-grid/ai-assistant/). You can use the AI Assistant Panel Trigger and [Toolbar](/x/react-data-grid/components/toolbar/) components when you need to customize the AI assistant panel trigger, or when implementing a custom toolbar. ## Basic usage The demo below shows how to add an AI assistant panel trigger to a custom toolbar. ```tsx import { DataGridPremium, Toolbar, ToolbarButton, AiAssistantPanelTrigger, GridAiAssistantPanel, } from '@mui/x-data-grid-premium'; import { mockPromptResolver, useDemoData } from '@mui/x-data-grid-generator'; import Tooltip from '@mui/material/Tooltip'; import AssistantIcon from '@mui/icons-material/Assistant'; function CustomToolbar() { return ( }> ); } export default function GridAiAssistantPanelTrigger() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 10, maxColumns: 10, }); return (
); } ``` ## Anatomy ```tsx import { AiAssistantPanelTrigger } from '@mui/x-data-grid-premium'; ; ``` ### AI Assistant Panel Trigger `` is a button that opens and closes the AI assistant panel. It renders the `baseButton` slot. ## Custom elements Use the `render` prop to replace default elements. See [Components usage—Customization](/x/react-data-grid/components/usage/#customization) for more details. ## Accessibility ### ARIA You must apply a text label or an `aria-label` attribute to the ``. # AiAssistantPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - AI Assistant Panel component 🚧 ## Import ```jsx import { AiAssistantPanelTrigger } from '@mui/x-data-grid-premium/components'; // or import { AiAssistantPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/aiAssistantPanel/AiAssistantPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/aiAssistantPanel/AiAssistantPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/ai-assistant.md --- title: Ask Your Table - AI Assistant --- # Ask Your Table - AI Assistant [](/x/introduction/licensing/#premium-plan 'Premium plan') Translate natural language into Data Grid views. :::warning To use this feature you must have a prompt processing backend. MUI [offers this service](/x/react-data-grid/ai-assistant/#with-muis-service) as a part of a premium package add-on. Email us at [sales@mui.com](mailto:sales@mui.com) for more information. ::: The AI Assistant feature lets users interact with the Data Grid component using natural language. Type a prompt like "sort by name", "show amounts larger than 1000", or even make more complex queries like "which customers brought the most revenue the past year" in the prompt input field and the Data Grid will update accordingly. In [supported browsers](https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition#browser_compatibility), users can also prompt the assistant using their voice. To enable this feature on the Data Grid, pass the `aiAssistant` prop and use the `GridAiAssistantPanel` component for `aiAssistantPanel` slot: ```tsx import { DataGridPremium, GridAiAssistantPanel } from '@mui/x-data-grid-premium'; // ... ; ``` ## Improving accuracy with example values To increase the accuracy of the language processing, provide example values for the available columns via one of the methods below. ### Provide custom examples Use the `examples` property on items of the `columns` array to provide custom examples as context for prompt processing. The `examples` property should contain an array of possible values for each respective column. :::info AI Assistant demos use a limited version of [MUI's processing service](/x/react-data-grid/ai-assistant/#with-muis-service). ::: ```tsx import * as React from 'react'; import { DataGridPremium, GridAiAssistantPanel, unstable_gridDefaultPromptResolver as promptResolver, } from '@mui/x-data-grid-premium'; import { randomBoolean, randomCompanyName, randomCountry, randomCreatedDate, randomEmail, randomInt, randomJobTitle, randomPhoneNumber, randomTraderName, useDemoData, } from '@mui/x-data-grid-generator'; function createExamples(column: string) { switch (column) { case 'name': return Array.from({ length: 5 }, () => randomTraderName()); case 'email': return Array.from({ length: 5 }, () => randomEmail()); case 'position': return Array.from({ length: 5 }, () => randomJobTitle()); case 'company': return Array.from({ length: 5 }, () => randomCompanyName()); case 'salary': return Array.from({ length: 5 }, () => randomInt(30000, 80000)); case 'phone': return Array.from({ length: 5 }, () => randomPhoneNumber()); case 'country': return Array.from({ length: 5 }, () => randomCountry()); case 'dateCreated': return Array.from({ length: 5 }, () => randomCreatedDate()); case 'isAdmin': return Array.from({ length: 5 }, () => randomBoolean()); default: return []; } } function processPrompt(prompt: string, context: string, conversationId?: string) { return promptResolver( 'https://backend.mui.com/api/datagrid/prompt', prompt, context, conversationId, ); } const VISIBLE_FIELDS = [ 'id', 'avatar', 'name', 'website', 'rating', 'email', 'phone', 'username', 'position', 'company', 'salary', 'country', 'city', 'lastUpdated', 'dateCreated', 'isAdmin', ]; export default function AssistantWithExamples() { const { data } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 1000, }); const columns = React.useMemo( () => data.columns.map((column) => ({ ...column, examples: createExamples(column.field), })), [data.columns], ); return (
); } ``` :::success Provide examples for the [derived columns](/x/react-data-grid/pivoting/#derived-columns-in-pivot-mode) using the `getPivotDerivedColumns()` prop. ::: ### Use row data for examples Pass the `allowAiAssistantDataSampling` prop to use row data to generate examples. This is useful if you're dealing with non-sensitive data and want to skip creating custom examples for each column. Data is collected randomly at the cell level, which means that the examples for a given column might not come from the same rows. ```tsx import { DataGridPremium, GridAiAssistantPanel, unstable_gridDefaultPromptResolver as promptResolver, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = [ 'id', 'avatar', 'name', 'website', 'rating', 'email', 'phone', 'username', 'position', 'company', 'salary', 'country', 'city', 'lastUpdated', 'dateCreated', 'isAdmin', ]; function processPrompt(prompt: string, context: string, conversationId?: string) { return promptResolver( 'https://backend.mui.com/api/datagrid/prompt', prompt, context, conversationId, ); } export default function AssistantWithDataSampling() { const { data } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 1000, }); return (
); } ``` ### Using server-side data The example below shows how to combine the AI Assistant with [server-side data](/x/react-data-grid/server-side-data/). ```tsx import * as React from 'react'; import { DataGridPremium, GridDataSource, GridGetRowsResponse, useGridApiRef, useKeepGroupedColumnsHidden, unstable_gridDefaultPromptResolver as promptResolver, GridAiAssistantPanel, DataGridPremiumProps, } from '@mui/x-data-grid-premium'; import { useMockServer } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = [ 'id', 'avatar', 'name', 'website', 'rating', 'email', 'phone', 'username', 'position', 'company', 'salary', 'country', 'city', 'lastUpdated', 'dateCreated', 'isAdmin', ]; const aggregationFunctions = { sum: { columnTypes: ['number'] }, avg: { columnTypes: ['number'] }, min: { columnTypes: ['number', 'date', 'dateTime'] }, max: { columnTypes: ['number', 'date', 'dateTime'] }, size: {}, }; const pivotingColDef: DataGridPremiumProps['pivotingColDef'] = ( originalColumnField, columnGroupPath, ) => ({ field: columnGroupPath.concat(originalColumnField).join('>->'), }); function processPrompt(prompt: string, context: string, conversationId?: string) { return promptResolver( 'https://backend.mui.com/api/datagrid/prompt', prompt, context, conversationId, ); } export default function AssistantWithDataSource() { const apiRef = useGridApiRef(); const { columns, initialState, fetchRows } = useMockServer( { dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, maxColumns: 16, rowLength: 1000, }, { useCursorPagination: false }, ); const dataSource: GridDataSource = React.useMemo( () => ({ getRows: async (params) => { const urlParams = new URLSearchParams({ paginationModel: JSON.stringify(params.paginationModel), filterModel: JSON.stringify(params.filterModel), sortModel: JSON.stringify(params.sortModel), groupKeys: JSON.stringify(params.groupKeys), groupFields: JSON.stringify(params.groupFields), aggregationModel: JSON.stringify(params.aggregationModel), pivotModel: JSON.stringify(params.pivotModel), }); const getRowsResponse = await fetchRows( `https://mui.com/x/api/data-grid?${urlParams.toString()}`, ); return { rows: getRowsResponse.rows, rowCount: getRowsResponse.rowCount, aggregateRow: getRowsResponse.aggregateRow, pivotColumns: getRowsResponse.pivotColumns, }; }, getGroupKey: (row) => row.group, getChildrenCount: (row) => row.descendantCount, getAggregatedValue: (row, field) => row[field], }), [fetchRows], ); const initialStateUpdated = useKeepGroupedColumnsHidden({ apiRef, initialState: { ...initialState, pagination: { paginationModel: { pageSize: 10, page: 0 }, rowCount: 0, }, }, }); return (
); } ``` ### Data visualization AI Assistant analyzes the query to determine if it is helpful to visualize the results. [Integrate](/x/react-data-grid/charts-integration/) the Data Grid with [MUI X Charts](/x/react-charts/) to enable the Data Grid to apply the visualization instructions. ```tsx import { useDemoData } from '@mui/x-data-grid-generator'; import { DataGridPremium, GridAiAssistantPanel, unstable_gridDefaultPromptResolver as promptResolver, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, useGridApiRef, } from '@mui/x-data-grid-premium'; import { ChartsRenderer, configurationOptions, ChartsRendererProps, } from '@mui/x-charts-premium/ChartsRenderer'; function processPrompt(prompt: string, context: string, conversationId?: string) { return promptResolver( 'https://backend.mui.com/api/datagrid/prompt', prompt, context, conversationId, ); } export default function AssistantWithCharts() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10000, }); const apiRef = useGridApiRef(); const initialState = { ...data.initialState, pagination: { ...data.initialState?.pagination, paginationModel: { pageSize: 25, }, }, chartsIntegration: { charts: { main: { chartType: 'column', }, }, }, }; return (
); } function CustomRenderer(props: ChartsRendererProps) { // Do not render anything if the dimensions or values are empty if (props.dimensions.length === 0 || props.values.length === 0) { return null; } return ; } ``` ## Processing service integration Natural language prompts must be processed by a service to understand what kinds of state changes must be applied to the Data Grid to match the user's request. You can use MUI's processing service or build your own. ### With MUI's service The Data Grid provides all the necessary elements for integration with MUI's service. 1. Contact [sales@mui.com](mailto:sales@mui.com) to get an API key for our processing service. :::warning Do not expose the API key to the public. Instead, keep it private, use a proxy server that receives prompt processing requests, adds the `x-api-key` header, and passes the request on to MUI's service. This is an example of a [Fastify proxy](https://www.npmjs.com/package/@fastify/http-proxy) for the prompt requests. ```ts fastify.register(proxy, { upstream: 'https://backend.mui.com', prefix: '/api/my-custom-path', rewritePrefix: '/api/v1/datagrid/prompt', replyOptions: { rewriteRequestHeaders: (_, headers) => ({ ...headers, 'x-api-key': process.env.MUI_DATAGRID_API_KEY, }), }, }); ``` ::: 2. Enable the AI Assistant feature by adding the `aiAssistant` prop. This adds a new button to the Toolbar that controls the Assistant Panel's open state. 3. Provide `` as a component for the `aiAssistantPanel` slot. Slot is by default `null` to prevent bundling of the panel and its child components in the projects that are not using the AI Assistant feature. 4. Provide the `onPrompt()` callback to pass the user's prompts to the service. The service's response is used internally by the Data Grid to make the necessary state updates. :::success You can implement `onPrompt()` with `unstable_gridDefaultPromptResolver()`. This adds the necessary headers and stringifies the body in the correct format for you. It also makes it possible to provide additional context for better processing results, as shown below: ```ts const PROMPT_RESOLVER_PROXY_BASE_URL = process.env.NODE_ENV === 'development' ? 'http://localhost:3000' : 'https://api.my-proxy.com'; function processPrompt(query: string, context: string, conversationId?: string) { const additionalContext = `The rows represent: List of employees with their company, position and start date`; return unstable_gridDefaultPromptResolver( `${PROMPT_RESOLVER_PROXY_BASE_URL}/api/my-custom-path`, query, context, conversationId, { additionalContext }, ); } ``` By default, MUI's prompt resolver service stores the queries made to the service to analyze potential errors and improve the service (data is never stored). Enable `privateMode` to make the service only keep track of the data needed for billing, without any query related data. ```ts function processPrompt(query: string, context: string, conversationId?: string) { return unstable_gridDefaultPromptResolver( `${PROMPT_RESOLVER_PROXY_BASE_URL}/api/my-custom-path`, query, context, conversationId, { privateMode: true }, ); } ``` ::: 5. Provide data examples in either of the following ways: - Fill the `examples` prop in the `columns` array – this is recommended if you want to avoid exposing the row data to the AI Assistant. - Provide access to the row data with `allowAiAssistantDataSampling` prop – since this uses real data, it may lead to better processing results. 6. Optionally, provide `referenceId` in the metadata to track spending and set limits for each entity sharing your API key. The MUI Service supports `metadata` property through which you can send the reference that will be stored with the request. Later, use that reference in the request history analysis. ::warning The `metadata` object would store only `referenceId` property. If you are interested in storing more data, please [contact our support team](mailto:support@mui.com). :: ```ts function processPrompt(query: string, context: string, conversationId?: string) { return unstable_gridDefaultPromptResolver( `${PROMPT_RESOLVER_PROXY_BASE_URL}/api/my-custom-path`, query, context, conversationId, { metadata: { referenceId: 'example-user-reference', }, }, ); } ``` ### With a custom service The Data Grid exposes elements of the AI Assistant feature so you can build your own prompt processing service: - The [`aiAssistant` API](/x/api/data-grid/grid-api/#grid-api-prop-aiAssistant) for processing the prompt results and updating state - The `unstable_gridDefaultPromptResolver()` method for passing the prompt and context with the necessary headers to the processing service Integrate these elements with your custom components and methods to suit your specific use case. You can use a fully custom solution and apply the processing result using other Grid APIs such as [`setFilterModel()`](/x/api/data-grid/grid-api/#grid-api-prop-setFilterModel) or [`setSortModel()`](/x/api/data-grid/grid-api/#grid-api-prop-setSortModel) without the need to structure it as a `PromptResponse`. To replace `unstable_gridDefaultPromptResolver()` with your own solution, send a POST request to MUI's API. The body of the request requires `query` and `context` parameters. `conversationId` and `options` are optional. To keep the previous messages in the context you should pass the `conversationId` from the previous response. The API response type is `Result`. ```ts type Result = { ok: false; message: string } | { ok: true; data: T }; ``` Your resolver should return `Promise`. ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/api/charts/animated-area.md # AnimatedArea API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { AnimatedArea } from '@mui/x-charts/LineChart'; // or import { AnimatedArea } from '@mui/x-charts'; // or import { AnimatedArea } from '@mui/x-charts-pro'; // or import { AnimatedArea } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | skipAnimation | `bool` | `false` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/AnimatedArea.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/AnimatedArea.tsx) --- # Source: https://mui.com/x/api/charts/animated-line.md # AnimatedLine API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { AnimatedLine } from '@mui/x-charts/LineChart'; // or import { AnimatedLine } from '@mui/x-charts'; // or import { AnimatedLine } from '@mui/x-charts-pro'; // or import { AnimatedLine } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | skipAnimation | `bool` | `false` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/AnimatedLine.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/AnimatedLine.tsx) --- # Source: https://mui.com/x/react-charts/animation.md --- title: Charts - Animation productId: x-charts --- # Charts - Animation Learn how to customize both CSS and JavaScript-based Chart animations. 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: ```tsx import * as React from 'react'; import { pieArcLabelClasses, PieChart } from '@mui/x-charts/PieChart'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; const data = [ { id: 0, value: 10, label: 'series A' }, { id: 1, value: 15, label: 'series B' }, { id: 2, value: 20, label: 'series C' }, ]; export default function CSSAnimationCustomization() { const [key, rerender] = React.useReducer((x) => x + 1, 0); return ( `${item.value}` }]} width={200} height={200} hideLegend sx={{ [`& .${pieArcLabelClasses.root}.${pieArcLabelClasses.animate}`]: { animationDuration: '2s', }, }} /> ); } ``` ## 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: ```tsx import { BarChart, BarLabelProps } from '@mui/x-charts/BarChart'; import * as React from 'react'; import { useAnimateBarLabel } from '@mui/x-charts/hooks'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { styled } from '@mui/material/styles'; export default function JSDefaultAnimation() { const [key, animate] = React.useReducer((v) => v + 1, 0); return ( ); } const Text = styled('text')(({ theme }) => ({ ...theme?.typography?.body2, stroke: 'none', fill: (theme.vars || theme)?.palette?.text?.primary, })); function AnimatedBarLabel(props: BarLabelProps) { const { seriesId, dataIndex, color, isFaded, isHighlighted, classes, xOrigin, yOrigin, x, y, width, height, layout, skipAnimation, ...otherProps } = props; const animatedProps = useAnimateBarLabel({ xOrigin, x, yOrigin, y, width, height, layout, skipAnimation, }); return ( ); } ``` ### 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: ```tsx import { BarChart, BarLabelProps } from '@mui/x-charts/BarChart'; import * as React from 'react'; import { useAnimate } from '@mui/x-charts/hooks'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { interpolateObject } from '@mui/x-charts-vendor/d3-interpolate'; export default function JSAnimationCustomization() { const [key, animate] = React.useReducer((v) => v + 1, 0); return ( ); } function AnimatedBarLabel(props: BarLabelProps) { const { seriesId, dataIndex, color, isFaded, isHighlighted, classes, xOrigin, yOrigin, x, y, width, height, layout, skipAnimation, ...otherProps } = props; const animatedProps = useAnimate( { x: x + width / 2, y: y - 2 }, { initialProps: { x: x + width / 2, y: yOrigin }, createInterpolator: interpolateObject, transformProps: (p) => p, applyProps: (element: SVGTextElement, p) => { element.setAttribute('x', p.x.toString()); element.setAttribute('y', p.y.toString()); }, skip: skipAnimation, }, ); return ( ); } ``` ## 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: ```tsx import { BarChart, BarLabelProps } from '@mui/x-charts/BarChart'; import * as React from 'react'; import { animated, useSpring } from '@react-spring/web'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; export default function ReactSpringAnimationCustomization() { const [key, animate] = React.useReducer((v) => v + 1, 0); return ( ); } function AnimatedBarLabel(props: BarLabelProps) { const { seriesId, dataIndex, color, isFaded, isHighlighted, classes, xOrigin, yOrigin, x, y, width, height, layout, skipAnimation, ...otherProps } = props; const style = useSpring({ from: { y: yOrigin }, to: { y: y - 4 }, config: { tension: 100, friction: 10 }, }); return ( ); } ``` ### 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: ```tsx import { LineChart, type AnimatedLineProps, type MarkElementProps, } from '@mui/x-charts/LineChart'; import * as React from 'react'; import { motion } from 'motion/react'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; export default function MotionAnimationCustomization() { const [key, animate] = React.useReducer((v) => v + 1, 0); return ( ); } function AnimatedLine({ d, ownerState, skipAnimation }: AnimatedLineProps) { return ( ); } function AnimatedMark({ x, y, color, skipAnimation }: MarkElementProps) { return ( ); } ``` --- # Source: https://mui.com/x/react-data-grid/api-object.md # Data Grid - API object Interact with the Data Grid using its API. The API object is an interface containing the state and all the methods available to programmatically interact with the Data Grid. You can find the list of all the API methods on the [`GridApi` page](/x/api/data-grid/grid-api/). :::warning New and experimental features are prefixed with `unstable_` and may be removed, renamed, or reworked at any time. ::: ## How to use the API object The API object is accessible through the `apiRef` variable. To access this variable, use `useGridApiContext` (inside `DataGrid`) or `useGridApiRef` (outside `DataGrid`). ### Inside the Data Grid To access the API object inside component slots or inside renders (for instance, `renderCell` or `renderHeader`), use the `useGridApiContext` hook. The snippet below renders `Button` inside the Grid's `GridToolbarContainer`: ```tsx function CustomToolbar() { const apiRef = useGridApiContext(); return ( ); } ``` :::info You don't need to initialize the API object using `useGridApiRef` to be able to use it inside Data Grid components. ::: ```tsx import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import { DataGrid, GridToolbarContainer, useGridApiContext } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; function CustomToolbar() { const apiRef = useGridApiContext(); const handleGoToPage1 = () => apiRef.current.setPage(1); return ( ); } export default function UseGridApiContext() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return ( ); } ``` ### Outside the Data Grid When using the API object outside Data Grid components, you must initialize it using the `useGridApiRef` hook. You can then pass it to the `apiRef` prop on the `DataGrid`: ```tsx function CustomDataGrid(props) { const apiRef = useGridApiRef(); return (
); } ``` :::warning The API object is populated by the `DataGrid`'s various plugins during the first render of the component. If you try to use it in the first render of the component, it will crash because not all methods are registered yet. ::: ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import { DataGrid, useGridApiRef } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function UseGridApiRef() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); const [paginationModel, setPaginationModel] = React.useState({ page: 0, pageSize: 10, }); const apiRef = useGridApiRef(); const handleGoToPage1 = () => apiRef.current?.setPage(1); return ( ); } ``` ## Common use cases ### Access the disabled column features You can control the disabled features of a column (for example hiding, sorting, filtering, pinning, grouping, etc) programmatically using `initialState`, controlled models, or the API object. In the example below, the API object is used to build a custom sorting for the `firstName` column which is not sortable by the default grid UI (using the `colDef.sortable` property set to `false`). ```tsx const columns = [{ field: 'rating', sortable: false }, ...otherColumns]; function CustomDataGrid(props) { const apiRef = useGridApiRef(); return (
); } ``` ```tsx import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import { DataGrid, useGridApiRef, GridColDef } from '@mui/x-data-grid'; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 90 }, { field: 'firstName', headerName: 'First name', width: 150, editable: true, filterable: false, sortable: false, }, { field: 'lastName', headerName: 'Last name', width: 150, editable: true, }, ]; const rows = [ { id: 1, lastName: 'Snow', firstName: 'Jon' }, { id: 2, lastName: 'Lannister', firstName: 'Cersei' }, { id: 3, lastName: 'Lannister', firstName: 'Jaime' }, { id: 4, lastName: 'Stark', firstName: 'Arya' }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys' }, { id: 6, lastName: 'Melisandre', firstName: null }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara' }, { id: 8, lastName: 'Frances', firstName: 'Rossini' }, { id: 9, lastName: 'Roxie', firstName: 'Harvey' }, ]; export default function AccessDisabledColumnFeatures() { const apiRef = useGridApiRef(); return (
); } ``` ### Retrieve data from the state See [State—Access the state](/x/react-data-grid/state/#access-the-state) for a detailed example. ### Listen to grid events See [Events—Subscribing to events](/x/react-data-grid/events/#subscribing-to-events) for a detailed example. ## API - [`GridApi`](/x/api/data-grid/grid-api/) - [`DataGrid`](/x/api/data-grid/data-grid/) - [`DataGridPro`](/x/api/data-grid/data-grid-pro/) - [`DataGridPremium`](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/api/charts/area-element.md # AreaElement API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { AreaElement } from '@mui/x-charts/LineChart'; // or import { AreaElement } from '@mui/x-charts'; // or import { AreaElement } from '@mui/x-charts-pro'; // or import { AreaElement } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | area | `AnimatedArea` | - | The component that renders the area. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | faded | Styles applied to the root element when faded. | | - | highlighted | Styles applied to the root element when highlighted. | | - | root | Styles applied to the root element. | | - | series | Styles applied to the root element for a specified series. Needs to be suffixed with the series ID: `.${areaElementClasses.series}-${seriesId}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/AreaElement.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/AreaElement.tsx) --- # Source: https://mui.com/x/api/charts/area-plot.md # AreaPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { AreaPlot } from '@mui/x-charts/LineChart'; // or import { AreaPlot } from '@mui/x-charts'; // or import { AreaPlot } from '@mui/x-charts-pro'; // or import { AreaPlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | onItemClick | `function(event: React.MouseEvent, lineItemIdentifier: LineItemIdentifier) => void` | - | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | area | `AnimatedArea` | - | The component that renders the area. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/AreaPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/AreaPlot.tsx) --- # Source: https://mui.com/x/react-charts/areas-demo.md --- title: Charts - Areas demos productId: x-charts components: LineChart, LineElement, LineHighlightElement, LineHighlightPlot, LinePlot, MarkElement, MarkPlot, AreaElement, AreaPlot --- # Charts - Areas demos This page groups demos using area charts. ## SimpleAreaChart ```tsx import { LineChart, lineElementClasses } from '@mui/x-charts/LineChart'; import Box from '@mui/material/Box'; const margin = { right: 24 }; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function SimpleAreaChart() { return ( ); } ``` ## StackedAreaChart ```tsx import { LineChart, lineElementClasses } from '@mui/x-charts/LineChart'; import Box from '@mui/material/Box'; const margin = { right: 24 }; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const amtData = [2400, 2210, 0, 2000, 2181, 2500, 2100]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function StackedAreaChart() { return ( ); } ``` ## TinyAreaChart ```tsx import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { AreaPlot } from '@mui/x-charts/LineChart'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function TinyAreaChart() { return ( ); } ``` ## PercentAreaChart ```tsx import { LineChart } from '@mui/x-charts/LineChart'; import Box from '@mui/material/Box'; const time = [ new Date(2015, 1, 0), new Date(2015, 2, 0), new Date(2015, 3, 0), new Date(2015, 4, 0), new Date(2015, 5, 0), new Date(2015, 6, 0), new Date(2015, 7, 0), ]; const a = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const b = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const c = [2400, 2210, 2290, 2000, 2181, 2500, 2100]; const getPercents = (array: number[]) => array.map((v, index) => (100 * v) / (a[index] + b[index] + c[index])); export default function PercentAreaChart() { return ( ); } ``` ## AreaChartConnectNulls ```tsx import Stack from '@mui/material/Stack'; import { LineChart } from '@mui/x-charts/LineChart'; const data = [4000, 3000, 2000, null, 1890, 2390, 3490]; const xData = ['Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G']; const margin = { right: 24 }; export default function AreaChartConnectNulls() { return ( ); } ``` ## 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 `` and use `sx` to override the area `fill` property. To do so you will need to use the [``](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/linearGradient) and [``](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 `` 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 `` offset is a ratio of gradient vector. That's why you need to divide the coordinate by the SVG height. ::: ```tsx import { ScaleLinear } from '@mui/x-charts-vendor/d3-scale'; import { green, red } from '@mui/material/colors'; import Stack from '@mui/material/Stack'; import { useYScale, useDrawingArea } from '@mui/x-charts/hooks'; import { LineChart, areaElementClasses } from '@mui/x-charts/LineChart'; const margin = { right: 24, bottom: 0 }; const data = [4000, 3000, -1000, 500, -2100, -250, 3490]; const xData = ['Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G']; type ColorSwitchProps = { threshold: number; color1: string; color2: string; id: string; }; function ColorSwitch({ threshold, color1, color2, id }: ColorSwitchProps) { const { top, height, bottom } = useDrawingArea(); const svgHeight = top + bottom + height; const scale = useYScale() as ScaleLinear; // You can provide the axis Id if you have multiple ones const y0 = scale(threshold); // The coordinate of the origin const off = y0 !== undefined ? y0 / svgHeight : 0; return ( ); } export default function AreaChartFillByValue() { return ( ); } function ColorPalette({ id }: { id: string }) { const { top, height, bottom } = useDrawingArea(); const svgHeight = top + bottom + height; const scale = useYScale() as ScaleLinear; // You can provide the axis Id if you have multiple ones return ( ); } ``` --- # Source: https://mui.com/x/api/charts/axis-config.md # AxisConfig API ## Import ```jsx import { AxisConfig } from '@mui/x-charts-premium' // or import { AxisConfig } from '@mui/x-charts-pro' // or import { AxisConfig } from '@mui/x-charts' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | id | `AxisId` | - | Yes | | | scaleType | `'linear'` | - | Yes | | | classes | `Partial` | - | No | | | colorMap | `ContinuousColorConfig \| PiecewiseColorConfig` | - | No | | | data | `readonly V[]` | - | No | | | dataKey | `string` | - | No | | | disableLine | `boolean` | `false` | No | | | disableTicks | `boolean` | `false` | No | | | domainLimit | `'nice' \| 'strict' \| ((min: number, max: number) => { min: number; max: number })` | - | No | | | height | `number` | `45 if an axis label is provided, 25 otherwise.` | No | | | hideTooltip | `boolean` | - | No | | | ignoreTooltip | `boolean` | - | No | | | label | `string` | - | No | | | labelStyle | `ChartsTextProps['style']` | - | No | | | offset | `number` | `0` | No | | | position | `'top' \| 'bottom' \| 'none'` | - | No | | | reverse | `boolean` | - | No | | | slotProps | `Partial` | `{}` | No | | | slots | `Partial` | `{}` | No | | | sx | `SxProps` | - | No | | | tickInterval | `'auto' \| ((value: any, index: number) => boolean) \| any[]` | `'auto'` | No | | | tickLabelInterval | `'auto' \| ((value: any, index: number) => boolean)` | `'auto'` | No | | | tickLabelPlacement | `'middle' \| 'tick'` | `'middle'` | No | | | tickLabelStyle | `ChartsTextProps['style']` | - | No | | | tickMaxStep | `number` | - | No | | | tickMinStep | `number` | - | No | | | tickNumber | `number` | - | No | | | tickPlacement | `'start' \| 'end' \| 'middle' \| 'extremities'` | `'extremities'` | No | | | tickSize | `number` | `6` | No | | | tickSpacing | `number` | `0` | No | | | valueFormatter | `(value: V, context: AxisValueFormatterContext) => string` | - | No | | | zoom | `boolean \| ZoomOptions` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/react-charts/axis.md --- title: Charts - Axis productId: x-charts components: ChartsAxis, ChartsReferenceLine, ChartsText, ChartsXAxis, ChartsYAxis, ChartsReferenceLine --- # Charts - Axis Define, format, and customize Chart axes. 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. ```tsx import Box from '@mui/material/Box'; import { LineChart } from '@mui/x-charts/LineChart'; const sample = [1, 10, 30, 50, 70, 90, 100]; export default function ScaleExample() { return ( ); } ``` :::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. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; const otherSetting = { height: 300, yAxis: [{ label: 'rainfall (mm)', width: 60 }], grid: { horizontal: true }, }; const dataset = [ { london: 59, paris: 57, newYork: 86, seoul: 21, month: 'January', }, { london: 50, paris: 52, newYork: 78, seoul: 28, month: 'February', }, { london: 47, paris: 53, newYork: 106, seoul: 41, month: 'March', }, { london: 54, paris: 56, newYork: 92, seoul: 73, month: 'April', }, { london: 57, paris: 69, newYork: 92, seoul: 99, month: 'May', }, { london: 60, paris: 63, newYork: 103, seoul: 144, month: 'June', }, { london: 59, paris: 60, newYork: 105, seoul: 319, month: 'July', }, { london: 65, paris: 60, newYork: 106, seoul: 249, month: 'August', }, { london: 51, paris: 51, newYork: 95, seoul: 131, month: 'September', }, { london: 60, paris: 65, newYork: 97, seoul: 55, month: 'October', }, { london: 67, paris: 64, newYork: 76, seoul: 48, month: 'November', }, { london: 61, paris: 70, newYork: 103, seoul: 25, month: 'December', }, ]; const valueFormatter = (value: number | null) => `${value}mm`; export default function FormatterDemo() { return ( context.location === 'tick' ? `${month.slice(0, 3)} \n2023` : `${month} 2023`, height: 40, }, ]} series={[{ dataKey: 'seoul', label: 'Seoul rainfall', valueFormatter }]} {...otherSetting} /> ); } ``` ### 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: ```tsx import * as React from 'react'; import { ScatterChart } from '@mui/x-charts/ScatterChart'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import RadioGroup from '@mui/material/RadioGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import Radio from '@mui/material/Radio'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; import { AxisValueFormatterContext, ScatterValueType } from '@mui/x-charts/models'; import { earthquakeData } from '../dataset/earthquakeData'; const settings = { height: 400, grid: { horizontal: true }, }; const data = Object.entries(earthquakeData).reduce( (acc, [magnitude, events]) => { acc.push({ x: Number.parseFloat(magnitude), y: events }); return acc; }, [], ); const formatter = new Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 1, }); function valueFormatterIgnoreEmpty(value: any, context: AxisValueFormatterContext) { if (context.location === 'tick' && context.defaultTickLabel === '') { return ''; } return formatter.format(value); } function valueFormatterShowAll(value: any) { return formatter.format(value); } export default function TicksWithoutLabels() { const [tickFormatter, setTickFormatter] = React.useState( () => valueFormatterIgnoreEmpty, ); return ( Worldwide Earthquake Count and Magnitude, 2020-2024 Source: US Geological Survey Tick Format setTickFormatter(() => event.target.value === 'empty' ? valueFormatterIgnoreEmpty : valueFormatterShowAll, ) } > } label="Ignore empty ticks" /> } label="Show all values" /> ); } ``` ### 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: ```tsx import { ScaleLogarithmic } from '@mui/x-charts-vendor/d3-scale'; import { LineChart } from '@mui/x-charts/LineChart'; import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; const otherSetting = { height: 300, grid: { horizontal: true, vertical: true }, }; // https://en.wikipedia.org/wiki/Low-pass_filter const f0 = 440; const frequencyResponse = (f: number) => 5 / Math.sqrt(1 + (f / f0) ** 2); const dataset = [ 0.1, 0.5, 0.8, 1, 5, 8, 10, 50, 80, 100, 500, 800, 1_000, 5_000, 8_000, 10_000, 50_000, 80_000, 100_000, 500_000, 800_000, 1_000_000, ].map((f) => ({ frequency: f, voltage: frequencyResponse(f) })); export default function FormatterD3() { return ( { if (context.location === 'tick') { const d3Text = ( context.scale as ScaleLogarithmic ).tickFormat( context.tickNumber!, 'e', )(f); return d3Text; } return `${f.toLocaleString()}Hz`; }, }, ]} yAxis={[ { scaleType: 'log', label: 'Vo/Vi', width: 60, valueFormatter: (f, context) => { if (context.location === 'tick') { const d3Text = ( context.scale as ScaleLogarithmic ).tickFormat( 30, 'f', )(f); return d3Text; } return f.toLocaleString(); }, }, ]} series={[{ dataKey: 'voltage' }]} {...otherSetting} > ); } ``` ## 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, }, ]} ``` ```tsx import * as React from 'react'; import Slider from '@mui/material/Slider'; import Box from '@mui/material/Box'; import { ScatterChart } from '@mui/x-charts/ScatterChart'; import { Chance } from 'chance'; const chance = new Chance(42); const data = Array.from({ length: 200 }, () => ({ x: chance.floating({ min: -25, max: 25 }), y: chance.floating({ min: -25, max: 25 }), })).map((d, index) => ({ ...d, id: index })); const minDistance = 10; export default function MinMaxExample() { const [value, setValue] = React.useState([-25, 25]); const handleChange = ( event: Event, newValue: number | number[], activeThumb: number, ) => { if (!Array.isArray(newValue)) { return; } if (newValue[1] - newValue[0] < minDistance) { if (activeThumb === 0) { const clamped = Math.min(newValue[0], 100 - minDistance); setValue([clamped, clamped + minDistance]); } else { const clamped = Math.max(newValue[1], minDistance); setValue([clamped - minDistance, clamped]); } } else { setValue(newValue as number[]); } }; return ( ); } ``` ### 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: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { BarChart } from '@mui/x-charts/BarChart'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; const settings = { height: 220, series: [{ data: [60, -15, 66, 68, 87, 82, 83, 85, 92, 75, 76, 50, 91] }], margin: { top: 20, bottom: 10 }, } as const; // Extend a value to match a multiple of the step. function extend(value: number, step: number) { if (value > 0) { // If >0 go to the next step return step * Math.ceil(value / step); } // If <0 go to the previous step return step * Math.floor(value / step); } export default function CustomDomainYAxis() { const [domainLimit, setDomainLimit] = React.useState< 'nice' | 'strict' | 'function' >('nice'); return ( setDomainLimit(event.target.value as 'nice' | 'strict' | 'function') } label="domain limit" sx={{ minWidth: 150, mb: 2 }} > nice strict function ({ min: extend(min, 10), max: extend(max, 10), }) : domainLimit, }, ]} {...settings} /> ); } ``` ## 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: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; import { BarPlot } from '@mui/x-charts/BarChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsGrid } from '@mui/x-charts/ChartsGrid'; import { ChartsTooltip } from '@mui/x-charts/ChartsTooltip'; const dataset = [ { min: -12, max: -4, precip: 79, month: 'Jan' }, { min: -11, max: -3, precip: 66, month: 'Feb' }, { min: -6, max: 2, precip: 76, month: 'Mar' }, { min: 1, max: 9, precip: 106, month: 'Apr' }, { min: 8, max: 17, precip: 105, month: 'Mai' }, { min: 15, max: 24, precip: 114, month: 'Jun' }, { min: 18, max: 26, precip: 106, month: 'Jul' }, { min: 17, max: 26, precip: 105, month: 'Aug' }, { min: 13, max: 21, precip: 100, month: 'Sept' }, { min: 6, max: 13, precip: 116, month: 'Oct' }, { min: 0, max: 6, precip: 93, month: 'Nov' }, { min: -8, max: -1, precip: 93, month: 'Dec' }, ]; const series = [ { type: 'line', dataKey: 'min', color: '#577399' }, { type: 'line', dataKey: 'max', color: '#fe5f55' }, { type: 'bar', dataKey: 'precip', color: '#bfdbf7', yAxisId: 'rightAxis' }, ] as const; export default function ReverseExample() { const [reverseX, setReverseX] = React.useState(false); const [reverseLeft, setReverseLeft] = React.useState(false); const [reverseRight, setReverseRight] = React.useState(false); return ( setReverseX(event.target.checked)} /> } label="reverse x-axis" labelPlacement="end" /> setReverseLeft(event.target.checked)} /> } label="reverse left axis" labelPlacement="end" /> setReverseRight(event.target.checked)} /> } label="reverse right axis" labelPlacement="end" /> ); } ``` ## 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 `` component: ```jsx ``` ```tsx import { chartsGridClasses } from '@mui/x-charts/ChartsGrid'; import { BarChart } from '@mui/x-charts/BarChart'; import { dataset, valueFormatter } from '../dataset/weather'; const chartSetting = { yAxis: [{ label: 'rainfall (mm)', width: 60 }], height: 300, }; export default function GridDemo() { return ( ); } ``` ## 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. ```tsx import Box from '@mui/material/Box'; import { LineChart } from '@mui/x-charts/LineChart'; const timeData = [ new Date(2023, 7, 31), new Date(2023, 7, 31, 12), new Date(2023, 8, 1), new Date(2023, 8, 1, 12), new Date(2023, 8, 2), new Date(2023, 8, 2, 12), new Date(2023, 8, 3), new Date(2023, 8, 3, 12), new Date(2023, 8, 4), ]; const y1 = [5, 5, 10, 90, 85, 70, 30, 25, 25]; const y2 = [90, 85, 70, 25, 23, 40, 45, 40, 50]; const valueFormatter = (date: Date) => date.getHours() === 0 ? date.toLocaleDateString('fr-FR', { month: '2-digit', day: '2-digit', }) : date.toLocaleTimeString('fr-FR', { hour: '2-digit', }); const config = { series: [{ data: y1 }, { data: y2 }], height: 300, }; const xAxisCommon = { data: timeData, scaleType: 'time', valueFormatter, } as const; export default function TickNumber() { return ( ); } ``` ### 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. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Slider from '@mui/material/Slider'; import Typography from '@mui/material/Typography'; import { BarChartPro } from '@mui/x-charts-pro/BarChartPro'; import data from '../dataset/sp500-intraday.json'; const tickLabelDateFormatter = new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric', }); export default function TickSpacing() { const [tickSpacing, setTickSpacing] = React.useState(50); return ( Tick Spacing setTickSpacing(value as number)} valueLabelDisplay="auto" min={0} max={100} step={5} sx={{ mt: 2 }} aria-labelledby="tickSpacing" /> new Date(Date.parse(d.date))), valueFormatter: (v: Date) => tickLabelDateFormatter.format(v), tickSpacing, tickPlacement: 'middle', zoom: true, }, ]} series={[{ data: data.map((d) => d.close), label: 'Close' }]} height={300} /> ); } ``` ### 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. ```tsx import Box from '@mui/material/Box'; import { ShowMarkParams } from '@mui/x-charts/models'; import { LineChart } from '@mui/x-charts/LineChart'; export default function TickPosition() { return ( time.getHours() === 0, position: 'bottom', }, { ...xAxisCommon, scaleType: 'point', position: 'top', }, ]} {...config} /> ); } const valueFormatter = (date: Date) => date.toLocaleDateString('fr-FR', { month: '2-digit', day: '2-digit', }); const timeData = [ new Date(2023, 7, 31), new Date(2023, 7, 31, 3), new Date(2023, 7, 31, 6), new Date(2023, 7, 31, 9), new Date(2023, 7, 31, 12), new Date(2023, 7, 31, 15), new Date(2023, 7, 31, 18), new Date(2023, 8, 1), new Date(2023, 8, 1, 3), new Date(2023, 8, 1, 6), new Date(2023, 8, 1, 9), new Date(2023, 8, 1, 12), new Date(2023, 8, 1, 15), new Date(2023, 8, 1, 18), new Date(2023, 8, 2), new Date(2023, 8, 2, 3), new Date(2023, 8, 2, 6), new Date(2023, 8, 2, 9), new Date(2023, 8, 2, 12), new Date(2023, 8, 2, 15), new Date(2023, 8, 2, 18), new Date(2023, 8, 3), new Date(2023, 8, 3, 3), new Date(2023, 8, 3, 6), new Date(2023, 8, 3, 9), new Date(2023, 8, 3, 12), new Date(2023, 8, 3, 15), new Date(2023, 8, 3, 18), new Date(2023, 8, 4), ]; const y1 = [ 5, 5.5, 5.3, 4.9, 5, 6.2, 8.9, 10, 15, 30, 80, 90, 94, 93, 85, 86, 75, 70, 68, 50, 20, 30, 35, 28, 25, 27, 30, 28, 25, ]; const y2 = [ 90, 93, 89, 84, 85, 83, 73, 70, 63, 32, 30, 25, 18, 19, 23, 30, 32, 36, 40, 40, 42, 45, 46, 42, 39, 40, 41, 43, 50, ]; const showMark = (params: ShowMarkParams) => { const { position } = params as ShowMarkParams; return position.getHours() === 0; }; const config = { series: [ { data: y1, showMark }, { data: y2, showMark }, ], height: 300, yAxis: [{ position: 'none' as const }], }; const xAxisCommon = { data: timeData, scaleType: 'time', valueFormatter, } as const; ``` ### 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. ```tsx import Box from '@mui/material/Box'; import { ShowMarkParams } from '@mui/x-charts/models'; import { LineChart } from '@mui/x-charts/LineChart'; export default function TickLabelPosition() { return ( [0, 12].includes(time.getHours()), tickLabelInterval: (time) => time.getHours() === 0, position: 'bottom', }, { ...xAxisCommon, id: 'topAxis', scaleType: 'point', position: 'top', }, ]} yAxis={[{ position: 'none' }]} {...config} /> ); } const valueFormatter = (date: Date) => date.toLocaleDateString('fr-FR', { month: '2-digit', day: '2-digit', }); const timeData = [ new Date(2023, 7, 31), new Date(2023, 7, 31, 3), new Date(2023, 7, 31, 6), new Date(2023, 7, 31, 9), new Date(2023, 7, 31, 12), new Date(2023, 7, 31, 15), new Date(2023, 7, 31, 18), new Date(2023, 8, 1), new Date(2023, 8, 1, 3), new Date(2023, 8, 1, 6), new Date(2023, 8, 1, 9), new Date(2023, 8, 1, 12), new Date(2023, 8, 1, 15), new Date(2023, 8, 1, 18), new Date(2023, 8, 2), new Date(2023, 8, 2, 3), new Date(2023, 8, 2, 6), new Date(2023, 8, 2, 9), new Date(2023, 8, 2, 12), new Date(2023, 8, 2, 15), new Date(2023, 8, 2, 18), new Date(2023, 8, 3), new Date(2023, 8, 3, 3), new Date(2023, 8, 3, 6), new Date(2023, 8, 3, 9), new Date(2023, 8, 3, 12), new Date(2023, 8, 3, 15), new Date(2023, 8, 3, 18), new Date(2023, 8, 4), ]; const y1 = [ 5, 5.5, 5.3, 4.9, 5, 6.2, 8.9, 10, 15, 30, 80, 90, 94, 93, 85, 86, 75, 70, 68, 50, 20, 30, 35, 28, 25, 27, 30, 28, 25, ]; const y2 = [ 90, 93, 89, 84, 85, 83, 73, 70, 63, 32, 30, 25, 18, 19, 23, 30, 32, 36, 40, 40, 42, 45, 46, 42, 39, 40, 41, 43, 50, ]; const showMark = (params: ShowMarkParams) => { const { position } = params as ShowMarkParams; return position.getHours() === 0; }; const config = { series: [ { data: y1, showMark }, { data: y2, showMark }, ], height: 300, }; const xAxisCommon = { data: timeData, scaleType: 'time', valueFormatter, } as const; ``` ### 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. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { BarChartPro } from '@mui/x-charts-pro/BarChartPro'; import { BarSeriesType, XAxis, YAxis, ZoomOptions } from '@mui/x-charts-pro/models'; import { TickFrequency } from '@mui/x-charts/models'; import alphabetStock from '../dataset/GOOGL.json'; import SelectTimeFrequency from './SelectTimeFrequency'; const tickFrequencies: TickFrequency[] = [ 'years', 'quarterly', 'months', 'biweekly', 'weeks', 'days', ]; export default function OrdinalTickPlacement() { const [ordinalTimeTicks, setOrdinalTimeTicks] = React.useState(defaultTicks); const [tickNumber, setTickNumber] = React.useState(5); return ( ordinalTimeTicks[frequency as keyof typeof ordinalTimeTicks], ), }, ]} /> ); } type FilteredTicksState = Record; const defaultTicks = Object.fromEntries( tickFrequencies.map((frequency) => [frequency, true]), ) as FilteredTicksState; const zoom: ZoomOptions = { minSpan: 1, filterMode: 'discard' }; const xAxis: XAxis = { id: 'date', data: alphabetStock.map((day) => new Date(day.date)), scaleType: 'band', zoom, valueFormatter: (value) => value.toLocaleDateString(), height: 30, }; const barSettings = { height: 200, hideLegend: true, margin: { bottom: 5 }, series: [ { type: 'bar', yAxisId: 'volume', label: 'Volume', color: 'lightgray', data: alphabetStock.map((day) => day.volume), } as BarSeriesType, ], yAxis: [ { id: 'volume', scaleType: 'linear', position: 'left', valueFormatter: (value) => `${(value / 1000000).toLocaleString()}M`, width: 55, } as YAxis, ], }; ``` 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. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { BarChartPro } from '@mui/x-charts-pro/BarChartPro'; import { BarSeriesType, XAxis, YAxis, ZoomOptions } from '@mui/x-charts-pro/models'; import { tickFrequencies } from '@mui/x-charts/utils'; import alphabetStock from '../dataset/GOOGL.json'; export default function CustomTickFrequency() { return ( ); } const quarterFormat = (d: Date) => `Q${Math.floor(d.getMonth() / 3) + 1}`; const weekFormat = (d: Date) => `W${getWeekNumber(d)}`; const zoom: ZoomOptions = { minSpan: 1, filterMode: 'discard' }; const xAxis: XAxis = { id: 'date', data: alphabetStock.map((day) => new Date(day.date)), scaleType: 'band', zoom, valueFormatter: (value) => value.toLocaleDateString(), height: 30, tickNumber: 15, }; const barSettings = { height: 200, hideLegend: true, margin: { bottom: 5 }, series: [ { type: 'bar', yAxisId: 'volume', label: 'Volume', color: 'lightgray', data: alphabetStock.map((day) => day.volume), } as BarSeriesType, ], yAxis: [ { id: 'volume', scaleType: 'linear', position: 'left', valueFormatter: (value) => `${(value / 1000000).toLocaleString()}M`, width: 55, } as YAxis, ], grid: { vertical: true, horizontal: true }, }; function getWeekNumber(date: Date) { const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); const dayNum = d.getUTCDay() || 7; d.setUTCDate(d.getUTCDate() + 4 - dayNum); const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)); return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7); } ``` ## 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 ```tsx import Box from '@mui/material/Box'; import { ScatterChart } from '@mui/x-charts/ScatterChart'; import { Chance } from 'chance'; const chance = new Chance(42); const data = Array.from({ length: 200 }, () => ({ x: chance.floating({ min: -25, max: 25 }), y: chance.floating({ min: -25, max: 25 }), })).map((d, index) => ({ ...d, id: index })); const params = { series: [{ data }], height: 300, margin: { top: 12, right: 12, bottom: 20, left: 12 }, }; export default function ModifyAxisPosition() { return ( ); } ``` ### Hiding axes To hide an axis, set its `position` to `'none'`. Note that the axis is still computed and used for scaling. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function HidingAxis() { return ( ); } ``` ### 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. ```tsx import Box from '@mui/material/Box'; import { LineChart } from '@mui/x-charts/LineChart'; const sample = [1, 10, 30, 50, 70, 90, 100]; export default function MultipleAxes() { return ( ); } ``` ## 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. ### X-axis grouping In the demo below, the x-axis is grouped by month, quarter, and year. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function GroupedAxes() { return ( ); } const getMonth = (date: Date) => date.toLocaleDateString('en-US', { month: 'short' }); const getQuarter = (date: Date) => `Q${Math.floor(date.getMonth() / 3) + 1}`; const getYear = (date: Date) => date.toLocaleDateString('en-US', { year: 'numeric' }); const valueFormatter = (v: Date) => v.toLocaleDateString('en-US', { month: 'short', year: 'numeric', }); const data = [ new Date(2014, 11, 1), new Date(2015, 0, 1), new Date(2015, 1, 1), new Date(2015, 2, 1), new Date(2015, 3, 1), new Date(2015, 4, 1), new Date(2015, 5, 1), new Date(2015, 6, 1), new Date(2015, 7, 1), new Date(2015, 8, 1), new Date(2015, 9, 1), new Date(2015, 10, 1), new Date(2015, 11, 1), new Date(2016, 0, 1), ]; const a = [ 3190, 4000, 3000, 2000, 2780, 1890, 2390, 3490, 2400, 1398, 9800, 3908, 4800, 2040, ]; const b = [ 1200, 2400, 1398, 9800, 3908, 4800, 3800, 4300, 2181, 2500, 2100, 3000, 2000, 2040, ]; const getPercents = (array: number[]) => array.map((v, index) => (100 * v) / (a[index] + b[index])); const chartConfig = { height: 200, margin: { left: 0 }, series: [ { data: getPercents(a), label: 'Income', valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, { data: getPercents(b), label: 'Expenses', valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, ], yAxis: [ { valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, ], } as const; ``` ### Y-axis grouping In the following demo, the y-axis is grouped by category and subcategory. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function GroupedYAxes() { return ( category[1] }, // Extract subcategory { getValue: (category) => category[0], tickSize: 120, tickLabelStyle: { angle: -90, textAnchor: 'middle', }, }, ], valueFormatter: (value) => value.join(' - '), }, ]} {...chartConfig} /> ); } const categoryData = [ ['Technology', 'Software'], ['Technology', 'Hardware'], ['Technology', 'AI/ML'], ['Finance', 'Banking'], ['Finance', 'Insurance'], ['Finance', 'Investment'], ['Healthcare', 'Pharmaceuticals'], ['Healthcare', 'Medical Devices'], ['Healthcare', 'Telemedicine'], ]; const salesData = [150, 120, 200, 180, 90, 160, 140, 110, 85]; const profitData = [45, 35, 80, 65, 25, 55, 50, 40, 30]; const chartConfig = { height: 400, xAxis: [{ valueFormatter: (value: number) => `${value}K` }], series: [ { data: salesData, label: 'Sales', valueFormatter: (value: number | null) => `${value}K`, }, { data: profitData, label: 'Profit', valueFormatter: (value: number | null) => `${value}K`, }, ], }; ``` ### Tick size You can customize the tick size for each group 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. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function GroupedAxesTickSize() { return ( ); } const getMonth = (date: Date) => date.toLocaleDateString('en-US', { month: 'short' }); const formatQuarterYear = (date: Date) => { const quarter = Math.floor(date.getMonth() / 3) + 1; const year = date.getFullYear().toString().slice(-2); return `Q${quarter} '${year}`; }; const valueFormatter = (v: Date) => v.toLocaleDateString('en-US', { month: 'short', year: 'numeric', }); const data = [ new Date(2015, 0, 1), new Date(2015, 1, 1), new Date(2015, 2, 1), new Date(2015, 3, 1), new Date(2015, 4, 1), new Date(2015, 5, 1), new Date(2015, 6, 1), new Date(2015, 7, 1), new Date(2015, 8, 1), new Date(2015, 9, 1), new Date(2015, 10, 1), new Date(2015, 11, 1), ]; const a = [4000, 3000, 2000, 2780, 1890, 2390, 3490, 2400, 1398, 9800, 3908, 4800]; const b = [2400, 1398, 9800, 3908, 4800, 3800, 4300, 2181, 2500, 2100, 3000, 2000]; const getPercents = (array: number[]) => array.map((v, index) => (100 * v) / (a[index] + b[index])); const chartConfig = { height: 200, margin: { left: 0 }, series: [ { data: getPercents(a), label: 'Income', valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, { data: getPercents(b), label: 'Expenses', valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, ], yAxis: [ { valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, ], } as const; ``` ### Styling grouped axes 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. ```tsx import { LineChart } from '@mui/x-charts/LineChart'; import { axisClasses } from '@mui/x-charts/ChartsAxis'; export default function GroupedAxesStyling() { return ( ); } const getMonth = (date: Date) => date.toLocaleDateString('en-US', { month: 'short' }); const formatQuarterYear = (date: Date) => { const quarter = Math.floor(date.getMonth() / 3) + 1; const year = date.getFullYear().toString().slice(-2); return `Q${quarter} '${year}`; }; const valueFormatter = (v: Date) => v.toLocaleDateString('en-US', { month: 'short', year: 'numeric', }); const data = [ new Date(2015, 0, 1), new Date(2015, 1, 1), new Date(2015, 2, 1), new Date(2015, 3, 1), new Date(2015, 4, 1), new Date(2015, 5, 1), new Date(2015, 6, 1), new Date(2015, 7, 1), new Date(2015, 8, 1), new Date(2015, 9, 1), new Date(2015, 10, 1), new Date(2015, 11, 1), new Date(2016, 0, 1), ]; const a = [ 4000, 3000, 2000, 2780, 1890, 2390, 3490, 2400, 1398, 9800, 3908, 4800, 2040, ]; const b = [ 2400, 1398, 9800, 3908, 4800, 3800, 4300, 2181, 2500, 2100, 3000, 2000, 2040, ]; const getPercents = (array: number[]) => array.map((v, index) => (100 * v) / (a[index] + b[index])); const chartConfig = { height: 200, margin: { left: 0 }, series: [ { data: getPercents(a), label: 'Income', valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, { data: getPercents(b), label: 'Expenses', valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, ], yAxis: [ { valueFormatter: (value: number | null) => `${(value ?? 0).toFixed(0)}%`, }, ], } as const; ``` ## Axis customization Beyond the axis definition, there are several other ways to further customize how axes are rendered: ### Styling axes by ID 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. ```tsx import * as React from 'react'; import { LineChart, type LineChartProps } from '@mui/x-charts/LineChart'; import { axisClasses } from '@mui/x-charts/ChartsAxis'; const years = [2010, 2011, 2012, 2013, 2014, 2015]; const revenue = [4000, 3000, 2000, 2780, 1890, 2390]; const profit = [24, 13, 98, 39, 48, 38]; const chartConfig: LineChartProps = { xAxis: [{ data: years, scaleType: 'point' }], yAxis: [ { id: 'revenue-axis', label: 'Revenue ($)' }, { id: 'profit-axis', label: 'Profit (%)', position: 'right' }, ], series: [ { data: revenue, label: 'Revenue', yAxisId: 'revenue-axis', color: '#02b2af' }, { data: profit, label: 'Profit', yAxisId: 'profit-axis', color: '#2e96ff' }, ], height: 300, }; export default function AxisIdStyling() { return ( ); } ``` ### 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/#text-customization) 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. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { BarChart } from '@mui/x-charts/BarChart'; export default function MarginAndLabelPosition() { const [fixMargin, setFixMargin] = React.useState(true); return ( setFixMargin(event.target.checked)} /> } label="Increase axes size" labelPlacement="end" /> context.location === 'tick' ? value.split('').join('\n') : usAirportPassengers.find((item) => item.code === value)!.fullName, label: 'airports', height: fixMargin ? 75 : undefined, }, ]} // Other props height={300} dataset={usAirportPassengers} series={[ { dataKey: '2018', label: '2018' }, { dataKey: '2019', label: '2019' }, { dataKey: '2020', label: '2020' }, { dataKey: '2021', label: '2021' }, { dataKey: '2022', label: '2022' }, ]} hideLegend yAxis={[ { valueFormatter: (value: number) => `${(value / 1000).toLocaleString()}k`, label: 'passengers', width: fixMargin ? 85 : undefined, }, ]} /> ); } const usAirportPassengers = [ { fullName: 'Hartsfield–Jackson Atlanta International Airport', code: 'ATL', 2022: 45396001, 2021: 36676010, 2020: 20559866, 2019: 53505795, 2018: 51865797, }, { fullName: 'Dallas/Fort Worth International Airport', code: 'DFW', 2022: 35345138, 2021: 30005266, 2020: 18593421, 2019: 35778573, 2018: 32821799, }, { fullName: 'Denver International Airport', code: 'DEN', 2022: 33773832, 2021: 28645527, 2020: 16243216, 2019: 33592945, 2018: 31362941, }, { fullName: "O'Hare International Airport", code: 'ORD', 2022: 33120474, 2021: 26350976, 2020: 14606034, 2019: 40871223, 2018: 39873927, }, { fullName: 'Los Angeles International Airport', code: 'LAX', 2022: 32326616, 2021: 23663410, 2020: 14055777, 2019: 42939104, 2018: 42624050, }, { fullName: 'John F. Kennedy International Airport', code: 'JFK', 2022: 26919982, 2021: 15273342, 2020: 8269819, 2019: 31036655, 2018: 30620769, }, { fullName: 'Harry Reid International Airport', code: 'LAS', 2022: 25480500, 2021: 19160342, 2020: 10584059, 2019: 24728361, 2018: 23795012, }, { fullName: 'Orlando International Airport', code: 'MCO', 2022: 24469733, 2021: 19618838, 2020: 10467728, 2019: 24562271, 2018: 23202480, }, { fullName: 'Miami International Airport', code: 'MIA', 2022: 23949892, 2021: 17500096, 2020: 8786007, 2019: 21421031, 2018: 21021640, }, { fullName: 'Charlotte Douglas International Airport', code: 'CLT', 2022: 23100300, 2021: 20900875, 2020: 12952869, 2019: 24199688, 2018: 22281949, }, { fullName: 'Seattle–Tacoma International Airport', code: 'SEA', 2022: 22157862, 2021: 17430195, 2020: 9462411, 2019: 25001762, 2018: 24024908, }, { fullName: 'Phoenix Sky Harbor International Airport', code: 'PHX', 2022: 21852586, 2021: 18940287, 2020: 10531436, 2019: 22433552, 2018: 21622580, }, { fullName: 'Newark Liberty International Airport', code: 'EWR', 2022: 21572147, 2021: 14514049, 2020: 7985474, 2019: 23160763, 2018: 22797602, }, { fullName: 'San Francisco International Airport', code: 'SFO', 2022: 20411420, 2021: 11725347, 2020: 7745057, 2019: 27779230, 2018: 27790717, }, { fullName: 'George Bush Intercontinental Airport', code: 'IAH', 2022: 19814052, 2021: 16242821, 2020: 8682558, 2019: 21905309, 2018: 21157398, }, { fullName: 'Logan International Airport', code: 'BOS', 2022: 17443775, 2021: 10909817, 2020: 6035452, 2019: 20699377, 2018: 20006521, }, { fullName: 'Fort Lauderdale–Hollywood International Airport', code: 'FLL', 2022: 15370165, 2021: 13598994, 2020: 8015744, 2019: 17950989, 2018: 17612331, }, { fullName: 'Minneapolis–Saint Paul International Airport', code: 'MSP', 2022: 15242089, 2021: 12211409, 2020: 7069720, 2019: 19192917, 2018: 18361942, }, { fullName: 'LaGuardia Airport', code: 'LGA', 2022: 14367463, 2021: 7827307, 2020: 4147116, 2019: 15393601, 2018: 15058501, }, { fullName: 'Detroit Metropolitan Airport', code: 'DTW', 2022: 13751197, 2021: 11517696, 2020: 6822324, 2019: 18143040, 2018: 17436837, }, ]; ``` ### Rendering The demo below illustrates all of the props available to customize axis rendering: ```tsx import Box from '@mui/material/Box'; import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { ScatterChart } from '@mui/x-charts/ScatterChart'; import { Chance } from 'chance'; const chance = new Chance(42); const data = Array.from({ length: 200 }, () => ({ x: chance.floating({ min: -25, max: 25 }), y: chance.floating({ min: -25, max: 25 }), })).map((d, index) => ({ ...d, id: index })); const defaultXAxis = { disableLine: false, disableTicks: false, fontSize: 12, label: 'My axis', tickSize: 6, }; export default function AxisCustomization() { return ( ( )} getCode={({ props, }) => `import { ScatterChart } from '@mui/x-charts/ScatterChart'; `} /> ); } ``` ### 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: ```tsx import Box from '@mui/material/Box'; import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { BarChart } from '@mui/x-charts/BarChart'; import { dataset, valueFormatter } from '../dataset/weather'; const chartSetting = { height: 300, }; export default function AxisTextCustomization() { return ( ( )} getCode={({ props }) => `import { BarChart } from '@mui/x-charts/BarChart'; `} /> ); } ``` ### 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/). ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { BarPlot } from '@mui/x-charts/BarChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsTextProps } from '@mui/x-charts/ChartsText'; import { iconMap } from '../dataset/company.icons'; function CustomTick(props: ChartsTextProps) { const { x, y, text } = props; const logo = iconMap[text]; return (
{logo && ( {text} )}
); } export default function TickLabelImage() { return ( ); } ``` ## 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. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import ToggleButton from '@mui/material/ToggleButton'; import { BarChart } from '@mui/x-charts/BarChart'; import { LineChart } from '@mui/x-charts/LineChart'; export default function SymlogScale() { const [chartType, setChartType] = React.useState('bar'); const handleChartType = (event: any, newChartType: string) => { if (newChartType !== null) { setChartType(newChartType); } }; return ( {['bar', 'area'].map((type) => ( {type} ))} {chartType === 'bar' && } {chartType === 'area' && } ); } function SymlogBarChart() { return ( ); } function SymlogAreaChart() { return ( ); } ``` ## Composition If you're using composition, you must provide the axis settings in the `` using the `xAxis` and `yAxis` props. This provides all the scaling properties to its children, and lets you use the `` and `` components as children. In turn, those components require an `axisId` prop to link them to an axis you defined in the ``. You can choose their position with the `position` prop which accepts `'top'`/`'bottom'` for `` and `'left'`/`'right'` for ``. The props described in the [rendering playground above](/x/react-charts/axis/#rendering) are also available. ```tsx import Box from '@mui/material/Box'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { LinePlot } from '@mui/x-charts/LineChart'; import { BarPlot } from '@mui/x-charts/BarChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; export default function AxisWithComposition() { return ( ); } ``` ### Reference line Use the `` 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. ```tsx import Box from '@mui/material/Box'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { LinePlot } from '@mui/x-charts/LineChart'; import { LineSeriesType } from '@mui/x-charts/models'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; const timeData = [ new Date(2023, 7, 31), new Date(2023, 7, 31, 12), new Date(2023, 8, 1), new Date(2023, 8, 1, 12), new Date(2023, 8, 2), new Date(2023, 8, 2, 12), new Date(2023, 8, 3), new Date(2023, 8, 3, 12), new Date(2023, 8, 4), ]; const y1 = [5, 5, 10, 90, 85, 70, 30, 25, 25]; const y2 = [90, 85, 70, 25, 23, 40, 45, 40, 50]; const config = { series: [ { type: 'line', data: y1 }, { type: 'line', data: y2 }, ] as LineSeriesType[], height: 400, xAxis: [ { data: timeData, scaleType: 'time', valueFormatter: (date: Date) => date.getHours() === 0 ? date.toLocaleDateString('fr-FR', { month: '2-digit', day: '2-digit', }) : date.toLocaleTimeString('fr-FR', { hour: '2-digit', }), } as const, ], }; export default function ReferenceLine() { return ( ); } ``` --- # Source: https://mui.com/x/api/charts/bar-chart-premium.md # BarChartPremium API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Range Bar ## Import ```jsx import { BarChartPremium } from '@mui/x-charts-premium/BarChartPremium'; // or import { BarChartPremium } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | axisHighlight | `{ x?: 'band' \| 'line' \| 'none', y?: 'band' \| 'line' \| 'none' }` | - | No | | | borderRadius | `number` | - | No | | | brushConfig | `{ enabled?: bool, preventHighlight?: bool, preventTooltip?: bool }` | - | No | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | disableAxisListener | `bool` | `false` | No | | | grid | `{ horizontal?: bool, vertical?: bool }` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'bar' }>` | - | No | | | hideLegend | `bool` | - | No | | | highlightedAxis | `Array<{ axisId: number \| string, dataIndex: number }>` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'bar' }>` | - | No | | | initialZoom | `Array<{ axisId: number \| string, end: number, start: number }>` | - | No | | | layout | `'horizontal' \| 'vertical'` | `'vertical'` | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onAxisClick | `function(event: MouseEvent, data: null \| ChartsAxisData) => void` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onHighlightedAxisChange | `function(axisItems: Array) => void` | - | No | | | onItemClick | `function(event: React.MouseEvent, itemIdentifier: BarItemIdentifier \| RangeBarItemIdentifier) => void` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | onZoomChange | `function(zoomData: Array) => void` | - | No | | | renderer | `'svg-batch' \| 'svg-single'` | `'svg-single'` | No | | | showToolbar | `bool` | `false` | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex: number, seriesId: number \| string, type: 'bar' }` | - | No | | | width | `number` | - | No | | | xAxis | `Array<{ axis?: 'x', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool }>` | - | No | | | yAxis | `Array<{ axis?: 'y', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool }>` | - | No | | | zAxis | `Array<{ colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, id?: string, max?: number, min?: number }>` | - | No | | | zoomData | `Array<{ axisId: number \| string, end: number, start: number }>` | - | No | | | zoomInteractionConfig | `{ pan?: Array<'drag' \| 'pressAndDrag' \| 'wheel' \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'drag' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'pressAndDrag' } \| { allowedDirection?: 'x' \| 'xy' \| 'y', pointerMode?: any, requiredKeys?: Array, type: 'wheel' }>, zoom?: Array<'brush' \| 'doubleTapReset' \| 'pinch' \| 'tapAndDrag' \| 'wheel' \| { pointerMode?: any, requiredKeys?: Array, type: 'wheel' } \| { pointerMode?: any, requiredKeys?: array, type: 'pinch' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'tapAndDrag' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'doubleTapReset' } \| { pointerMode?: any, requiredKeys?: array, type: 'brush' }> }` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-premium/src/BarChartPremium/BarChartPremium.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-premium/src/BarChartPremium/BarChartPremium.tsx) --- # Source: https://mui.com/x/api/charts/bar-chart-pro.md # BarChartPro API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Bars](/x/react-charts/bars/) - Charts - Export - Charts - Zoom and pan ## Import ```jsx import { BarChartPro } from '@mui/x-charts-pro/BarChartPro'; // or import { BarChartPro } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | axisHighlight | `{ x?: 'band' \| 'line' \| 'none', y?: 'band' \| 'line' \| 'none' }` | - | No | | | borderRadius | `number` | - | No | | | brushConfig | `{ enabled?: bool, preventHighlight?: bool, preventTooltip?: bool }` | - | No | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | disableAxisListener | `bool` | `false` | No | | | grid | `{ horizontal?: bool, vertical?: bool }` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'bar' }>` | - | No | | | hideLegend | `bool` | - | No | | | highlightedAxis | `Array<{ axisId: number \| string, dataIndex: number }>` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'bar' }>` | - | No | | | initialZoom | `Array<{ axisId: number \| string, end: number, start: number }>` | - | No | | | layout | `'horizontal' \| 'vertical'` | `'vertical'` | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onAxisClick | `function(event: MouseEvent, data: null \| ChartsAxisData) => void` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onHighlightedAxisChange | `function(axisItems: Array) => void` | - | No | | | onItemClick | `function(event: React.MouseEvent, barItemIdentifier: BarItemIdentifier) => void` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | onZoomChange | `function(zoomData: Array) => void` | - | No | | | renderer | `'svg-batch' \| 'svg-single'` | `'svg-single'` | No | | | showToolbar | `bool` | `false` | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex: number, seriesId: number \| string, type: 'bar' }` | - | No | | | width | `number` | - | No | | | xAxis | `Array<{ axis?: 'x', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool }>` | - | No | | | yAxis | `Array<{ axis?: 'y', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool }>` | - | No | | | zAxis | `Array<{ colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, id?: string, max?: number, min?: number }>` | - | No | | | zoomData | `Array<{ axisId: number \| string, end: number, start: number }>` | - | No | | | zoomInteractionConfig | `{ pan?: Array<'drag' \| 'pressAndDrag' \| 'wheel' \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'drag' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'pressAndDrag' } \| { allowedDirection?: 'x' \| 'xy' \| 'y', pointerMode?: any, requiredKeys?: Array, type: 'wheel' }>, zoom?: Array<'brush' \| 'doubleTapReset' \| 'pinch' \| 'tapAndDrag' \| 'wheel' \| { pointerMode?: any, requiredKeys?: Array, type: 'wheel' } \| { pointerMode?: any, requiredKeys?: array, type: 'pinch' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'tapAndDrag' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'doubleTapReset' } \| { pointerMode?: any, requiredKeys?: array, type: 'brush' }> }` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | axisLabel | `ChartsText` | - | Custom component for axis label. | | axisLine | `'line'` | - | Custom component for the axis main line. | | axisTick | `'line'` | - | Custom component for the axis tick. | | axisTickLabel | `ChartsText` | - | Custom component for tick label. | | bar | `BarElementPath` | - | The component that renders the bar. | | barLabel | `BarLabel` | - | The component that renders the bar label. | | baseButton | `undefined` | - | | | baseDivider | `undefined` | - | | | baseIconButton | `undefined` | - | | | baseMenuItem | `undefined` | - | | | baseMenuList | `undefined` | - | | | basePopper | `undefined` | - | | | baseTooltip | `undefined` | - | | | exportIcon | `ChartsExportIcon` | - | Icon displayed on the toolbar's export button. | | legend | `ChartsLegend` | - | Custom rendering of the legend. | | loadingOverlay | `ChartsLoadingOverlay` | - | Overlay component rendered when the chart is in a loading state. | | noDataOverlay | `ChartsNoDataOverlay` | - | Overlay component rendered when the chart has no data to display. | | toolbar | `ChartsToolbar` | - | Custom component for the toolbar. | | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | | zoomInIcon | `ChartsZoomInIcon` | - | Icon displayed on the toolbar's zoom in button. | | zoomOutIcon | `ChartsZoomOutIcon` | - | Icon displayed on the toolbar's zoom out button. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/BarChartPro/BarChartPro.tsx) --- # Source: https://mui.com/x/api/charts/bar-chart.md # BarChart API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Bar demos](/x/react-charts/bar-demo/) - [Charts - Bars](/x/react-charts/bars/) - [Charts - Label](/x/react-charts/label/) ## Import ```jsx import { BarChart } from '@mui/x-charts/BarChart'; // or import { BarChart } from '@mui/x-charts'; // or import { BarChart } from '@mui/x-charts-pro'; // or import { BarChart } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | axisHighlight | `{ x?: 'band' \| 'line' \| 'none', y?: 'band' \| 'line' \| 'none' }` | - | No | | | borderRadius | `number` | - | No | | | brushConfig | `{ enabled?: bool, preventHighlight?: bool, preventTooltip?: bool }` | - | No | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | disableAxisListener | `bool` | `false` | No | | | grid | `{ horizontal?: bool, vertical?: bool }` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'bar' }>` | - | No | | | hideLegend | `bool` | - | No | | | highlightedAxis | `Array<{ axisId: number \| string, dataIndex: number }>` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'bar' }>` | - | No | | | layout | `'horizontal' \| 'vertical'` | `'vertical'` | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onAxisClick | `function(event: MouseEvent, data: null \| ChartsAxisData) => void` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onHighlightedAxisChange | `function(axisItems: Array) => void` | - | No | | | onItemClick | `function(event: React.MouseEvent, barItemIdentifier: BarItemIdentifier) => void` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | renderer | `'svg-batch' \| 'svg-single'` | `'svg-single'` | No | | | showToolbar | `bool` | `false` | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex: number, seriesId: number \| string, type: 'bar' }` | - | No | | | width | `number` | - | No | | | xAxis | `Array<{ axis?: 'x', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func }>` | - | No | | | yAxis | `Array<{ axis?: 'y', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number }>` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). > Any other props supplied will be provided to the root element (native element). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | axisLabel | `ChartsText` | - | Custom component for axis label. | | axisLine | `'line'` | - | Custom component for the axis main line. | | axisTick | `'line'` | - | Custom component for the axis tick. | | axisTickLabel | `ChartsText` | - | Custom component for tick label. | | bar | `BarElementPath` | - | The component that renders the bar. | | barLabel | `BarLabel` | - | The component that renders the bar label. | | baseButton | `undefined` | - | | | baseIconButton | `undefined` | - | | | legend | `ChartsLegend` | - | Custom rendering of the legend. | | loadingOverlay | `ChartsLoadingOverlay` | - | Overlay component rendered when the chart is in a loading state. | | noDataOverlay | `ChartsNoDataOverlay` | - | Overlay component rendered when the chart has no data to display. | | toolbar | `ChartsToolbar` | - | Custom component for the toolbar. | | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/BarChart/BarChart.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/BarChart/BarChart.tsx) --- # Source: https://mui.com/x/react-charts/bar-demo.md --- title: Charts - Bar demos productId: x-charts components: BarChart, BarElement, BarPlot --- # Charts - Bar demos This page groups demos using bar charts. ## TinyBarChart ```tsx import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { BarPlot } from '@mui/x-charts/BarChart'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function TinyBarChart() { return ( ); } ``` ## SimpleBarChart ```tsx import Box from '@mui/material/Box'; import { BarChart } from '@mui/x-charts/BarChart'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function SimpleBarChart() { return ( ); } ``` ## StackedBarChart ```tsx import Box from '@mui/material/Box'; import { BarChart } from '@mui/x-charts/BarChart'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function StackedBarChart() { return ( ); } ``` ## MixedBarChart ```tsx import Box from '@mui/material/Box'; import { BarChart } from '@mui/x-charts/BarChart'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const amtData = [2400, 2210, 2290, 2000, 2181, 2500, 2100]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function MixedBarChart() { return ( ); } ``` ## PositiveAndNegativeBarChart ```tsx import Box from '@mui/material/Box'; import { BarChart } from '@mui/x-charts/BarChart'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, -9800, 3908, 4800, -3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function PositiveAndNegativeBarChart() { return ( ); } ``` ## BarChartStackedBySign ```tsx import Box from '@mui/material/Box'; import { BarChart } from '@mui/x-charts/BarChart'; const pData = [2400, 1398, -9800, 3908, 4800, -3800, 4300]; const uData = [4000, -3000, -2000, 2780, -1890, 2390, 3490]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function BarChartStackedBySign() { return ( ); } ``` ## BiaxialBarChart ```tsx import { BarChart } from '@mui/x-charts/BarChart'; import Box from '@mui/material/Box'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function BiaxialBarChart() { return ( ); } ``` ## Population pyramid ```tsx import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { BarChart } from '@mui/x-charts/BarChart'; const ageGroups = [ '100+ yrs', '95-99 yrs', '90-94 yrs', '85-89 yrs', '80-84 yrs', '75-79 yrs', '70-74 yrs', '65-69 yrs', '60-64 yrs', '55-59 yrs', '50-54 yrs', '45-49 yrs', '40-44 yrs', '35-39 yrs', '30-34 yrs', '25-29 yrs', '20-24 yrs', '15-19 yrs', '10-14 yrs', '5-9 yrs', '0-4 yrs', ]; const male = [ 1139, 8291, 50323, 201240, 476263, 696606, 1012668, 1478069, 2042614, 2068112, 2258061, 2061862, 2067075, 1808706, 1796779, 1933726, 1620461, 1183580, 1189663, 1097221, 766227, ]; const female = [ 5770, 36739, 168603, 445118, 762492, 899933, 1152098, 1585781, 2105499, 2045845, 2231491, 2000130, 1967944, 1673805, 1593655, 1695058, 1484776, 1104293, 1122176, 1044863, 727814, ]; const numberFormatter = Intl.NumberFormat('en-US', { useGrouping: true, }); const numberWithSuffixFormatter = new Intl.NumberFormat('en-US', { notation: 'compact', }); const valueFormatter = (population: number | null) => population ? `${numberFormatter.format(Math.abs(population))}` : ''; export default function PopulationPyramidBarChart() { return ( South Korea Population Pyramid - 2022 -population), label: 'Male', type: 'bar', valueFormatter, stack: 'stack', }, { data: female, label: 'Female', type: 'bar', valueFormatter, stack: 'stack', }, ]} yAxis={[ { data: ageGroups, width: 60, tickLabelInterval: (value, index) => index % 2 === 0, disableLine: true, disableTicks: true, }, ]} xAxis={[ { valueFormatter: (population: number) => numberWithSuffixFormatter.format(Math.abs(population)), disableLine: true, disableTicks: true, domainLimit(min, max) { const extremum = Math.max(-min, max); const roundedExtremum = Math.ceil(extremum / 100_000) * 100_000; return { min: -roundedExtremum, max: roundedExtremum }; }, }, ]} grid={{ vertical: true }} /> Source: KOSIS ); } ``` ## Waterfall Chart [](/x/introduction/licensing/#premium-plan 'Premium plan') The following demo shows a waterfall chart built using a [range bar chart](/x/react-charts/range-bar/). ```tsx import * as React from 'react'; import { useTheme } from '@mui/system'; import { rainbowSurgePalette } from '@mui/x-charts/colorPalettes'; import { BarChartPremium } from '@mui/x-charts-premium/BarChartPremium'; const dollarFormatter = new Intl.NumberFormat('en-US', { style: 'currency', compactDisplay: 'short', currency: 'USD', maximumFractionDigits: 0, }); export default function WaterfallChart() { const theme = useTheme(); const palette = rainbowSurgePalette(theme.palette.mode); const blue = palette[0]; const red = palette[2]; const green = palette[4]; return ( dollarFormatter.format(value), }, ]} series={[ { type: 'rangeBar', data: [ [0, 500_000], [500_000, 650_000], [650_000, 730_000], [730_000, 530_000], [530_000, 455_000], [455_000, 335_000], [335_000, 280_000], [0, 280_000], ], valueFormatter: (value) => value === null ? null : dollarFormatter.format(value[1] - value[0]), colorGetter: (data) => { const value = data?.value; if (value == null || value[0] === 0) { return blue; } return value[1] - value[0] >= 0 ? green : red; }, }, ]} height={300} /> ); } ``` --- # Source: https://mui.com/x/api/charts/bar-element.md # BarElement API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Bar demos](/x/react-charts/bar-demo/) - [Charts - Bars](/x/react-charts/bars/) ## Import ```jsx import { BarElement } from '@mui/x-charts/BarChart'; // or import { BarElement } from '@mui/x-charts'; // or import { BarElement } from '@mui/x-charts-pro'; // or import { BarElement } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | bar | `BarElementPath` | - | The component that renders the bar. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | faded | Styles applied to the root element if it is faded. | | - | highlighted | Styles applied to the root element if it is highlighted. | | - | root | Styles applied to the root element. | | - | series | Styles applied to the root element for a specified series. Needs to be suffixed with the series ID: `.${barElementClasses.series}-${seriesId}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/BarChart/BarElement.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/BarChart/BarElement.tsx) --- # Source: https://mui.com/x/api/charts/bar-label.md # BarLabel API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Bars](/x/react-charts/bars/) ## Import ```jsx import { BarLabel } from '@mui/x-charts/BarChart'; // or import { BarLabel } from '@mui/x-charts'; // or import { BarLabel } from '@mui/x-charts-pro'; // or import { BarLabel } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | height | `number` | - | Yes | | | width | `number` | - | Yes | | | x | `number` | - | Yes | | | xOrigin | `number` | - | Yes | | | y | `number` | - | Yes | | | yOrigin | `number` | - | Yes | | | hidden | `bool` | - | No | | | placement | `'center' \| 'outside'` | `'center'` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | barLabel | `BarLabel` | - | The component that renders the bar label. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | animate | Styles applied to the root element if it is animated. | | - | faded | Styles applied to the root element if it is faded. | | - | highlighted | Styles applied to the root element if it is highlighted. | | - | root | Styles applied to the root element. | | - | series | Styles applied to the root element for a specified series. Needs to be suffixed with the series ID: `.${barLabelClasses.series}-${seriesId}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/BarChart/BarLabel/BarLabel.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/BarChart/BarLabel/BarLabel.tsx) --- # Source: https://mui.com/x/api/charts/bar-plot.md # BarPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Bar demos](/x/react-charts/bar-demo/) - [Charts - Bars](/x/react-charts/bars/) ## Import ```jsx import { BarPlot } from '@mui/x-charts/BarChart'; // or import { BarPlot } from '@mui/x-charts'; // or import { BarPlot } from '@mui/x-charts-pro'; // or import { BarPlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | borderRadius | `number` | - | No | | | onItemClick | `function(event: React.MouseEvent, barItemIdentifier: BarItemIdentifier) => void` | - | No | | | renderer | `'svg-batch' \| 'svg-single'` | `'svg-single'` | No | | | skipAnimation | `bool` | `undefined` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | bar | `BarElementPath` | - | The component that renders the bar. | | barLabel | `BarLabel` | - | The component that renders the bar label. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/BarChart/BarPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/BarChart/BarPlot.tsx) --- # Source: https://mui.com/x/api/charts/bar-series.md # BarSeries API ## Import ```jsx import { BarSeries } from '@mui/x-charts-premium' // or import { BarSeries } from '@mui/x-charts-pro' // or import { BarSeries } from '@mui/x-charts' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | type | `'bar'` | - | Yes | | | barLabel | `'value' \| ((item: BarItem, context: BarLabelContext) => string \| null \| undefined)` | - | No | | | barLabelPlacement | `'center' \| 'outside'` | `'center'` | No | | | color | `string` | - | No | | | colorGetter | `(data: ColorCallbackValue) => string` | - | No | | | data | `ReadonlyArray` | - | No | | | dataKey | `string` | - | No | | | highlightScope | `HighlightScope` | - | No | | | id | `SeriesId` | - | No | | | label | `string \| ((location: 'tooltip' \| 'legend') => string)` | - | No | | | labelMarkType | `ChartsLabelMarkType` | - | No | | | layout | `'horizontal' \| 'vertical'` | `'vertical'` | No | | | minBarSize | `number` | `0px` | No | | | stack | `string` | - | No | | | stackOffset | `StackOffsetType` | `'diverging'` | No | | | stackOrder | `StackOrderType` | `'none'` | No | | | valueFormatter | `SeriesValueFormatter` | - | No | | | xAxisId | `AxisId` | - | No | | | yAxisId | `AxisId` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/react-charts/bars.md --- title: React Bar chart productId: x-charts components: BarChart, BarChartPro, BarElement, BarPlot, ChartsGrid, BarLabel --- # Charts - Bars Bar charts express quantities through a bar's length, using a common baseline. ## Overview Bar charts are ideal for comparing discrete categories. They excel at visualizing differences in magnitude across categories (or a group of categories), highlight trends, and compare proportions at a glance. The categories can represent progressive values such as time periods, or independent groups such as products, countries, age brackets, etc. Here are the basic requirements to create a bar chart: - One categorical dimension (x-axis for vertical bars, y-axis for horizontal bars) - One or more numerical metric for length of each bar The horizontal bar chart below compares voter turnout in some European countries: ```tsx import * as React from 'react'; import { useTheme, styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import { BarChart, type BarLabelProps, type BarProps } from '@mui/x-charts/BarChart'; import { useAnimate, useAnimateBar, useDrawingArea } from '@mui/x-charts/hooks'; import { PiecewiseColorLegend } from '@mui/x-charts/ChartsLegend'; import { interpolateObject } from '@mui/x-charts-vendor/d3-interpolate'; import Box from '@mui/material/Box'; import votesTurnout from '../dataset/votes.json'; export default function ShinyBarChartHorizontal() { return ( European countries with lowest & highest voter turnout `${value}%`, }, ]} layout="horizontal" xAxis={[ { id: 'color', min: 0, max: 100, colorMap: { type: 'piecewise', thresholds: [50, 85], colors: ['#d32f2f', '#78909c', '#1976d2'], }, valueFormatter: (value: number) => `${value}%`, }, ]} barLabel={(v) => `${v.value}%`} yAxis={[ { scaleType: 'band', dataKey: 'country', width: 140, }, ]} slots={{ legend: PiecewiseColorLegend, barLabel: BarLabelAtBase, bar: BarShadedBackground, }} slotProps={{ legend: { axisDirection: 'x', markType: 'square', labelPosition: 'inline-start', labelFormatter: ({ index }) => { if (index === 0) { return 'lowest turnout'; } if (index === 1) { return 'average'; } return 'highest turnout'; }, }, }} /> ); } export function BarShadedBackground(props: BarProps) { const { ownerState, skipAnimation, id, dataIndex, xOrigin, yOrigin, ...other } = props; const theme = useTheme(); const animatedProps = useAnimateBar(props); const { width } = useDrawingArea(); return ( ); } const Text = styled('text')(({ theme }) => ({ ...theme?.typography?.body2, stroke: 'none', fill: (theme.vars || theme).palette.common.white, transition: 'opacity 0.2s ease-in, fill 0.2s ease-in', textAnchor: 'start', dominantBaseline: 'central', pointerEvents: 'none', fontWeight: 600, })); function BarLabelAtBase(props: BarLabelProps) { const { seriesId, dataIndex, color, isFaded, isHighlighted, classes, xOrigin, yOrigin, x, y, width, height, layout, skipAnimation, ...otherProps } = props; const animatedProps = useAnimate( { x: xOrigin + 8, y: y + height / 2 }, { initialProps: { x: xOrigin, y: y + height / 2 }, createInterpolator: interpolateObject, transformProps: (p) => p, applyProps: (element: SVGTextElement, p) => { element.setAttribute('x', p.x.toString()); element.setAttribute('y', p.y.toString()); }, skip: skipAnimation, }, ); return ; } ``` ## Basics Bar charts series should contain a `data` property containing an array of values. You can specify bar ticks with the `xAxis` prop. This axis might have `scaleType='band'` and its `data` should have the same length as your series. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function BasicBars() { return ( ); } ``` ### 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 axis, thanks to the `dataKey` property. For example `xAxis={[{ dataKey: 'x'}]}` or `series={[{ dataKey: 'y'}]}`. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; import { dataset, valueFormatter } from '../dataset/weather'; const chartSetting = { yAxis: [ { label: 'rainfall (mm)', width: 60, }, ], height: 300, }; export default function BarsDataset() { return ( ); } ``` ## 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. And a value of `-1` will make bars overlap on top of each other. ```tsx import Typography from '@mui/material/Typography'; import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { BarChart } from '@mui/x-charts/BarChart'; import { balanceSheet, addLabels } from './netflixsBalanceSheet'; const series = addLabels([ { dataKey: 'totAss' }, { dataKey: 'totLia', stack: 'passive' }, { dataKey: 'totEq', stack: 'passive' }, ]); export default function BarGap() { return ( (
Netflix balance sheet `$ ${v / 1000000}B` }]} hideLegend />
)} getCode={({ props }) => { return `import { BarChart } from '@mui/x-charts/BarChart'; `; }} /> ); } ``` ## Stacking Bar series accept a string property named `stack`. Series with the same `stack` value are stacked on top of each other. ```tsx import Typography from '@mui/material/Typography'; import { BarChart, BarChartProps } from '@mui/x-charts/BarChart'; import { addLabels, balanceSheet, valueFormatter } from './netflixsBalanceSheet'; export default function StackBars() { return (
Netflix balance sheet
); } const config: Partial = { height: 350, margin: { left: 0 }, yAxis: [{ width: 50, valueFormatter }], hideLegend: true, }; ``` ### Stacking strategy You can use the `stackOffset` and `stackOrder` properties to define how the series will be stacked. By default, they are stacked in the order you defined them, with positive values stacked above 0 and negative values stacked below 0. For more information, see [stacking docs](/x/react-charts/stacking/). ## Layout ### Bar direction Bar charts can be rendered with a horizontal layout by providing the `layout="horizontal"` prop. If you're using [composition](/x/react-charts/composition/), you should set the property `layout: 'horizontal'` to each bar series object. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; import { dataset, valueFormatter } from '../dataset/weather'; const chartSetting = { xAxis: [ { label: 'rainfall (mm)', }, ], height: 400, margin: { left: 0 }, }; export default function HorizontalBars() { return ( ); } ``` ### Tick placement When using a `"band"` scale, the axis has some additional customization properties about 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: ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; import RadioGroup from '@mui/material/RadioGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import Radio from '@mui/material/Radio'; import { BarChart } from '@mui/x-charts/BarChart'; import { dataset, valueFormatter } from '../dataset/weather'; type TickParamsSelectorProps = { tickPlacement: 'end' | 'start' | 'middle' | 'extremities'; tickLabelPlacement: 'tick' | 'middle'; setTickPlacement: React.Dispatch< React.SetStateAction<'end' | 'start' | 'middle' | 'extremities'> >; setTickLabelPlacement: React.Dispatch>; }; function TickParamsSelector({ tickPlacement, tickLabelPlacement, setTickPlacement, setTickLabelPlacement, }: TickParamsSelectorProps) { return ( tickPlacement setTickPlacement( event.target.value as 'start' | 'end' | 'middle' | 'extremities', ) } > } label="start" /> } label="end" /> } label="middle" /> } label="extremities" /> tickLabelPlacement setTickLabelPlacement(event.target.value as 'tick' | 'middle') } > } label="tick" /> } label="middle" /> ); } const chartSetting = { yAxis: [ { label: 'rainfall (mm)', width: 60, }, ], series: [{ dataKey: 'seoul', label: 'Seoul rainfall', valueFormatter }], height: 300, margin: { left: 0 }, }; export default function TickPlacementBars() { const [tickPlacement, setTickPlacement] = React.useState< 'start' | 'end' | 'middle' | 'extremities' >('middle'); const [tickLabelPlacement, setTickLabelPlacement] = React.useState< 'middle' | 'tick' >('middle'); return (
); } ``` ### Date axis If your band axis represents dates in a usual way (they are sorted and evenly spaced), you can set `ordinalTimeTicks` to pick some date frequencies. This modifies the [tick management](/x/react-charts/axis/#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. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; import { BarChart } from '@mui/x-charts/BarChart'; // Create sparse data where some bars would be very small const sparseData: (number | null)[] = [0.02, 5, null, 7, 0.01, 0, -0.03]; export default function MinBarSize(): React.JSX.Element { const [minBarSize, setMinBarSize] = React.useState(10); const handleChange = (event: Event, newValue: number | number[]) => { if (typeof newValue !== 'number') { return; } setMinBarSize(newValue); }; return ( minBarSize: {minBarSize}px `${v}`), scaleType: 'band' }]} series={[{ data: sparseData, minBarSize }]} height={300} width={400} /> ); } ``` ### 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/#grid) documentation for more information. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; import { dataset, valueFormatter } from '../dataset/weather'; const chartSetting = { xAxis: [{ label: 'rainfall (mm)' }], height: 400, margin: { left: 0 }, }; export default function GridDemo() { return ( ); } ``` ### 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 axes `colorMap` which maps values to colors. The bar charts use by priority: 1. The value axis color 2. The band axis color 3. The series color Learn more about the `colorMap` properties in the [Styling docs](/x/react-charts/styling/#values-color). ```tsx import * as React from 'react'; import { BarChart } from '@mui/x-charts/BarChart'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; const series = [{ data: [-2, -9, 12, 11, 6, -4] }]; export default function ColorScale() { const [colorX, setColorX] = React.useState< 'None' | 'piecewise' | 'continuous' | 'ordinal' >('piecewise'); const [colorY, setColorY] = React.useState<'None' | 'piecewise' | 'continuous'>( 'None', ); return ( setColorX( event.target.value as 'None' | 'piecewise' | 'continuous' | 'ordinal', ) } > None piecewise continuous ordinal setColorY(event.target.value as 'None' | 'piecewise' | 'continuous') } > None piecewise continuous value.getFullYear().toString(), colorMap: (colorX === 'ordinal' && { type: 'ordinal', colors: [ '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#08589e', ], }) || (colorX === 'continuous' && { type: 'continuous', min: new Date(2019, 1, 1), max: new Date(2024, 1, 1), color: ['green', 'orange'], }) || (colorX === 'piecewise' && { type: 'piecewise', thresholds: [new Date(2021, 1, 1), new Date(2023, 1, 1)], colors: ['blue', 'red', 'blue'], }) || undefined, }, ]} margin={{ left: 0 }} /> `, ].join('\n')} language="jsx" copyButtonHidden /> ); } ``` ### Border radius To give your bar chart rounded corners, you can change the value of the `borderRadius` property on the [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 using composition, you can set the `borderRadius` prop on the `BarPlot` component. ```tsx import * as React from 'react'; import { BarChart, BarChartProps } from '@mui/x-charts/BarChart'; import Stack from '@mui/material/Stack'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import Slider from '@mui/material/Slider'; import Typography from '@mui/material/Typography'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; export default function BorderRadius() { const [layout, setLayout] = React.useState<'horizontal' | 'vertical'>('vertical'); const [radius, setRadius] = React.useState(10); const [reverse, setReverse] = React.useState(false); return ( Border Radius setRadius(value as number)} valueLabelDisplay="auto" min={0} max={50} sx={{ mt: 2 }} /> setLayout(event.target.value as 'horizontal' | 'vertical') } > Horizontal Vertical setReverse(event.target.checked)} /> } label="Reverse" labelPlacement="end" /> `} language="jsx" copyButtonHidden /> ); } const dataset = [ [3, -7, '1st'], [0, -5, '2nd'], [10, 0, '3rd'], [9, 6, '4th'], ].map(([high, low, order]) => ({ high, low, order, })); function getChartSettings( layout: 'vertical' | 'horizontal', reverse: boolean, ): Partial { return { dataset, height: 300, xAxis: layout === 'horizontal' ? [{ reverse }] : [{ dataKey: 'order' }], yAxis: layout === 'horizontal' ? [{ scaleType: 'band', dataKey: 'order' }] : [{ reverse }], slotProps: { legend: { direction: 'horizontal', position: { vertical: 'bottom', horizontal: 'center' }, }, }, }; } ``` ### 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. ```tsx import * as React from 'react'; import { BarChart, barClasses, barElementClasses, barLabelClasses, } from '@mui/x-charts/BarChart'; const settings = { xAxis: [{ data: ['group A', 'group B', 'group C'] }], series: [ { id: '1', data: [4, 3, 5] }, { id: '2', data: [1, 6, 3] }, { id: '3', data: [2, 5, 6] }, ], height: 300, barLabel: 'value', margin: { left: 0 }, } as const; export default function BarGradient() { return ( ); } function Gradient(props: React.SVGProps) { return ( ); } ``` ### 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. `userSpaceOnUse` means that the gradient's coordinates are relative to the SVG, meaning that 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. ```tsx import * as React from 'react'; import { BarChart, BarChartProps, barElementClasses } from '@mui/x-charts/BarChart'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; import RadioGroup from '@mui/material/RadioGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import Radio from '@mui/material/Radio'; import { countryData } from '../dataset/countryData'; import householdSavings from '../dataset/oecdHouseholdSavings2024.json'; /* Source: https://www.oecd.org/en/data/indicators/household-savings.html */ const savings = Object.entries(householdSavings) .map(([country, value]) => ({ country, value, })) .sort((a, b) => a.value - b.value); const percentageFormatter = new Intl.NumberFormat('en-US', { style: 'percent', maximumFractionDigits: 1, }); const settings = { height: 600, xAxis: [{ label: 'Household Savings (%)' }], layout: 'horizontal', hideLegend: true, } satisfies Partial; export default function BarOECDHouseholdSavings() { const [gradientUnits, setGradientUnits] = React.useState< 'objectBoundingBox' | 'userSpaceOnUse' >('userSpaceOnUse'); return ( Household Savings in OECD Countries (2016) Gradient Units setGradientUnits( event.target.value as 'objectBoundingBox' | 'userSpaceOnUse', ) } > } label="objectBoundingBox (default)" /> } label="userSpaceOnUse" /> v.country), valueFormatter: (value: keyof typeof countryData) => countryData[value].country, width: 100, }, ]} series={[ { label: 'Household Savings', data: savings.map((v) => v.value), color: 'url(#savings-gradient)', valueFormatter: (value) => percentageFormatter.format(value! / 100), }, ]} sx={ gradientUnits === 'userSpaceOnUse' ? { [`.${barElementClasses.root}`]: { fill: 'url(#savings-gradient-user-space)', }, } : undefined } > Source: Our World in Data ); } function Gradient(props: React.SVGProps) { return ( ); } ``` Note that, in the example above, there are two gradients: - 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. - 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. ## 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 format the value of the second series as US dollars. The labels of the third series are hidden. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; const dollarFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0, }); export default function BarLabel() { return ( dollarFormatter.format(item.value!), }, { data: [2, 5, 6] }, ]} height={300} margin={{ left: 0 }} yAxis={[{ width: 30 }]} /> ); } ``` ### Label placement The position of the bar label can be customized. To do so, 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 the view of the origin. For a vertical positive bar, the label is above its top edge; for a horizontal negative bar, the label is placed to the left of its leftmost limit. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function BarLabelPlacement() { return ( ); } ``` :::info When using `outside` placement, if the label does not fit in the chart area, it will be clipped. To avoid this, you can decrease/increase the axis min/max respectively so that there's enough space for the labels. ::: ### Custom labels You can display, change, or hide labels based on conditional logic. To do so, provide a function to the `barLabel`. Labels are not displayed if the function returns `null`. In the example we display a `'High'` text on values higher than 10, and hide values when the generated bar height is lower than 60px. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function CustomLabels() { return ( { if ((item.value ?? 0) > 10) { return 'High'; } return context.bar.height < 60 ? null : item.value?.toString(); }} height={350} margin={{ left: 0 }} /> ); } ``` You can further customize the labels by providing a component to the `barLabel` slot. In the example below, we position the labels above the bars they refer to. ```tsx import { useAnimate } from '@mui/x-charts/hooks'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { BarLabelProps, BarPlot } from '@mui/x-charts/BarChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { styled } from '@mui/material/styles'; import { interpolateObject } from '@mui/x-charts-vendor/d3-interpolate'; export default function LabelsAboveBars() { return ( ); } const Text = styled('text')(({ theme }) => ({ ...theme?.typography?.body2, stroke: 'none', fill: (theme.vars || theme)?.palette?.text?.primary, transition: 'opacity 0.2s ease-in, fill 0.2s ease-in', textAnchor: 'middle', dominantBaseline: 'central', pointerEvents: 'none', })); function BarLabel(props: BarLabelProps) { const { seriesId, dataIndex, color, isFaded, isHighlighted, classes, xOrigin, yOrigin, x, y, width, height, layout, skipAnimation, ...otherProps } = props; const animatedProps = useAnimate( { x: x + width / 2, y: y - 8 }, { initialProps: { x: x + width / 2, y: yOrigin }, createInterpolator: interpolateObject, transformProps: (p) => p, applyProps: (element: SVGTextElement, p) => { element.setAttribute('x', p.x.toString()); element.setAttribute('y', p.y.toString()); }, skip: skipAnimation, }, ); return ( ); } ``` ## Click event Bar charts provides two click handlers: - `onItemClick` for click on a specific bar. - `onAxisClick` for a click 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. ) => {}; ``` ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined'; import { BarChart } from '@mui/x-charts/BarChart'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { BarItemIdentifier, ChartsAxisData } from '@mui/x-charts/models'; const barChartsParams = { series: [ { id: 'series-1', data: [3, 4, 1, 6, 5], label: 'A', stack: 'total', highlightScope: { highlight: 'item', }, }, { id: 'series-2', data: [4, 3, 1, 5, 8], label: 'B', stack: 'total', highlightScope: { highlight: 'item', }, }, { id: 'series-3', data: [4, 2, 5, 4, 1], label: 'C', highlightScope: { highlight: 'item', }, }, ], xAxis: [{ data: ['0', '3', '6', '9', '12'], id: 'axis1' }], height: 400, margin: { left: 0 }, } as const; export default function BarClick() { const [itemData, setItemData] = React.useState(); const [axisData, setAxisData] = React.useState(); return ( setItemData(d)} onAxisClick={(event, d) => setAxisData(d)} /> Click on the chart { setItemData(undefined); setAxisData(null); }} > ); } ``` :::info There is a slight difference between the `event` of `onItemClick` and `onAxisClick`: - For `onItemClick` it's a React synthetic mouse event emitted by the bar component. - For `onAxisClick` it's 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 {/* ... */} ``` ## 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 `skipAnimation` is enabled, the chart renders without any animations. ```jsx // For a single component chart // For a composed chart ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { BarChart } from '@mui/x-charts/BarChart'; import { HighlightScope } from '@mui/x-charts/context'; export default function BarAnimation() { const [seriesNb, setSeriesNb] = React.useState(2); const [itemNb, setItemNb] = React.useState(5); const [skipAnimation, setSkipAnimation] = React.useState(false); const handleItemNbChange = (event: Event, newValue: number | number[]) => { if (typeof newValue !== 'number') { return; } setItemNb(newValue); }; const handleSeriesNbChange = (event: Event, newValue: number | number[]) => { if (typeof newValue !== 'number') { return; } setSeriesNb(newValue); }; return ( ({ ...s, data: s.data.slice(0, itemNb) }))} skipAnimation={skipAnimation} margin={{ left: 0 }} /> setSkipAnimation(event.target.checked)} /> } label="skipAnimation" labelPlacement="end" /> Number of items Number of series ); } const highlightScope: HighlightScope = { highlight: 'series', fade: 'global', }; const series = [ { label: 'series 1', data: [ 2423, 2210, 764, 1879, 1478, 1373, 1891, 2171, 620, 1269, 724, 1707, 1188, 1879, 626, 1635, 2177, 516, 1793, 1598, ], }, { label: 'series 2', data: [ 2362, 2254, 1962, 1336, 586, 1069, 2194, 1629, 2173, 2031, 1757, 862, 2446, 910, 2430, 2300, 805, 1835, 1684, 2197, ], }, { label: 'series 3', data: [ 1145, 1214, 975, 2266, 1768, 2341, 747, 1282, 1780, 1766, 2115, 1720, 1057, 2000, 1716, 2253, 619, 1626, 1209, 1786, ], }, { label: 'series 4', data: [ 2361, 979, 2430, 1768, 1913, 2342, 1868, 1319, 1038, 2139, 1691, 935, 2262, 1580, 692, 1559, 1344, 1442, 1593, 1889, ], }, { label: 'series 5', data: [ 968, 1371, 1381, 1060, 1327, 934, 1779, 1361, 878, 1055, 1737, 2380, 875, 2408, 1066, 1802, 1442, 1567, 1552, 1742, ], }, { label: 'series 6', data: [ 2316, 1845, 2057, 1479, 1859, 1015, 1569, 1448, 1354, 1007, 799, 1748, 1454, 1968, 1129, 1196, 2158, 540, 1482, 880, ], }, { label: 'series 7', data: [ 2140, 2082, 708, 2032, 554, 1365, 2121, 1639, 2430, 2440, 814, 1328, 883, 1811, 2322, 1743, 700, 2131, 1473, 957, ], }, { label: 'series 8', data: [ 1074, 744, 2487, 823, 2252, 2317, 2139, 1818, 2256, 1769, 1123, 1461, 672, 1335, 960, 1871, 2305, 1231, 2005, 908, ], }, { label: 'series 9', data: [ 1792, 886, 2472, 1546, 2164, 2323, 2435, 1268, 2368, 2158, 2200, 1316, 552, 1874, 1771, 1038, 1838, 2029, 1793, 1117, ], }, { label: 'series 10', data: [ 1433, 1161, 1107, 1517, 1410, 1058, 676, 1280, 1936, 1774, 698, 1721, 1421, 785, 1752, 800, 990, 1809, 1985, 665, ], }, ].map((s) => ({ ...s, highlightScope })); ``` ## Performance Bar charts can display many bars, which can impact performance. The default rendering of bars use SVG `rect` elements, which can be slow for a large number of bars. To improve performance, you can use the `renderer` prop set to `"svg-batch"`, which renders the bars more efficiently. However, this comes with the following trade-offs: - CSS styling of single bars is no longer possible; - Transparent highlight style: for performance reasons, the highlighted state creates a highlighted bar on top of the original bar. Applying transparency to the highlighted bar can cause the original bar to be partially visible; - No animation when highlighting or fading bars; - The event of the `onItemClick` handler is a `MouseEvent` instead of a `React.MouseEvent`. To avoid breaking changes, the type of `onItemClick` was not changed, but you can import a type overload to fix it: `import type {} from '@mui/x-charts/moduleAugmentation/barChartBatchRendererOnItemClick'`; - It 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. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import { BarChartPro } from '@mui/x-charts-pro/BarChartPro'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; import RadioGroup from '@mui/material/RadioGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import Radio from '@mui/material/Radio'; import data from '../dataset/sp500-intraday.json'; const tickLabelDateFormatter = new Intl.DateTimeFormat(undefined, { month: 'short', day: 'numeric', }); export default function BarBatchRenderer() { const [renderer, setRenderer] = React.useState<'svg-single' | 'svg-batch'>( 'svg-batch', ); return ( Rendering Strategy setRenderer(event.target.value as 'svg-single' | 'svg-batch') } > } label="Individual Bars (default)" /> } label="Batch Bar Rendering" /> new Date(d.date)), valueFormatter: (v: Date) => tickLabelDateFormatter.format(v), zoom: true, ordinalTimeTicks: [ 'years', 'quarterly', 'months', 'biweekly', 'weeks', 'days', ], }, ]} series={[ { data: data.map((d) => d.close), label: 'Close', highlightScope: { highlight: 'item', fade: 'global' }, }, { data: data.map((d) => d.open), label: 'Open', highlightScope: { highlight: 'item', fade: 'global' }, }, ]} height={300} renderer={renderer} /> ); } ``` ## Composition Use the `` to provide `series`, `xAxis`, and `yAxis` props for composition. In addition to the common chart components available for [composition](/x/react-charts/composition/), you can use the `` component that renders the bars and their labels. Here's how the Bar Chart is composed: ```jsx ``` ```tsx import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import { BarPlot } from '@mui/x-charts/BarChart'; import { ScatterPlot } from '@mui/x-charts/ScatterChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsGrid } from '@mui/x-charts/ChartsGrid'; import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; import { ChartsTooltip } from '@mui/x-charts/ChartsTooltip'; import { legendClasses, ChartsLegend } from '@mui/x-charts/ChartsLegend'; import { GDPdata } from '../dataset/gdpGrowth'; const chartSetting = { xAxis: [ { id: 'bar', label: 'GDP growth rate', dataKey: '2024', colorMap: { type: 'piecewise' as const, thresholds: [0], colors: ['#ff4d4f', '#1976d2'], }, }, { id: 'scatter', label: '2010-19 Average', dataKey: '2010_19', color: '#FFFF00', }, ], height: 800, }; const valueFormatter = (value: number | null) => value ? `${value.toFixed(2)}%` : ''; const scatterValueFormatter = (value: { x: number } | null) => value ? `${value.x.toFixed(2)}%` : ''; function Gradient() { return ( ); } export default function BarScatterCompostion() { return ( GDP growth rate comparison (2024 vs 2010-19 Avg) ); } ``` --- # Source: https://mui.com/x/react-date-pickers/base-concepts.md --- productId: x-date-pickers title: Date and Time Picker - Base concepts 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 - Base concepts The Date and Time Pickers expose a lot of components to fit your every need. ## Controlled value All the components have a `value` / `onChange` API to set and control the values: ```tsx import * as React from 'react'; import { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function ControlledComponent() { const [value, setValue] = React.useState(null); return ( setValue(newValue)} /> ); } ``` ## Imports All the components exported by `@mui/x-date-pickers` are also exported by `@mui/x-date-pickers-pro` but without the nested imports. For example, to use the `DatePicker` component, the following three imports are valid: ```tsx import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { DatePicker } from '@mui/x-date-pickers'; import { DatePicker } from '@mui/x-date-pickers-pro'; ``` ## Date library The Date and Time Pickers are focused on UI/UX and, like most other picker components available, require a third-party library to format, parse, and mutate dates. MUI's components let you choose which library you prefer for this purpose. This gives you the flexibility to implement any date library you may already be using in your application, without adding an extra one to your bundle. To achieve this, both `@mui/x-date-pickers` and `@mui/x-date-pickers-pro` export a set of **adapters** that expose the date manipulation libraries under a unified API. ### Available libraries The Date and Time Pickers currently support the following date libraries: - [Day.js](https://day.js.org/) - [date-fns](https://date-fns.org/) - [Luxon](https://moment.github.io/luxon/#/) - [Moment.js](https://momentjs.com/) :::info If you are using a non-Gregorian calendar (such as Jalali or Hijri), please refer to the [Support for other calendar systems](/x/react-date-pickers/calendar-systems/) page. ::: ### Recommended library If you are already using one of the libraries listed above in your application, then you can keep using it with the Date and Time Pickers as well. This will avoid bundling two libraries. If you don't have your own requirements or don't manipulate dates outside of MUI X components, then the recommendation is to use `dayjs` because it has the smallest impact on your application's bundle size. Here is the weight added to your gzipped bundle size by each of these libraries when used inside the Date and Time Pickers: | Library | Gzipped size | | :---------------- | -----------: | | `dayjs@1.11.5` | 6.77 kB | | `date-fns@2.29.3` | 19.39 kB | | `luxon@3.0.4` | 23.26 kB | | `moment@2.29.4` | 20.78 kB | :::info The results above were obtained in October 2022 with the latest version of each library. The bundling of the JavaScript modules was done by a Create React App, and no locale was loaded for any of the libraries. The results may vary in your application depending on the version of each library, the locale, and the bundler used. ::: ## Other components ### Choose interaction style Depending on your use case, different interaction styles are preferred. - For input editing with a popover or modal for mouse interaction, use the _Picker_ components: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function BasicDatePicker() { return ( ); } ``` - For input-only editing, use the _Field_ components: ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; export default function BasicDateField() { return ( ); } ``` - For inline editing, use the _Calendar / Clock_ components: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function BasicDateCalendar() { return ( ); } ``` :::info Each _Picker_ is a combination of one _Field_ and one or several _Calendar / Clock_ components. For example, the `DatePicker` is the combination of the `DateField` and the `DateCalendar`. The _Calendar / Clock_ components are rendered inside a _Popover_ on desktop and inside a _Modal_ on mobile. ::: ### Date or time editing? The Date and Time Pickers are divided into six families of components. The demo below shows each one of them using their field component: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import { styled } from '@mui/material/styles'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; import { TimeField } from '@mui/x-date-pickers/TimeField'; import { DateTimeField } from '@mui/x-date-pickers/DateTimeField'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { SingleInputTimeRangeField } from '@mui/x-date-pickers-pro/SingleInputTimeRangeField'; import { SingleInputDateTimeRangeField } from '@mui/x-date-pickers-pro/SingleInputDateTimeRangeField'; import Stack from '@mui/material/Stack'; import Tooltip from '@mui/material/Tooltip'; const ProSpan = styled('span')({ display: 'inline-block', height: '1em', width: '1em', verticalAlign: 'middle', marginLeft: '0.3em', marginBottom: '0.08em', backgroundSize: 'contain', backgroundRepeat: 'no-repeat', backgroundImage: 'url(https://mui.com/static/x/pro.svg)', }); function ProLabel({ children }: { children: React.ReactNode }) { return ( {children} ); } export default function ComponentFamilies() { return ( Date Range} component="SingleInputDateRangeField" > Time Range} component="SingleInputTimeRangeField" > Date Time Range} component="SingleInputDateTimeRangeField" > ); } ``` ### Responsiveness Each _Picker_ is available in a responsive, desktop and mobile variant: - The responsive component (for example `DatePicker`) which renders the desktop component or the mobile one depending on the device it runs on. - The desktop component (for example `DesktopDatePicker`) which works best for mouse devices and large screens. It renders the views inside a popover and a field for keyboard editing. - The mobile component (for example `MobileDatePicker`) which works best for touch devices and small screens. It renders the view inside a modal and a field for keyboard editing. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker'; export default function ResponsivePickers() { return ( ); } ``` ### Find your component There are many components available, each fitting specific use cases. Use the form below to find the component you need: ```tsx import * as React from 'react'; // @ts-ignore import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import Link from '@mui/material/Link'; import Select from '@mui/material/Select'; import MenuItem from '@mui/material/MenuItem'; import FormControl from '@mui/material/FormControl'; import InputLabel from '@mui/material/InputLabel'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; // eslint-disable-next-line no-restricted-imports import * as exportedElements from '@mui/x-date-pickers-pro'; import Typography from '@mui/material/Typography'; const camelCaseToKebabCase = (str: string) => str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); const camelCaseToPascalCase = (str: string) => str.replace(/([a-z])([A-Z])/g, '$1 $2'); const getSubPackageFromExportedName = (exportedName: string) => exportedName.replace(/Unstable_/g, ''); type ExportedElements = keyof typeof exportedElements; interface State { valueType: | 'date' | 'time' | 'dateTime' | 'dateRange' | 'timeRange' | 'dateTimeRange'; family: 'field' | 'view' | 'picker'; } const COMPONENTS: Record< State['valueType'], Record > = { date: { field: ['DateField'], view: ['DateCalendar'], picker: [ 'DatePicker', 'DesktopDatePicker', 'MobileDatePicker', 'StaticDatePicker', ], }, time: { field: ['TimeField'], view: ['TimeClock'], picker: [ 'TimePicker', 'DesktopTimePicker', 'MobileTimePicker', 'StaticTimePicker', ], }, dateTime: { field: ['DateTimeField'], view: ['DateCalendar', 'TimeClock'], picker: [ 'DateTimePicker', 'DesktopDateTimePicker', 'MobileDateTimePicker', 'StaticDateTimePicker', ], }, dateRange: { field: ['SingleInputDateRangeField', 'MultiInputDateRangeField'], view: ['DateRangeCalendar'], picker: [ 'DateRangePicker', 'DesktopDateRangePicker', 'MobileDateRangePicker', 'StaticDateRangePicker', ], }, timeRange: { field: ['SingleInputTimeRangeField', 'MultiInputTimeRangeField'], view: [], picker: ['TimeRangePicker', 'DesktopTimeRangePicker', 'MobileTimeRangePicker'], }, dateTimeRange: { field: ['SingleInputDateTimeRangeField', 'MultiInputDateTimeRangeField'], view: [], picker: [ 'DateTimeRangePicker', 'DesktopDateTimeRangePicker', 'MobileDateTimeRangePicker', ], }, }; export default function ComponentExplorerNoSnap() { const [state, setState] = React.useState({ valueType: 'date', family: 'picker', }); const exportedNames = COMPONENTS[state.valueType][state.family]; const importCode = exportedNames .map((exportedName) => { const cleanName = exportedName.replace(/Unstable_|Next/g, ''); const subPackage = getSubPackageFromExportedName(exportedName); const isPro = cleanName.includes('Range'); return isPro ? ` import { ${exportedName} } from '@mui/x-date-pickers-pro/${subPackage}'; import { ${exportedName} } from '@mui/x-date-pickers-pro';` : ` import { ${exportedName} } from '@mui/x-date-pickers/${subPackage}'; import { ${exportedName} } from '@mui/x-date-pickers'; import { ${exportedName} } from '@mui/x-date-pickers-pro';`; }) .join('\n'); const content = exportedNames.map((exportedName) => { const Component = exportedElements[ exportedName ] as unknown as React.JSXElementConstructor<{}>; return ( ); }); const docPages = React.useMemo(() => { const docPagesNames = Array.from( new Set( exportedNames.map((exportedName) => exportedName.replace( /(Unstable_|Desktop|Mobile|Static|Next|SingleInput|MultiInput)/g, '', ), ), ), ); return docPagesNames.map((docPageName) => ({ name: camelCaseToPascalCase(docPageName), path: `/x/react-date-pickers/${camelCaseToKebabCase(docPageName)}/`, })); }, [exportedNames]); return ( Value type Family {exportedNames.length > 0 ? (
{docPages.map((docPage) => (
{docPage.name} documentation
))}
Import code:
Live example: {content}
) : ( This component is not available yet )}
); } ``` ## Reference date when no value is defined If `value` or `defaultValue` contains a valid date, this date will be used to initialize the rendered component. In the demo below, you can see that the calendar is set to April 2022 on mount: ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function ReferenceDateUsingValue() { return ( ); } ``` When `value` and `defaultValue` contain no valid date, the component will try to find a reference date that passes the validation to initialize its rendering: ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function ReferenceDateDefaultBehavior() { return ( ); } ``` You can override this date using the `referenceDate` prop: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; export default function ReferenceDateExplicitDateTimePicker() { const [value, setValue] = React.useState(null); return ( Stored value: {value == null ? 'null' : value.format()} ); } ``` This can also be useful to set the part of the value that will not be selectable in the component. For example, in a Time Picker, it lets you choose the date of your value: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { TimePicker } from '@mui/x-date-pickers/TimePicker'; export default function ReferenceDateExplicitTimePicker() { const [value, setValue] = React.useState(null); return ( Stored value: {value == null ? 'null' : value.format()} ); } ``` Reference date can be unique for each range component position. You can pass an array of dates to the `referenceDate` prop to set the reference date for each position in the range. This might be useful when you want different time values for start and end positions in a Date Time Range Picker. :::info Try selecting a date in the demo below, then move to the next position to observe the end reference date usage. ::: ```tsx import dayjs from 'dayjs'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; export default function ReferenceDateRange() { return ( ); } ``` ## Testing caveats ### Responsive components :::info Some test environments (for example `jsdom`) do not support media query. In such cases, components will be rendered in desktop mode. To modify this behavior you can fake the `window.matchMedia`. ::: Be aware that running tests in headless browsers might not pass the default mediaQuery (`pointer: fine`). In such cases you can [force pointer precision](https://github.com/microsoft/playwright/issues/7769#issuecomment-1205106311) via browser flags or preferences. ### Field components :::info To support RTL and some keyboard interactions, field components add some Unicode characters that are invisible, but appear in the input value. ::: To add tests about a field value without having to care about those characters, you can remove the specific characters before testing the equality. Here is an example of how to do it. ```js // Helper removing specific characters const cleanText = (string) => string.replace(/\u200e|\u2066|\u2067|\u2068|\u2069/g, ''); // Example of a test using the helper expect(cleanText(input.value)).to.equal('04-17-2022'); ``` ## Overriding slots and slot props Date and Time Pickers are complex components built using many subcomponents known as **slots**. Slots are commonly filled by React components that you can override using the `slots` prop. You can also pass additional props to the available slots using the `slotProps` prop. Learn more about the mental model of slots in the Base UI documentation: [Overriding component structure](https://v6.mui.com/base-ui/guides/overriding-component-structure/). You can find the list of available slots for each component in its respective [API reference](/x/api/date-pickers/date-picker/#slots) doc. Some parts of the Pickers' UI are built on several nested slots. For instance, the adornment of the `TextField` on `DatePicker` contains three slots (`inputAdornment`, `openPickerButton`, and `openPickerIcon`) that you can use depending on what you are trying to customize. ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { PickersDay } from '@mui/x-date-pickers/PickersDay'; import EditCalendarRoundedIcon from '@mui/icons-material/EditCalendarRounded'; import { styled } from '@mui/material/styles'; import IconButton from '@mui/material/IconButton'; const StyledButton = styled(IconButton)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, })); const StyledDay = styled(PickersDay)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, color: theme.palette.secondary.light, ...theme.applyStyles('light', { color: theme.palette.secondary.dark, }), })); export default function CustomSlots() { return ( ); } ``` :::info Learn more about overriding slots in the doc page about [Custom slots and subcomponents](/x/react-date-pickers/custom-components/). ::: --- # Source: https://mui.com/x/react-charts/brush.md --- title: Charts - Brush productId: x-charts components: ChartsBrushOverlay --- # Charts - Brush Let users select a region on a chart by clicking and dragging. 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. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; import { ChartsBrushOverlay } from '@mui/x-charts/ChartsBrushOverlay'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; export default function BrushBasic() { return ( Click and drag on the chart to see the brush selection overlay. ); } const xAxisData = [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ]; ``` ## 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. ```tsx import { LineChart } from '@mui/x-charts/LineChart'; import { useBrush, useDrawingArea, useLineSeries, useXScale, } from '@mui/x-charts/hooks'; import { useTheme } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; function CustomBrushOverlay() { const theme = useTheme(); const drawingArea = useDrawingArea(); const brush = useBrush(); const xScale = useXScale<'point'>(); const series = useLineSeries('marketValue'); if (!brush || !series) { return null; } const { left, top, width, height } = drawingArea; // Clamp coordinates to drawing area const clampX = (x: number) => Math.max(left, Math.min(left + width, x)); const clampedStartX = clampX(brush.start.x!); const clampedCurrentX = clampX(brush.current.x!); const minX = Math.min(clampedStartX, clampedCurrentX); const maxX = Math.max(clampedStartX, clampedCurrentX); const rectWidth = maxX - minX; const color = theme.palette.primary.main; if (rectWidth < 1) { return null; } const getIndex = (x: number) => Math.floor( (x - Math.min(...xScale.range()) + xScale.step() / 2) / xScale.step(), ); // Calculate the approximate data indices based on x position const startIndex = getIndex(clampedStartX); const currentIndex = getIndex(clampedCurrentX); const startValue = series.data[startIndex]!; const currentValue = series.data[currentIndex]!; const difference = currentValue - startValue; const percentChange = ((difference / startValue) * 100).toFixed(2); // Get the date labels const startDate = (xScale.domain()[startIndex] as string) || ''; const currentDate = (xScale.domain()[currentIndex] as string) || ''; return ( {/* Start line */} {/* Current line */} {/* Selection rectangle */} {/* Start label */} {/* Date label */} {startDate} {/* Value label */} {startValue.toFixed(2)} {/* End label */} {/* Date label */} {currentDate} {/* Value label */} {currentValue.toFixed(2)} {/* Difference label in the middle */} = 0 ? theme.palette.success.main : theme.palette.error.main } rx={4} /> {difference >= 0 ? '+' : ''} {difference.toFixed(2)} ({percentChange}%) ); } const marketData = [ 100, 96.56, 97.04, 98.95, 102.66, 106.18, 107.76, 109.78, 113.57, 111.54, 107.69, 104.58, 106.62, 103.81, 104.46, 105.14, 108.94, 112.81, 112.62, 117.52, 122.17, 122.11, 121.44, 122.5, 125.42, 127.46, 129.21, 124.71, 125.0, 125.28, 125.15, 125.06, 120.48, 115.83, 116.47, 119.58, 118.99, 123.46, 126.83, 130.84, 131.12, 131.31, 129.14, 133.35, 130.15, 129.02, 132.57, 136.1, 139.33, 139.66, ]; const dates = Array.from({ length: 50 }, (_, i) => { const date = new Date(2024, 0, i + 1); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); }); export default function BrushCustomOverlay() { return ( Custom brush overlay showing the values at start and end positions, and the difference between them. ); } ``` ### 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. ```tsx import * as React from 'react'; import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; import { ScatterPlot } from '@mui/x-charts/ScatterChart'; import { ChartsAxis } from '@mui/x-charts/ChartsAxis'; import { useBrush, useScatterSeries, useXScale, useYScale, } from '@mui/x-charts/hooks'; import { ChartsBrushOverlay } from '@mui/x-charts/ChartsBrushOverlay'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Chip from '@mui/material/Chip'; import Stack from '@mui/material/Stack'; const scatterData = [ { x: 5, y: 12, id: 1 }, { x: 12, y: 18, id: 2 }, { x: 18, y: 9, id: 3 }, { x: 25, y: 22, id: 4 }, { x: 32, y: 15, id: 5 }, { x: 40, y: 28, id: 6 }, { x: 48, y: 20, id: 7 }, { x: 55, y: 35, id: 8 }, { x: 62, y: 25, id: 9 }, { x: 70, y: 40, id: 10 }, { x: 78, y: 32, id: 11 }, { x: 85, y: 45, id: 12 }, { x: 15, y: 30, id: 13 }, { x: 35, y: 38, id: 14 }, { x: 50, y: 42, id: 15 }, { x: 65, y: 36, id: 16 }, { x: 22, y: 25, id: 17 }, { x: 44, y: 33, id: 18 }, { x: 58, y: 29, id: 19 }, { x: 72, y: 37, id: 20 }, ]; const empty: { x: number; y: number; id: number }[] = []; function ChartContent() { return ( ); } function SelectedPointsList() { const brush = useBrush(); const series = useScatterSeries('data'); const xScale = useXScale<'linear'>(); const yScale = useYScale<'linear'>(); const selectedData = React.useMemo(() => { if (!brush || !series || !xScale || !yScale) { return empty; } const { start, current } = brush; // Get the min/max x and y positions const minX = Math.min(start.x!, current.x!); const maxX = Math.max(start.x!, current.x!); const minY = Math.min(start.y!, current.y!); const maxY = Math.max(start.y!, current.y!); // Convert pixel coordinates back to data values const minDataX = xScale.invert(minX); const maxDataX = xScale.invert(maxX); const minDataY = yScale.invert(maxY); const maxDataY = yScale.invert(minY); // Filter data points within the brush selection const d = series.data .map((point, index) => ({ x: point.x as number, y: point.y as number, id: (point.id as number) ?? index + 1, })) .filter((point) => { return ( point.x >= (minDataX as number) && point.x <= (maxDataX as number) && point.y >= (minDataY as number) && point.y <= (maxDataY as number) ); }); return d; }, [brush, series, xScale, yScale]); if (selectedData.length === 0) { return ( No points selected. Drag on the chart to select data points. ); } return ( Selected Points ({selectedData.length}): {selectedData.map((point) => ( ))} ); } export default function BrushScatterList() { return ( Drag to select points on the scatter chart. Selected points will be displayed below. ); } ``` ### 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 {/* Your custom overlay */}; } ``` ## 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 ``` --- # Source: https://mui.com/x/react-date-pickers/calendar-systems.md --- productId: x-date-pickers title: Date and Time Pickers - Calendar systems components: LocalizationProvider githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Calendar systems Use the Date and Time Pickers with non-Gregorian calendars. ## Jalali You can use either the `AdapterDateFnsJalali` adapter, which is based on [date-fns-jalali](https://www.npmjs.com/package/date-fns-jalali), or the `AdapterMomentJalaali` adapter, which is based on [moment-jalaali](https://www.npmjs.com/package/moment-jalaali). The following demo shows how to use the `date-fns-jalali` adapter: ```tsx import * as React from 'react'; import { prefixer } from 'stylis'; import rtlPlugin from '@mui/stylis-plugin-rtl'; import createCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalali'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; // Create rtl cache const cacheRtl = createCache({ key: 'adapter-date-fns-jalali-demo', stylisPlugins: [prefixer, rtlPlugin], }); export default function AdapterJalali() { // Inherit the theme from the docs site (dark/light mode) const existingTheme = useTheme(); const theme = React.useMemo( () => createTheme(existingTheme, { direction: 'rtl' }), [existingTheme], ); return (
`, you can skip it. slotProps={{ desktopPaper: { dir: 'rtl', }, mobilePaper: { dir: 'rtl', }, }} />
); } ``` :::info We support `date-fns-jalali` package v2.x, v3.x, and v4.x major versions. A single adapter cannot work for all `date-fns-jalali` versions, because the way functions are exported has been changed in v3.x. To use `date-fns-jalali` v2.x, you need to import the adapter from `@mui/x-date-pickers/AdapterDateFnsJalaliV2` instead of `@mui/x-date-pickers/AdapterDateFnsJalali`. ```tsx // with date-fns-jalali v3.x or v4.x import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalali'; // with date-fns-jalali v2.x import { AdapterDateFnsJalali } from '@mui/x-date-pickers/AdapterDateFnsJalaliV2'; ``` ::: The following demo shows how to use the `moment-jalaali` adapter: ```tsx import * as React from 'react'; import { prefixer } from 'stylis'; import rtlPlugin from '@mui/stylis-plugin-rtl'; import createCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; import moment from 'moment-jalaali'; import { AdapterMomentJalaali } from '@mui/x-date-pickers/AdapterMomentJalaali'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; // Create rtl cache const cacheRtl = createCache({ key: 'adapter-moment-jalali-demo', stylisPlugins: [prefixer, rtlPlugin], }); export default function AdapterMomentJalali() { // Inherit the theme from the docs site (dark/light mode) const existingTheme = useTheme(); const theme = React.useMemo( () => createTheme(existingTheme, { direction: 'rtl' }), [existingTheme], ); return (
`, you can skip it. slotProps={{ desktopPaper: { dir: 'rtl', }, mobilePaper: { dir: 'rtl', }, }} />
); } ``` ## Hijri You can use the `AdapterMomentHijri` adapter, which is based on [moment-hijri](https://www.npmjs.com/package/moment-hijri): ```tsx import * as React from 'react'; import moment from 'moment-hijri'; import { prefixer } from 'stylis'; import rtlPlugin from '@mui/stylis-plugin-rtl'; import createCache from '@emotion/cache'; import { CacheProvider } from '@emotion/react'; import Button from '@mui/material/Button'; import { createTheme, ThemeProvider, useTheme } from '@mui/material/styles'; import { AdapterMomentHijri } from '@mui/x-date-pickers/AdapterMomentHijri'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker, DateTimePickerProps, DateTimePickerFieldProps, } from '@mui/x-date-pickers/DateTimePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useParsedFormat, usePickerContext, } from '@mui/x-date-pickers/hooks'; // Create rtl cache const cacheRtl = createCache({ key: 'adapter-moment-hijri-demo', stylisPlugins: [prefixer, rtlPlugin], }); function ButtonDateTimeField(props: DateTimePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const pickerContext = usePickerContext(); const parsedFormat = useParsedFormat(); const { hasValidationError } = useValidation({ validator: validateDate, value: pickerContext.value, timezone: pickerContext.timezone, props: internalProps, }); const valueStr = pickerContext.value == null ? parsedFormat : pickerContext.value.format(pickerContext.fieldFormat); return ( ); } function ButtonFieldDateTimePicker(props: DateTimePickerProps) { return ( ); } export default function AdapterHijri() { // Inherit the theme from the docs site (dark/light mode) const existingTheme = useTheme(); const theme = React.useMemo( () => createTheme(existingTheme, { direction: 'rtl' }), [existingTheme], ); return (
`, you can skip it. slotProps={{ desktopPaper: { dir: 'rtl', }, mobilePaper: { dir: 'rtl', }, }} />
); } ``` :::error The adapter with `moment-hijri` does not support the new fields components because the date library seems buggy when parsing a month only. If you want to help on the support of hijri calendar, please have a look at [this issue](https://github.com/xsoh/moment-hijri/issues/83). The demo is based on the [Custom Field—Using a Button](/x/react-date-pickers/custom-field/#using-a-button) demo to let you pick a value using only the view. You can have a look at the other demos in the [Custom Field—With a custom editing experience](/x/react-date-pickers/custom-field/#with-a-custom-editing-experience) section if you want a different editing experience that works with `AdapterMomentHijri`. ::: ## Unsupported libraries If you need to use a date library that is not supported yet, please [open an issue](https://github.com/mui/mui-x/issues/new/choose) in the MUI X repository. --- # Source: https://mui.com/x/react-data-grid/cell-selection.md --- title: Data Grid - Cell selection --- # Data Grid - Cell selection [](/x/introduction/licensing/#premium-plan 'Premium plan') Let users select individual cells or a range of cells. ## Enabling cell selection By default, the Data Grid lets users select individual rows. With the Data Grid Premium, you can apply the `cellSelection` prop to let users select individual cells or ranges of cells. ```tsx ``` ## Selecting cells With the `cellSelection` prop applied, users can select a single cell by clicking on it, or by pressing Shift+Space when the cell is in focus. Select multiple cells by holding Cmd (or Ctrl on Windows) while clicking on them. Hold Cmd (or Ctrl on Windows) and click on a selected cell to deselect it. To select a range of cells, users can: - Click on a cell, drag the mouse over nearby cells, and then release. - Click on a cell, then hold Shift and click on another cell. If a third cell is clicked then the selection will restart from the last clicked cell. - Use the arrow keys to focus on a cell, then hold Shift and navigate to another cell—if Shift is released and pressed again then the selection will restart from the last focused cell. Try out the various actions to select cells in the demo below—you can toggle [row selection](/x/react-data-grid/row-selection/) on and off to see how these two selection features can work in parallel. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function CellSelectionGrid() { const [rowSelection, setRowSelection] = React.useState(false); const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 6, }); return (
); } ``` ## Controlling cell selection You can control which cells are selected using the `cellSelectionModel` prop. This prop accepts an object with keys corresponding to the row IDs that contain selected cells. The value of each key is itself an object, which has a column field for a key and a boolean value for its selection state. You can set this to `true` to select a cell or `false` to deselect it. Removing the field from the object also deselects the cell. ```tsx // Selects the cell with field=name from row with id=1 // Unselects the cell with field=name from row with id=1 ``` When a new selection is made, the callback passed to the `onCellSelectionModelChange` prop is called with the updated model. Use this value to update the current model. The following demo shows how these props can be combined to create an Excel-like formula field—try updating multiple cells at once by selecting them and entering a new value in the field at the top. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import TextField from '@mui/material/TextField'; import Stack from '@mui/material/Stack'; import { DataGridPremium, GridCellSelectionModel, GridRowModelUpdate, useGridApiRef, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function CellSelectionFormulaField() { const apiRef = useGridApiRef(); const [value, setValue] = React.useState(''); const [cellSelectionModel, setCellSelectionModel] = React.useState({}); const [numberOfSelectedCells, setNumberOfSelectedCells] = React.useState(0); const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 6, }); const handleCellSelectionModelChange = React.useCallback( (newModel: GridCellSelectionModel) => { setCellSelectionModel(newModel); }, [], ); const handleValueChange = React.useCallback( (event: React.ChangeEvent) => { setValue(event.target.value); }, [], ); const updateSelectedCells = React.useCallback(() => { const updates: GridRowModelUpdate[] = []; Object.entries(cellSelectionModel).forEach(([id, fields]) => { const updatedRow = { ...apiRef.current?.getRow(id) }; Object.entries(fields).forEach(([field, isSelected]) => { if (isSelected) { updatedRow[field] = value; } }); updates.push(updatedRow); }); apiRef.current?.updateRows(updates); }, [apiRef, cellSelectionModel, value]); React.useEffect(() => { if (apiRef.current === null) { return; } const selectedCells = apiRef.current.getSelectedCellsAsArray(); setNumberOfSelectedCells(selectedCells.length); if (selectedCells.length > 1) { setValue('(multiple values)'); } else if (selectedCells.length === 1) { setValue( apiRef.current.getCellValue(selectedCells[0].id, selectedCells[0].field), ); } else { setValue(''); } }, [apiRef, cellSelectionModel]); return (
); } ``` ## Customizing range styles When multiple selected cells form a continuous range of any size, the following class names are applied to the cells at the edges: - `MuiDataGrid-cell--rangeTop`: to all cells in the first row of the range - `MuiDataGrid-cell--rangeBottom`: to all cells in the last row of the range - `MuiDataGrid-cell--rangeLeft`: to all cells in the first column of the range - `MuiDataGrid-cell--rangeRight`: to all cells in the last column of the range :::info When a single cell is selected, all classes above are applied to that element. ::: You can use these classes to create CSS selectors targeting specific corners of each range—for example, the demo below adds a border around the outside of the range. ```tsx import { styled, lighten, darken, alpha } from '@mui/material/styles'; import { DataGridPremium, gridClasses } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; const StyledDataGridPremium = styled(DataGridPremium)(({ theme }) => { const lightBorderColor = lighten(alpha(theme.palette.divider, 1), 0.88); const darkBorderColor = darken(alpha(theme.palette.divider, 1), 0.68); const selectedCellBorder = alpha(theme.palette.primary.main, 0.5); return { [`& .${gridClasses.cell}`]: { border: `1px solid transparent`, borderRight: `1px solid ${lightBorderColor}`, borderBottom: `1px solid ${lightBorderColor}`, ...theme.applyStyles('dark', { borderRightColor: `${darkBorderColor}`, borderBottomColor: `${darkBorderColor}`, }), }, [`& .${gridClasses.cell}.Mui-selected`]: { borderColor: alpha(theme.palette.primary.main, 0.1), }, [`& .${gridClasses.cell}.Mui-selected.${gridClasses['cell--rangeTop']}`]: { borderTopColor: selectedCellBorder, }, [`& .${gridClasses.cell}.Mui-selected.${gridClasses['cell--rangeBottom']}`]: { borderBottomColor: selectedCellBorder, }, [`& .${gridClasses.cell}.Mui-selected.${gridClasses['cell--rangeLeft']}`]: { borderLeftColor: selectedCellBorder, }, [`& .${gridClasses.cell}.Mui-selected.${gridClasses['cell--rangeRight']}`]: { borderRightColor: selectedCellBorder, }, }; }); export default function CellSelectionRangeStyling() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 6, }); return (
); } ``` ## apiRef The Data Grid exposes a set of methods via the `apiRef` object that are used internally in the implementation of the cell selection 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. ::: ```jsx import ApiDocs from 'docsx/src/modules/components/ApiDocs'; import premiumApi from 'docsx/pages/x/api/data-grid/grid-cell-selection-api.json'; export default function CellSelectionApiNoSnap() { return ; } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/cells.md # Data Grid - Cells Learn how to customize the rendered elements and values of a cell. ## Customizing cells The Data Grid provides several methods for customizing the rendered elements and values of a cell, including `renderCell()`, `valueGetter()`, and `valueFormatter()`. This document describes the key differences and specific use cases for each. ### renderCell() Use the `renderCell()` function to render any element inside of a cell. This is the only way to render a React component inside a cell, and also the only way to customize a cell's behavior—for example, by adding a click handler. Though powerful, it's also expensive in terms of performance, so it should only be used as a last resort when there are no other means for implementing a specific use case. Here's an example of a cell that uses `renderCell()` to render a button: ```tsx const columns: GridColDef[] = [ { field: 'date', headerName: 'Year', renderCell: (params: GridRenderCellParams) => ( {params.value.getFullYear()} ), }, ]; ``` See [Column definition—Rendering cells](/x/react-data-grid/column-definition/#rendering-cells) for more details. ### valueGetter() Use the `valueGetter()` function to derive a cell's value from the row data. This is the most performant way to customize the contents of a cell, and it does so without altering the row data itself. Common use cases include: - Transforming a value (for example, converting a decimal value to a percentage value) - Deriving a value from multiple fields (for example, concatenating first name and last name) - Deriving a value from a nested field (for example, `user.address.city`) This function is also used internally in the Data Grid to filter, sort, and render (if `renderCell()` or `valueFormatter()` are not provided). See [Column definition—Value getter](/x/react-data-grid/column-definition/#value-getter) for more details. ### valueFormatter() Use the `valueFormatter()` function to format a cell's value (without changing the underlying row data). Common use cases include: - Formatting a date to a custom display format - Formatting a decimal value to a percentage and appending a `%` sign - Formatting a boolean value to `Yes` or `No` Unlike `valueGetter()`, this function only impacts rendering—_not_ internal calculations like filtering or sorting. See [Column definition—value formatter](/x/react-data-grid/column-definition/#value-formatter) for more details. --- # Source: https://mui.com/x/api/charts/chart-container-premium.md # ChartContainerPremium API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Range Bar ## Import ```jsx import { ChartContainerPremium } from '@mui/x-charts-premium/ChartContainerPremium'; // or import { ChartContainerPremium } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-premium/src/ChartContainerPremium/ChartContainerPremium.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-premium/src/ChartContainerPremium/ChartContainerPremium.tsx) --- # Source: https://mui.com/x/api/charts/chart-container-pro.md # ChartContainerPro API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Composition](/x/react-charts/composition/) ## Import ```jsx import { ChartContainerPro } from '@mui/x-charts-pro/ChartContainerPro'; // or import { ChartContainerPro } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | colors | `Array \| func` | `blueberryTwilightPalette` | No | | | dataset | `Array` | - | No | | | disableAxisListener | `bool` | `false` | No | | | height | `number` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialZoom | `Array<{ axisId: number \| string, end: number, start: number }>` | - | No | | | margin | `{ bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onZoomChange | `function(zoomData: Array) => void` | - | No | | | series | `Array` | - | No | | | skipAnimation | `bool` | - | No | | | width | `number` | - | No | | | xAxis | `Array<{ classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, fill?: string, hideTooltip?: bool, id?: number \| string, label?: string, labelStyle?: object, max?: Date \| number, min?: Date \| number, position?: 'bottom' \| 'top', reverse?: bool, scaleType?: 'band' \| 'linear' \| 'log' \| 'point' \| 'pow' \| 'sqrt' \| 'time' \| 'utc', slotProps?: object, slots?: object, stroke?: string, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, step?: number } \| bool }>` | - | No | | | yAxis | `Array<{ classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, fill?: string, hideTooltip?: bool, id?: number \| string, label?: string, labelStyle?: object, max?: Date \| number, min?: Date \| number, position?: 'left' \| 'right', reverse?: bool, scaleType?: 'band' \| 'linear' \| 'log' \| 'point' \| 'pow' \| 'sqrt' \| 'time' \| 'utc', slotProps?: object, slots?: object, stroke?: string, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, step?: number } \| bool }>` | - | No | | | zAxis | `Array<{ colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, id?: string, max?: number, min?: number }>` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartContainerPro/ChartContainerPro.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartContainerPro/ChartContainerPro.tsx) --- # Source: https://mui.com/x/api/charts/chart-container.md # ChartContainer API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Composition](/x/react-charts/composition/) - [Charts - Localization](/x/react-charts/localization/) - [Charts - Plugins](/x/react-charts/plugins/) ## Import ```jsx import { ChartContainer } from '@mui/x-charts/ChartContainer'; // or import { ChartContainer } from '@mui/x-charts'; // or import { ChartContainer } from '@mui/x-charts-pro'; // or import { ChartContainer } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | brushConfig | `{ enabled?: bool, preventHighlight?: bool, preventTooltip?: bool }` | - | No | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | disableAxisListener | `bool` | `false` | No | | | disableVoronoi | `bool` | - | No | | | experimentalFeatures | `{ preferStrictDomainInLineCharts?: bool }` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: any, seriesId?: { toLocaleString: func, toString: func, valueOf: func }, type: object }>` | - | No | | | highlightedAxis | `Array<{ axisId: number \| string, dataIndex: number }>` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: any, seriesId?: { toLocaleString: func, toString: func, valueOf: func }, type: object }>` | - | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onAxisClick | `function(event: MouseEvent, data: null \| ChartsAxisData) => void` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onHighlightedAxisChange | `function(axisItems: Array) => void` | - | No | | | onItemClick | `function(event: MouseEvent, scatterItemIdentifier: ScatterItemIdentifier) => void` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | radiusAxis | `Array<{ classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, maxRadius?: number, min?: number, minRadius?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func }>` | - | No | | | rotationAxis | `Array<{ barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, endAngle?: number, height?: number, hideTooltip?: bool, id: number \| string, ignoreTooltip?: bool, label?: string, labelGap?: number, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, startAngle?: number, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func }>` | - | No | | | series | `Array` | - | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | - | No | | | slots | `object` | - | No | | | tooltipItem | `{ dataIndex?: number, seriesId: number \| string, type: 'bar' \| 'line' \| 'pie' \| 'radar' \| 'scatter' }` | - | No | | | voronoiMaxRadius | `'item' \| number` | - | No | | | width | `number` | - | No | | | xAxis | `Array<{ axis?: 'x', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func }>` | - | No | | | yAxis | `Array<{ axis?: 'y', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number }>` | - | No | | | zAxis | `Array<{ colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, id?: string, max?: number, min?: number }>` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartContainer/ChartContainer.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartContainer/ChartContainer.tsx) --- # Source: https://mui.com/x/api/charts/chart-data-provider-premium.md # ChartDataProviderPremium API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Range Bar ## Import ```jsx import { ChartDataProviderPremium } from '@mui/x-charts-premium/ChartDataProviderPremium'; // or import { ChartDataProviderPremium } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | experimentalFeatures | `{ preferStrictDomainInLineCharts?: bool }` | - | No | | | height | `number` | - | No | | | id | `string` | - | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | series | `Array` | - | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | - | No | | | slots | `object` | - | No | | | width | `number` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-premium/src/ChartDataProviderPremium/ChartDataProviderPremium.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-premium/src/ChartDataProviderPremium/ChartDataProviderPremium.tsx) --- # Source: https://mui.com/x/api/charts/chart-data-provider-pro.md # ChartDataProviderPro API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Composition](/x/react-charts/composition/) ## Import ```jsx import { ChartDataProviderPro } from '@mui/x-charts-pro/ChartDataProviderPro'; // or import { ChartDataProviderPro } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | experimentalFeatures | `{ preferStrictDomainInLineCharts?: bool }` | - | No | | | height | `number` | - | No | | | id | `string` | - | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | series | `Array` | - | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | - | No | | | slots | `object` | - | No | | | width | `number` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartDataProviderPro/ChartDataProviderPro.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartDataProviderPro/ChartDataProviderPro.tsx) --- # Source: https://mui.com/x/api/charts/chart-data-provider.md # ChartDataProvider API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Composition](/x/react-charts/composition/) - [Charts - Localization](/x/react-charts/localization/) - [Charts - Plugins](/x/react-charts/plugins/) ## Import ```jsx import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; // or import { ChartDataProvider } from '@mui/x-charts'; // or import { ChartDataProvider } from '@mui/x-charts-pro'; // or import { ChartDataProvider } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | experimentalFeatures | `{ preferStrictDomainInLineCharts?: bool }` | - | No | | | height | `number` | - | No | | | id | `string` | - | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | series | `Array` | - | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | - | No | | | slots | `object` | - | No | | | width | `number` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartDataProvider/ChartDataProvider.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartDataProvider/ChartDataProvider.tsx) --- # Source: https://mui.com/x/api/charts/chart-image-export-options.md # ChartImageExportOptions API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Image export](https://mui.com/x/react-charts/export/#export-as-image) ## Import ```jsx import { ChartImageExportOptions } from '@mui/x-charts-pro' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | copyStyles | `boolean` | `true` | No | | | fileName | `string` | `The title of the document the chart belongs to` | No | | | nonce | `string` | - | No | | | onBeforeExport | `(iframe: HTMLIFrameElement) => Promise \| void` | - | No | | | quality | `number` | `0.9` | No | | | type | `'image/png' \| string` | `'image/png'` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/charts/chart-print-export-options.md # ChartPrintExportOptions API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Print export](https://mui.com/x/react-charts/export/#print-export-as-pdf) ## Import ```jsx import { ChartPrintExportOptions } from '@mui/x-charts-pro' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | copyStyles | `boolean` | `true` | No | | | fileName | `string` | `The title of the document the chart belongs to` | No | | | nonce | `string` | - | No | | | onBeforeExport | `(iframe: HTMLIFrameElement) => Promise \| void` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/charts/chart-zoom-slider.md # ChartZoomSlider API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Zoom and pan ## Import ```jsx import { ChartZoomSlider } from '@mui/x-charts-pro/ChartZoomSlider'; // or import { ChartZoomSlider } from '@mui/x-charts-pro'; ``` > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartZoomSlider/ChartZoomSlider.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartZoomSlider/ChartZoomSlider.tsx) --- # Source: https://mui.com/x/api/charts/charts-axis-highlight.md # ChartsAxisHighlight API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Highlighting](/x/react-charts/highlighting/) ## Import ```jsx import { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight'; // or import { ChartsAxisHighlight } from '@mui/x-charts'; // or import { ChartsAxisHighlight } from '@mui/x-charts-pro'; // or import { ChartsAxisHighlight } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsAxisHighlight/ChartsAxisHighlight.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsAxisHighlight/ChartsAxisHighlight.tsx) --- # Source: https://mui.com/x/api/charts/charts-axis-tooltip-content.md # ChartsAxisTooltipContent API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Tooltip](/x/react-charts/tooltip/) ## Import ```jsx import { ChartsAxisTooltipContent } from '@mui/x-charts/ChartsTooltip'; // or import { ChartsAxisTooltipContent } from '@mui/x-charts'; // or import { ChartsAxisTooltipContent } from '@mui/x-charts-pro'; // or import { ChartsAxisTooltipContent } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsTooltip/ChartsAxisTooltipContent.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsTooltip/ChartsAxisTooltipContent.tsx) --- # Source: https://mui.com/x/api/charts/charts-axis.md # ChartsAxis API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Axis](/x/react-charts/axis/) ## Import ```jsx import { ChartsAxis } from '@mui/x-charts/ChartsAxis'; // or import { ChartsAxis } from '@mui/x-charts'; // or import { ChartsAxis } from '@mui/x-charts-pro'; // or import { ChartsAxis } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | bottom | Styles applied to the bottom axis. | | - | directionX | Styles applied to x-axes. | | - | directionY | Styles applied to y-axes. | | - | id | Styles applied to the root element for the axis with the given ID. Needs to be suffixed with the axis ID: `.${axisClasses.id}-${axisId}`. | | - | label | Styles applied to the group containing the axis label. | | - | left | Styles applied to the left axis. | | - | line | Styles applied to the main line element. | | - | right | Styles applied to the right axis. | | - | root | Styles applied to the root element. | | - | tick | Styles applied to ticks. | | - | tickContainer | Styles applied to group including the tick and its label. | | - | tickLabel | Styles applied to ticks label. ⚠️ For performance reasons, only the inline styles get considered for bounding box computation. Modifying text size by adding properties like `font-size` or `letter-spacing` to this class might cause labels to overlap. | | - | top | Styles applied to the top axis. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsAxis/ChartsAxis.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsAxis/ChartsAxis.tsx) --- # Source: https://mui.com/x/api/charts/charts-brush-overlay.md # ChartsBrushOverlay API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Brush](/x/react-charts/brush/) - Charts - Zoom and pan ## Import ```jsx import { ChartsBrushOverlay } from '@mui/x-charts/ChartsBrushOverlay'; // or import { ChartsBrushOverlay } from '@mui/x-charts'; // or import { ChartsBrushOverlay } from '@mui/x-charts-pro'; // or import { ChartsBrushOverlay } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsBrushOverlay/ChartsBrushOverlay.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsBrushOverlay/ChartsBrushOverlay.tsx) --- # Source: https://mui.com/x/api/charts/charts-clip-path.md # ChartsClipPath API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Custom components](/x/react-charts/components/) ## Import ```jsx import { ChartsClipPath } from '@mui/x-charts/ChartsClipPath'; // or import { ChartsClipPath } from '@mui/x-charts'; // or import { ChartsClipPath } from '@mui/x-charts-pro'; // or import { ChartsClipPath } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | id | `string` | - | Yes | | | offset | `{ bottom?: number, left?: number, right?: number, top?: number }` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsClipPath/ChartsClipPath.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsClipPath/ChartsClipPath.tsx) --- # Source: https://mui.com/x/api/charts/charts-grid.md # ChartsGrid API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Bars](/x/react-charts/bars/) - [Charts - Composition](/x/react-charts/composition/) - [Charts - Lines](/x/react-charts/lines/) - [Charts - Scatter](/x/react-charts/scatter/) ## Import ```jsx import { ChartsGrid } from '@mui/x-charts/ChartsGrid'; // or import { ChartsGrid } from '@mui/x-charts'; // or import { ChartsGrid } from '@mui/x-charts-pro'; // or import { ChartsGrid } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | horizontal | `bool` | - | No | | | vertical | `bool` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | horizontalLine | Styles applied to x-axes. | | - | line | Styles applied to every line element. | | - | root | Styles applied to the root element. | | - | verticalLine | Styles applied to y-axes. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsGrid/ChartsGrid.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsGrid/ChartsGrid.tsx) --- # Source: https://mui.com/x/react-data-grid/charts-integration.md --- title: Data Grid and Charts integration --- # Charts integration [](/x/introduction/licensing/#premium-plan 'Premium plan') 🧪 Use the MUI X Charts to visualize data from the Data Grid. Data Grid seamlessly integrates with [MUI X Charts](/x/react-charts/) for data visualization with dynamic Chart updates based on the Data Grid state changes (whether through the Data Grid API or user interactions). :::warning This feature is in preview. It is ready for production use, but its API, visuals and behavior may change in future minor or patch releases. To use the feature, add `charts` experimental flag on top of other props described below. ```tsx ``` ::: This integration is possible via the `` and `` components from `@mui/x-data-grid-premium` and the `` component from the `@mui/x-charts-premium` package. Based on its internal models, the Grid calculates and stores the data in a format that is easy to use for chart rendering. `` reads that data and renders an appropriate chart component with props that depend on the configuration stored in the context. ## Implementing Charts and Data Grid integration To enable chart integration, pass the `chartsIntegration` prop to the Grid and `` to the `chartsPanel` slot. This enables the charts panel and makes it possible for the charts integration context provider state to receive updates. ```tsx import { DataGridPremium, GridChartsPanel } from '@mui/x-data-grid-premium'; // ... return ( ); ``` Wrap your Grid and chart renderer in a ``. Use `` to connect the chart renderer to the Grid's state updates. ```tsx import { DataGridPremium, GridChartsIntegrationContextProvider, GridChartsRendererProxy, } from '@mui/x-data-grid-premium'; import { ChartsRenderer } from '@mui/x-charts-premium/ChartsRenderer'; // ... return ( ); ``` ### Basic integration The demo below shows all the basic elements needed to get the charts integration working. Use `initialState` to set the initial configuration for the chart renderer. ```tsx import { useDemoData } from '@mui/x-data-grid-generator'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, GridSidebarValue, } from '@mui/x-data-grid-premium'; import { ChartsRenderer, configurationOptions, } from '@mui/x-charts-premium/ChartsRenderer'; export default function GridChartsIntegrationBasic() { const { data } = useDemoData({ dataSet: 'Employee', rowLength: 20, editable: true, }); return (
); } ``` ## Row grouping You can integrate charts with grouped and aggregated data. The Grid's grouping and aggregation states are reflected in the chart. ```tsx import * as React from 'react'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, useGridApiRef, useKeepGroupedColumnsHidden, GridSidebarValue, } from '@mui/x-data-grid-premium'; import { ChartsRenderer, configurationOptions, } from '@mui/x-charts-premium/ChartsRenderer'; import { useDemoData } from '@mui/x-data-grid-generator'; // make sure that the commodity labels are not overlapping on the initial load // this is just for the demo // the logic needs an update to cover other possible configurations const onRender = ( type: string, props: Record, Component: React.ComponentType, ) => { if (type === 'pie') { return ; } const axisProp = type === 'bar' ? 'yAxis' : 'xAxis'; const adjustedProps = { ...props, [axisProp]: props[axisProp].map((axisProps: Record) => ({ ...axisProps, groups: axisProps.groups?.map( (axisGroup: { getValue: (value: any) => string }, index: number) => ({ ...axisGroup, getValue: (value: string[]) => { const targetIndex = axisProps.groups.length - 1 - index; if (targetIndex === 0) { return value[0]; } return value[targetIndex][0]; }, }), ), })), }; return ; }; export default function GridChartsIntegrationRowGrouping() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 100, editable: true, }); const apiRef = useGridApiRef(); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { ...data.initialState, rowGrouping: { ...data.initialState?.rowGrouping, model: ['status', 'commodity'], }, aggregation: { ...data.initialState?.aggregation, model: { filledQuantity: 'avg', feeRate: 'sum', }, }, sidebar: { open: true, value: GridSidebarValue.Charts, }, chartsIntegration: { charts: { main: { dimensions: ['status', 'commodity'], values: ['filledQuantity', 'feeRate'], chartType: 'column', }, }, }, }, }); return (
); } ``` ## Pivoting [Pivoting](/x/react-data-grid/pivoting/) creates columns dynamically, based on the pivoting model. The names of those columns are determined by the values used to generate them, which makes it impossible to initialize `values` with those values. Use the [`updateChartValuesData()`](/x/api/data-grid/grid-api/#grid-api-prop-updateChartValuesData) to update the chart's value datasets after the columns are created. ```tsx const apiRef = useGridApiRef(); React.useEffect(() => { const handleColumnVisibilityModelChange = () => { // Get dynamically created columns const unwrappedGroupingModel = Object.keys( gridColumnGroupsUnwrappedModelSelector(apiRef), ); // Update chart value datasets apiRef.current?.updateChartValuesData( 'main', unwrappedGroupingModel .filter((field) => field.endsWith('quantity')) .slice(0, 5) .map((field, index) => ({ field, hidden: index >= 3 })), ); }; return apiRef.current?.subscribeEvent( 'columnVisibilityModelChange', handleColumnVisibilityModelChange, ); }, [apiRef]); ``` ```tsx import * as React from 'react'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, gridColumnGroupsUnwrappedModelSelector, GridEventListener, GridPivotModel, useGridApiRef, } from '@mui/x-data-grid-premium'; import { ChartsRenderer, configurationOptions, } from '@mui/x-charts-premium/ChartsRenderer'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function GridChartsIntegrationPivoting() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 1000, editable: true, }); const apiRef = useGridApiRef(); const pivotModel: GridPivotModel = { rows: [{ field: 'commodity' }], columns: [ { field: 'maturityDate-year', sort: 'asc' }, { field: 'maturityDate-quarter', sort: 'asc' }, ], values: [ { field: 'quantity', aggFunc: 'sum' }, { field: 'feeRate', aggFunc: 'avg' }, ], }; const initialState = { ...data.initialState, pivoting: { model: pivotModel, enabled: true, }, chartsIntegration: { charts: { main: { dimensions: ['commodity'], chartType: 'column', }, }, }, }; const hasInitializedPivotingSeries = React.useRef(false); React.useEffect(() => { const handleColumnVisibilityModelChange: GridEventListener< 'columnVisibilityModelChange' > = () => { if (!apiRef.current || hasInitializedPivotingSeries.current) { return; } const unwrappedGroupingModel = Object.keys( gridColumnGroupsUnwrappedModelSelector(apiRef), ); // wait until pivoting creates column grouping model if (unwrappedGroupingModel.length === 0) { return; } hasInitializedPivotingSeries.current = true; // pick up the first 5 dyamically created columns with quantity in the name and enable first 3 apiRef.current.updateChartValuesData( 'main', unwrappedGroupingModel .filter((field) => field.endsWith('quantity')) .slice(0, 5) .map((field, index) => ({ field, hidden: index >= 3 })), ); }; return apiRef.current?.subscribeEvent( 'columnVisibilityModelChange', handleColumnVisibilityModelChange, ); }, [apiRef]); return (
); } ``` ## Server-side data The following demo shows charts integration with the grid using [Server-side data](/x/react-data-grid/server-side-data/). ```tsx import * as React from 'react'; import { useMockServer } from '@mui/x-data-grid-generator'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, GridSidebarValue, useKeepGroupedColumnsHidden, GridDataSource, useGridApiRef, GridPivotModel, GridEventListener, gridColumnGroupsUnwrappedModelSelector, gridPivotModelSelector, DataGridPremiumProps, } from '@mui/x-data-grid-premium'; import { ChartsRenderer, configurationOptions, } from '@mui/x-charts-premium/ChartsRenderer'; const initialPivotModel: GridPivotModel = { rows: [{ field: 'commodity' }], columns: [{ field: 'incoTerm' }], values: [{ field: 'quantity', aggFunc: 'sum' }], }; const aggregationFunctions = { sum: { columnTypes: ['number'] }, avg: { columnTypes: ['number'] }, min: { columnTypes: ['number', 'date', 'dateTime'] }, max: { columnTypes: ['number', 'date', 'dateTime'] }, size: {}, }; const pivotingColDef: DataGridPremiumProps['pivotingColDef'] = ( originalColumnField, columnGroupPath, ) => ({ field: columnGroupPath.concat(originalColumnField).join('>->'), }); export default function GridChartsIntegrationDataSource() { const apiRef = useGridApiRef(); const { fetchRows, initialState, columns } = useMockServer( { rowLength: 1000, dataSet: 'Commodity', maxColumns: 20, }, { useCursorPagination: false }, ); const dataSource: GridDataSource = React.useMemo(() => { return { getRows: async (params) => { const urlParams = new URLSearchParams({ paginationModel: JSON.stringify(params.paginationModel), filterModel: JSON.stringify(params.filterModel), sortModel: JSON.stringify(params.sortModel), groupKeys: JSON.stringify(params.groupKeys), groupFields: JSON.stringify(params.groupFields), aggregationModel: JSON.stringify(params.aggregationModel), pivotModel: JSON.stringify(params.pivotModel), }); const getRowsResponse = await fetchRows( `https://mui.com/x/api/data-grid?${urlParams.toString()}`, ); return { rows: getRowsResponse.rows, rowCount: getRowsResponse.rowCount, aggregateRow: getRowsResponse.aggregateRow, pivotColumns: getRowsResponse.pivotColumns, }; }, getGroupKey: (row) => row.group, getChildrenCount: (row) => row.descendantCount, getAggregatedValue: (row, field) => row[field], }; }, [fetchRows]); const initialStateUpdated = useKeepGroupedColumnsHidden({ apiRef, initialState: { ...initialState, pivoting: { model: initialPivotModel, enabled: true, }, sidebar: { open: true, value: GridSidebarValue.Charts, }, chartsIntegration: { charts: { main: { dimensions: ['commodity'], values: [], chartType: 'column', }, }, }, }, }); const hasInitializedPivotingSeries = React.useRef(false); React.useEffect(() => { const handleColumnsChange: GridEventListener<'columnsChange'> = () => { if (!apiRef.current || hasInitializedPivotingSeries.current) { return; } const unwrappedGroupingModel = Object.keys( gridColumnGroupsUnwrappedModelSelector(apiRef), ); // wait until pivoting creates column grouping model if (unwrappedGroupingModel.length === 0) { return; } const pivotModel = gridPivotModelSelector(apiRef); const targetField = pivotModel.values.find( (value) => value.hidden !== true, )?.field; hasInitializedPivotingSeries.current = true; if (targetField) { apiRef.current.updateChartValuesData( 'main', unwrappedGroupingModel .filter((field) => field.endsWith(targetField)) .map((field) => ({ field })), ); } }; return apiRef.current?.subscribeEvent('columnsChange', handleColumnsChange); }, [apiRef]); return (
); } ``` ## Multiple charts Control multiple charts with one grid by adding more `` components with unique IDs. Each chart can have its own configuration and state. ```tsx ``` ```tsx import * as React from 'react'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, gridColumnGroupsUnwrappedModelSelector, GridEventListener, GridPivotModel, useGridApiRef, } from '@mui/x-data-grid-premium'; import { ChartsRenderer, configurationOptions, } from '@mui/x-charts-premium/ChartsRenderer'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function GridChartsIntegrationMultipleCharts() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 1000, editable: true, }); const apiRef = useGridApiRef(); const pivotModel: GridPivotModel = { rows: [{ field: 'dateCreated-quarter' }], columns: [ { field: 'maturityDate-year', sort: 'asc' }, { field: 'maturityDate-quarter', sort: 'asc' }, ], values: [ { field: 'quantity', aggFunc: 'sum' }, { field: 'feeRate', aggFunc: 'avg' }, ], }; const initialState = { ...data.initialState, pivoting: { model: pivotModel, enabled: true, }, chartsIntegration: { charts: { quantity: { chartType: 'bar', }, feeRate: { chartType: 'line', }, }, }, }; const hasInitializedPivotingSeries = React.useRef(false); React.useEffect(() => { const handleColumnVisibilityModelChange: GridEventListener< 'columnVisibilityModelChange' > = () => { if (hasInitializedPivotingSeries.current) { return; } const unwrappedGroupingModel = Object.keys( gridColumnGroupsUnwrappedModelSelector(apiRef), ); // wait until pivoting creates column grouping model if (unwrappedGroupingModel.length === 0) { return; } hasInitializedPivotingSeries.current = true; // add columns dynamically created by pivoting // they cannot be added to the initial state because they are not available at that time and will be cleaned up by the state initializer apiRef.current?.updateChartDimensionsData('quantity', [ { field: 'dateCreated-quarter', hidden: false }, ]); apiRef.current?.updateChartValuesData( 'quantity', unwrappedGroupingModel .filter((field) => field.endsWith('quantity')) .slice(0, 5) .map((field, index) => ({ field, hidden: index >= 3 })), ); apiRef.current?.updateChartDimensionsData('feeRate', [ { field: 'dateCreated-quarter', hidden: false }, ]); apiRef.current?.updateChartValuesData( 'feeRate', unwrappedGroupingModel .filter((field) => field.endsWith('feeRate')) .slice(0, 5) .map((field, index) => ({ field, hidden: index >= 3 })), ); }; return apiRef.current?.subscribeEvent( 'columnVisibilityModelChange', handleColumnVisibilityModelChange, ); }, [apiRef]); return (
); } ``` ## Customization Customize the chart configuration and rendering by: - Overriding configuration options to force certain values. Use it to hide or lock configuration controls in the panel. - Using the `onRender()` prop on `` to customize chart rendering for one or all chart types. The demo below overrides the configuration and removes the option to change the color palette. Additionally, it adds axes formatting for line and area chart that cannot be controlled via the default customization panel. If needed, you can extend the configuration to render the UI elements for the additional customized axes. ```tsx import * as React from 'react'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, GridSidebarValue, GridColDef, GridRowModel, GridPivotModel, DataGridPremiumProps, GridChartsPanelProps, useGridApiRef, GridEventListener, gridColumnGroupsUnwrappedModelSelector, } from '@mui/x-data-grid-premium'; import { ChartsRenderer, configurationOptions, GridChartsConfigurationSection, } from '@mui/x-charts-premium/ChartsRenderer'; import { downloads } from './dataset'; const columns: GridColDef[] = [ { field: 'id', chartable: false }, { field: 'timestamp', headerName: 'Timestamp', type: 'date' }, { field: 'version', headerName: 'Version', width: 100 }, { field: 'downloads', headerName: 'Downloads', type: 'number' }, ]; const versions = Object.keys( downloads.versionDownloads, ) as (keyof typeof downloads.versionDownloads)[]; const rows: GridRowModel[] = []; for (let i = 0; i < downloads.timestamps.length; i += 1) { for (let j = 0; j < versions.length; j += 1) { rows.push({ id: `${i}-${j}`, timestamp: new Date(downloads.timestamps[i]), version: versions[j], downloads: downloads.versionDownloads[versions[j]][i], }); } } const hideColorsControl = (sections: GridChartsConfigurationSection[]) => sections.map((section) => ({ ...section, controls: { ...section.controls, colors: { ...section.controls.colors, isHidden: () => true, }, }, })); const customConfiguration = { bar: { ...configurationOptions.bar, customization: hideColorsControl(configurationOptions.bar.customization), maxDimensions: 1, }, column: { ...configurationOptions.column, customization: hideColorsControl(configurationOptions.column.customization), maxDimensions: 1, }, line: { ...configurationOptions.line, customization: hideColorsControl(configurationOptions.line.customization), maxDimensions: 1, }, area: { ...configurationOptions.area, customization: hideColorsControl(configurationOptions.area.customization), maxDimensions: 1, }, }; const gridPivotModel: GridPivotModel = { rows: [{ field: 'timestamp' }], columns: [{ field: 'majorVersion', sort: 'asc' }], values: [{ field: 'downloads', aggFunc: 'sum' }], }; const getPivotDerivedColumns: DataGridPremiumProps['getPivotDerivedColumns'] = ( column, ) => { if (column.field === 'version') { return [ { field: 'majorVersion', headerName: `Major version`, type: 'number', valueGetter: (_, row) => Number(row.version.split('.')[0]), valueFormatter: (value: string) => `v${value}`, }, ]; } return undefined; }; const initialState = { sidebar: { open: true, value: GridSidebarValue.Charts, }, pivoting: { enabled: true, model: gridPivotModel, }, chartsIntegration: { charts: { main: { dimensions: ['timestamp'], values: [], chartType: 'line', configuration: { showMark: false, grid: 'both', height: 400, }, }, }, }, }; const getColumnName: GridChartsPanelProps['getColumnName'] = (field) => { if (field === 'downloads') { return 'Downloads'; } if (!field.endsWith('downloads')) { return undefined; } return `v${field[0]}`; }; const dateFormatter = (value: string | Date) => new Date(value).toLocaleDateString('en-US', { month: '2-digit', year: '2-digit', }); const downloadsFormatter = (value: number) => value === 0 ? '0' : `${Math.round(value / 1000)}k`; const onRender = ( type: string, props: Record, Component: React.ComponentType, ) => { let adjustedProps = props; if (type === 'line' || type === 'area') { adjustedProps = { ...adjustedProps, xAxis: props.xAxis.map((axis: any) => ({ ...axis, scaleType: 'time', domainLimit: 'strict', valueFormatter: dateFormatter, })), yAxis: props.yAxis.map((axis: any) => ({ ...axis, valueFormatter: downloadsFormatter, })), }; } if (type === 'bar') { adjustedProps = { ...adjustedProps, xAxis: [ { valueFormatter: downloadsFormatter, }, ], yAxis: adjustedProps.yAxis.map((axis: any) => ({ ...axis, valueFormatter: dateFormatter, tickInterval: (_: any, index: number) => index % 10 === 0, })), }; } if (type === 'column') { adjustedProps = { ...adjustedProps, xAxis: adjustedProps.xAxis.map((axis: any) => ({ ...axis, valueFormatter: dateFormatter, })), yAxis: [ { valueFormatter: downloadsFormatter, }, ], }; } return ; }; export default function GridChartsIntegrationCustomization() { const apiRef = useGridApiRef(); React.useEffect(() => { const handleColumnsChange: GridEventListener<'columnsChange'> = () => { const unwrappedGroupingModel = Object.keys( gridColumnGroupsUnwrappedModelSelector(apiRef), ); if (unwrappedGroupingModel.length === 0) { return; } // pick up the all major versions apiRef.current?.updateChartValuesData( 'main', unwrappedGroupingModel.map((field) => ({ field })), ); if (unsubscribe) { unsubscribe(); } }; const unsubscribe = apiRef.current?.subscribeEvent( 'columnsChange', handleColumnsChange, ); }, [apiRef]); return (
); } ``` ## Live data The demo below shows how the Charts react to live data updates in the Grid. ```tsx import * as React from 'react'; import { interval } from 'rxjs'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, GridColDef, useGridApiRef, } from '@mui/x-data-grid-premium'; import { randomInt } from '@mui/x-data-grid-generator'; import { ChartsRenderer, configurationOptions, } from '@mui/x-charts-premium/ChartsRenderer'; import { BarChartPro, BarChartProProps } from '@mui/x-charts-pro/BarChartPro'; import { AxisConfig } from '@mui/x-charts/models'; const columns: GridColDef[] = [ { field: 'id' }, { field: 'process', headerName: 'Process', width: 150 }, { field: 'cpu', headerName: 'CPU', width: 100, type: 'number', valueFormatter: (value) => `${value}%`, }, { field: 'memory', headerName: 'Memory', width: 100, type: 'number', valueFormatter: (value) => `${value} MB`, }, ]; const processDefinitions = [ { name: 'chrome', minCpu: 20, maxCpu: 80, minMemory: 950, maxMemory: 1000 }, { name: 'finder', minCpu: 0, maxCpu: 5, minMemory: 250, maxMemory: 300 }, { name: 'mail', minCpu: 0, maxCpu: 5, minMemory: 375, maxMemory: 400 }, { name: 'terminal', minCpu: 3, maxCpu: 10, minMemory: 120, maxMemory: 160 }, { name: 'adobe', minCpu: 50, maxCpu: 90, minMemory: 3700, maxMemory: 3900 }, { name: 'firefox', minCpu: 3, maxCpu: 20, minMemory: 670, maxMemory: 700 }, { name: 'slack', minCpu: 1, maxCpu: 10, minMemory: 480, maxMemory: 500 }, { name: 'chrome', minCpu: 3, maxCpu: 30, minMemory: 770, maxMemory: 790 }, { name: 'spotify', minCpu: 1, maxCpu: 10, minMemory: 220, maxMemory: 250 }, { name: 'chrome', minCpu: 12, maxCpu: 25, minMemory: 350, maxMemory: 400 }, { name: 'chrome', minCpu: 20, maxCpu: 30, minMemory: 550, maxMemory: 600 }, ]; const customConfigurationOptions = Object.fromEntries( Object.entries(configurationOptions).filter(([key]) => key === 'column'), ); export default function GridChartsIntegrationLiveData() { const apiRef = useGridApiRef(); React.useEffect(() => { const subscription = interval(1000).subscribe(() => { apiRef.current?.updateRows(generateRows()); }); return () => { subscription.unsubscribe(); }; }, [apiRef]); return (
); } function generateRows() { return processDefinitions.map((process, index) => ({ id: index, process: process.name, cpu: randomInt(process.minCpu, process.maxCpu), memory: randomInt(process.minMemory, process.maxMemory), })); } function getOnRender(max: number, unit: string) { return function onRender( type: string, props: Record, Component: React.ComponentType, ) { if (type !== 'column') { return ; } const series = props.series.map((seriesItem: AxisConfig) => ({ ...seriesItem, label: `${seriesItem.label} (${unit})`, })); const yAxis = [ { min: 0, max, valueFormatter: (value: number) => `${value} ${unit}`, width: 60, }, ]; return ( ); }; } ``` ## Localization To localize all components included in the Charts integration, choose one method for both the [Grid](/x/react-data-grid/localization/) and [Charts](/x/react-charts/localization/). We recommend using `createTheme()` and `ThemeProvider`. To get localized configuration options, use `getLocalizedConfigurationOptions()` instead of `configurationOptions`. The demo below shows how to incorporate localization into the integration using the `frFr` locale. ```tsx import * as React from 'react'; import { createTheme, useTheme, ThemeProvider } from '@mui/material/styles'; import { useDemoData } from '@mui/x-data-grid-generator'; import { DataGridPremium, GridChartsPanel, GridChartsIntegrationContextProvider, GridChartsRendererProxy, gridColumnGroupsUnwrappedModelSelector, GridEventListener, GridPivotModel, useGridApiRef, GridSidebarValue, } from '@mui/x-data-grid-premium'; import { frFR as frFRGrid } from '@mui/x-data-grid-premium/locales'; import { ChartsRenderer, getLocalizedConfigurationOptions, } from '@mui/x-charts-premium/ChartsRenderer'; import { frFR as frFRCharts, frFRLocalText } from '@mui/x-charts-premium/locales'; const configurationOptions = getLocalizedConfigurationOptions(frFRLocalText); // localized chart configuration options const frColumnHeaderNames = { commodity: 'Matière première', maturityDate: 'Date de maturité', quantity: 'Quantité', feeRate: 'Taux de frais', }; export default function GridChartsIntegrationLocalization() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 1000, editable: true, }); const apiRef = useGridApiRef(); // Inherit the theme from the docs site (dark/light mode) const existingTheme = useTheme(); const theme = React.useMemo( () => createTheme(frFRGrid, frFRCharts, existingTheme), [existingTheme], ); const columns = React.useMemo( () => data.columns.map((column) => frColumnHeaderNames[column.field as keyof typeof frColumnHeaderNames] ? { ...column, headerName: frColumnHeaderNames[ column.field as keyof typeof frColumnHeaderNames ], } : column, ), [data.columns], ); const pivotModel: GridPivotModel = { rows: [{ field: 'commodity' }], columns: [ { field: 'maturityDate-year', sort: 'asc' }, { field: 'maturityDate-quarter', sort: 'asc' }, ], values: [ { field: 'quantity', aggFunc: 'sum' }, { field: 'feeRate', aggFunc: 'avg' }, ], }; const initialState = { ...data.initialState, pivoting: { model: pivotModel, enabled: true, }, sidebar: { open: true, value: GridSidebarValue.Charts, }, chartsIntegration: { charts: { main: { dimensions: ['commodity'], chartType: 'column', }, }, }, }; const hasInitializedPivotingSeries = React.useRef(false); React.useEffect(() => { const handleColumnVisibilityModelChange: GridEventListener< 'columnVisibilityModelChange' > = () => { if (hasInitializedPivotingSeries.current) { return; } const unwrappedGroupingModel = Object.keys( gridColumnGroupsUnwrappedModelSelector(apiRef), ); // wait until pivoting creates column grouping model if (unwrappedGroupingModel.length === 0) { return; } hasInitializedPivotingSeries.current = true; // pick up the first 5 dyamically created columns with quantity in the name and enable first 3 apiRef.current?.updateChartValuesData( 'main', unwrappedGroupingModel .filter((field) => field.endsWith('quantity')) .slice(0, 5) .map((field, index) => ({ field, hidden: index >= 3 })), ); }; return apiRef.current?.subscribeEvent( 'columnVisibilityModelChange', handleColumnVisibilityModelChange, ); }, [apiRef]); return (
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/api/charts/charts-item-tooltip-content.md # ChartsItemTooltipContent API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Tooltip](/x/react-charts/tooltip/) ## Import ```jsx import { ChartsItemTooltipContent } from '@mui/x-charts/ChartsTooltip'; // or import { ChartsItemTooltipContent } from '@mui/x-charts'; // or import { ChartsItemTooltipContent } from '@mui/x-charts-pro'; // or import { ChartsItemTooltipContent } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsTooltip/ChartsItemTooltipContent.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsTooltip/ChartsItemTooltipContent.tsx) --- # Source: https://mui.com/x/api/charts/charts-localization-provider.md # ChartsLocalizationProvider API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Localization](/x/react-charts/localization/) ## Import ```jsx import { ChartsLocalizationProvider } from '@mui/x-charts/ChartsLocalizationProvider'; // or import { ChartsLocalizationProvider } from '@mui/x-charts'; // or import { ChartsLocalizationProvider } from '@mui/x-charts-pro'; // or import { ChartsLocalizationProvider } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | localeText | `object` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsLocalizationProvider/ChartsLocalizationProvider.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsLocalizationProvider/ChartsLocalizationProvider.tsx) --- # Source: https://mui.com/x/api/data-grid/charts-panel-trigger.md # ChartsPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - Charts Panel component 🚧 ## Import ```jsx import { ChartsPanelTrigger } from '@mui/x-data-grid-premium/components'; // or import { ChartsPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/chartsPanel/ChartsPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/chartsPanel/ChartsPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/components/charts-panel.md --- title: Data Grid - Charts Panel component productId: x-data-grid components: ChartsPanelTrigger packageName: '@mui/x-data-grid-premium' githubLabel: 'scope: data grid' --- # Data Grid - Charts Panel component [](/x/introduction/licensing/#premium-plan 'Premium plan') 🚧 Customize the Data Grid's Charts panel. :::warning This component is incomplete. Currently, the Charts Panel Trigger is the only part of the Charts Panel component available. Future versions of the Charts Panel component will make it possible to compose each of its parts for full customization. ::: The Charts panel is part of the [Charts integration feature](/x/react-data-grid/charts-integration/). You can use the Charts Panel Trigger and [Toolbar](/x/react-data-grid/components/toolbar/) components when you need to customize the Charts panel trigger, or when implementing a custom toolbar. ## Basic usage The demo below shows how to add a Charts Panel Trigger to a custom toolbar. ```tsx import { DataGridPremium, Toolbar, ToolbarButton, ChartsPanelTrigger, GridChartsPanel, GridChartsIcon, GridChartsIntegrationContextProvider, GridChartsRendererProxy, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; import Tooltip from '@mui/material/Tooltip'; import { configurationOptions } from '@mui/x-charts-premium/ChartsRenderer'; function CustomToolbar() { return ( }> ); } export default function GridChartsPanelTrigger() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 10, maxColumns: 10, }); return (
null} />
); } ``` ## Anatomy ```tsx import { ChartsPanelTrigger } from '@mui/x-data-grid-premium'; ; ``` ### Charts Panel Trigger `` is a button that opens and closes the Charts panel. It renders the `baseButton` slot. ## Custom elements Use the `render` prop to replace default elements. See [Components usage—Customization](/x/react-data-grid/components/usage/#customization) for more details. ## Accessibility ### ARIA You must apply a text label or an `aria-label` attribute to the ``. # ChartsPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - Charts Panel component 🚧 ## Import ```jsx import { ChartsPanelTrigger } from '@mui/x-data-grid-premium/components'; // or import { ChartsPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/chartsPanel/ChartsPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/chartsPanel/ChartsPanelTrigger.tsx) --- # Source: https://mui.com/x/api/charts/charts-reference-line.md # ChartsReferenceLine API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Axis](/x/react-charts/axis/) ## Import ```jsx import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; // or import { ChartsReferenceLine } from '@mui/x-charts'; // or import { ChartsReferenceLine } from '@mui/x-charts-pro'; // or import { ChartsReferenceLine } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | axisId | `number \| string` | `The `id` of the first defined axis.` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | label | `string` | - | No | | | labelAlign | `'end' \| 'middle' \| 'start'` | `'middle'` | No | | | labelStyle | `object` | - | No | | | lineStyle | `object` | - | No | | | spacing | `number \| { x?: number, y?: number }` | `{ x: 0, y: 5 } on a horizontal line and { x: 5, y: 0 } on a vertical line.` | No | | | x | `Date \| number \| string` | - | No | | | y | `Date \| number \| string` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | horizontal | Styles applied to the root element if the reference line is horizontal. | | - | label | Styles applied to the reference label. | | - | line | Styles applied to the reference line. | | - | root | Styles applied to the root element. | | - | vertical | Styles applied to the root element if the reference line is vertical. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsReferenceLine/ChartsReferenceLine.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsReferenceLine/ChartsReferenceLine.tsx) --- # Source: https://mui.com/x/api/charts/charts-surface.md # ChartsSurface API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Custom components](/x/react-charts/components/) - [Charts - Composition](/x/react-charts/composition/) ## Import ```jsx import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; // or import { ChartsSurface } from '@mui/x-charts'; // or import { ChartsSurface } from '@mui/x-charts-pro'; // or import { ChartsSurface } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsSurface/ChartsSurface.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsSurface/ChartsSurface.tsx) --- # Source: https://mui.com/x/api/charts/charts-text.md # ChartsText API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Axis](/x/react-charts/axis/) - [Charts - Legend](/x/react-charts/legend/) ## Import ```jsx import { ChartsText } from '@mui/x-charts/ChartsText'; // or import { ChartsText } from '@mui/x-charts'; // or import { ChartsText } from '@mui/x-charts-pro'; // or import { ChartsText } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | text | `string` | - | Yes | | | lineHeight | `number` | - | No | | | needsComputation | `bool` | `false` | No | | | style | `object` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsText/ChartsText.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsText/ChartsText.tsx) --- # Source: https://mui.com/x/api/charts/charts-toolbar-image-export-trigger.md # ChartsToolbarImageExportTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Toolbar](/x/react-charts/toolbar/) ## Import ```jsx import { ChartsToolbarImageExportTrigger } from '@mui/x-charts-pro/ChartsToolbarPro'; // or import { ChartsToolbarImageExportTrigger } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | options | `{ copyStyles?: bool, fileName?: string, nonce?: string, onBeforeExport?: func, quality?: number, type: string }` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarImageExportTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarImageExportTrigger.tsx) --- # Source: https://mui.com/x/api/charts/charts-toolbar-print-export-trigger.md # ChartsToolbarPrintExportTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Toolbar](/x/react-charts/toolbar/) ## Import ```jsx import { ChartsToolbarPrintExportTrigger } from '@mui/x-charts-pro/ChartsToolbarPro'; // or import { ChartsToolbarPrintExportTrigger } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | options | `{ copyStyles?: bool, fileName?: string, nonce?: string, onBeforeExport?: func }` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarPrintExportTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarPrintExportTrigger.tsx) --- # Source: https://mui.com/x/api/charts/charts-toolbar-pro.md # ChartsToolbarPro API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Toolbar](/x/react-charts/toolbar/) ## Import ```jsx import { ChartsToolbarPro } from '@mui/x-charts-pro/ChartsToolbarPro'; // or import { ChartsToolbarPro } from '@mui/x-charts-pro'; ``` > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarPro.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarPro.tsx) --- # Source: https://mui.com/x/api/charts/charts-toolbar-zoom-in-trigger.md # ChartsToolbarZoomInTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Toolbar](/x/react-charts/toolbar/) ## Import ```jsx import { ChartsToolbarZoomInTrigger } from '@mui/x-charts-pro/ChartsToolbarPro'; // or import { ChartsToolbarZoomInTrigger } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarZoomInTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarZoomInTrigger.tsx) --- # Source: https://mui.com/x/api/charts/charts-toolbar-zoom-out-trigger.md # ChartsToolbarZoomOutTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Toolbar](/x/react-charts/toolbar/) ## Import ```jsx import { ChartsToolbarZoomOutTrigger } from '@mui/x-charts-pro/ChartsToolbarPro'; // or import { ChartsToolbarZoomOutTrigger } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarZoomOutTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/ChartsToolbarPro/ChartsToolbarZoomOutTrigger.tsx) --- # Source: https://mui.com/x/api/charts/charts-tooltip-container.md # ChartsTooltipContainer API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Tooltip](/x/react-charts/tooltip/) ## Import ```jsx import { ChartsTooltipContainer } from '@mui/x-charts/ChartsTooltip'; // or import { ChartsTooltipContainer } from '@mui/x-charts'; // or import { ChartsTooltipContainer } from '@mui/x-charts-pro'; // or import { ChartsTooltipContainer } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | anchor | `'node' \| 'pointer'` | `'pointer'` | No | | | anchorEl | `HTML element \| object \| func` | - | No | | | children | `node` | - | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | component | `elementType` | - | No | | | components (deprecated) | `{ Root?: elementType }` | `{}` | No | ⚠️ use the `slots` prop instead. This prop will be removed in a future major release. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | | componentsProps (deprecated) | `{ root?: func \| object }` | `{}` | No | ⚠️ use the `slotProps` prop instead. This prop will be removed in a future major release. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | | container | `(props, propName) => { if (props[propName] == null) { return new Error(`Prop '${propName}' is required but wasn't specified`); } if (typeof props[propName] !== 'object' \| \| props[propName].nodeType !== 1) { return new Error(`Expected prop '${propName}' to be of type Element`); } return null; } \| func` | - | No | | | disablePortal | `bool` | `false` | No | | | keepMounted | `bool` | `false` | No | | | modifiers | `Array<{ data?: object, effect?: func, enabled?: bool, fn?: func, name?: any, options?: object, phase?: 'afterMain' \| 'afterRead' \| 'afterWrite' \| 'beforeMain' \| 'beforeRead' \| 'beforeWrite' \| 'main' \| 'read' \| 'write', requires?: Array, requiresIfExists?: Array }>` | - | No | | | open | `bool` | - | No | | | placement | `'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top'` | `'bottom'` | No | | | popperOptions | `{ modifiers?: array, onFirstUpdate?: func, placement?: 'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top', strategy?: 'absolute' \| 'fixed' }` | `{}` | No | | | popperRef | `func \| { current?: { destroy: func, forceUpdate: func, setOptions: func, state: { attributes: object, elements: object, modifiersData: object, options: object, orderedModifiers: Array, placement: 'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top', rects: object, reset: bool, scrollParents: object, strategy: 'absolute' \| 'fixed', styles: object }, update: func } }` | - | No | | | position | `'bottom' \| 'left' \| 'right' \| 'top'` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | transition | `bool` | `false` | No | | | trigger | `'axis' \| 'item' \| 'none'` | `'axis'` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsTooltip/ChartsTooltipContainer.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsTooltip/ChartsTooltipContainer.tsx) --- # Source: https://mui.com/x/api/charts/charts-tooltip.md # ChartsTooltip API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Tooltip](/x/react-charts/tooltip/) ## Import ```jsx import { ChartsTooltip } from '@mui/x-charts/ChartsTooltip'; // or import { ChartsTooltip } from '@mui/x-charts'; // or import { ChartsTooltip } from '@mui/x-charts-pro'; // or import { ChartsTooltip } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | anchor | `'node' \| 'pointer'` | `'pointer'` | No | | | anchorEl | `HTML element \| object \| func` | - | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | component | `elementType` | - | No | | | components (deprecated) | `{ Root?: elementType }` | `{}` | No | ⚠️ use the `slots` prop instead. This prop will be removed in a future major release. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | | componentsProps (deprecated) | `{ root?: func \| object }` | `{}` | No | ⚠️ use the `slotProps` prop instead. This prop will be removed in a future major release. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | | container | `(props, propName) => { if (props[propName] == null) { return new Error(`Prop '${propName}' is required but wasn't specified`); } if (typeof props[propName] !== 'object' \| \| props[propName].nodeType !== 1) { return new Error(`Expected prop '${propName}' to be of type Element`); } return null; } \| func` | - | No | | | disablePortal | `bool` | `false` | No | | | keepMounted | `bool` | `false` | No | | | modifiers | `Array<{ data?: object, effect?: func, enabled?: bool, fn?: func, name?: any, options?: object, phase?: 'afterMain' \| 'afterRead' \| 'afterWrite' \| 'beforeMain' \| 'beforeRead' \| 'beforeWrite' \| 'main' \| 'read' \| 'write', requires?: Array, requiresIfExists?: Array }>` | - | No | | | open | `bool` | - | No | | | placement | `'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top'` | `'bottom'` | No | | | popperOptions | `{ modifiers?: array, onFirstUpdate?: func, placement?: 'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top', strategy?: 'absolute' \| 'fixed' }` | `{}` | No | | | popperRef | `func \| { current?: { destroy: func, forceUpdate: func, setOptions: func, state: { attributes: object, elements: object, modifiersData: object, options: object, orderedModifiers: Array, placement: 'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top', rects: object, reset: bool, scrollParents: object, strategy: 'absolute' \| 'fixed', styles: object }, update: func } }` | - | No | | | position | `'bottom' \| 'left' \| 'right' \| 'top'` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | transition | `bool` | `false` | No | | | trigger | `'axis' \| 'item' \| 'none'` | `'axis'` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | axisValueCell | Styles applied to the axisValueCell element. Only available for axis tooltip. | | - | cell | Styles applied to the cell element. | | - | labelCell | Styles applied to the labelCell element. | | - | mark | Styles applied to the mark element. | | - | markContainer | Styles applied to the markContainer element. | | - | paper | Styles applied to the paper element. | | - | root | Styles applied to the root element. | | - | row | Styles applied to the row element. | | - | table | Styles applied to the table element. | | - | valueCell | Styles applied to the valueCell element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsTooltip/ChartsTooltip.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsTooltip/ChartsTooltip.tsx) --- # Source: https://mui.com/x/api/charts/charts-wrapper.md # ChartsWrapper API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Pie](/x/react-charts/pie/) - [Charts - Radar](/x/react-charts/radar/) - [Charts - Scatter](/x/react-charts/scatter/) ## Import ```jsx import { ChartsWrapper } from '@mui/x-charts/ChartsWrapper'; // or import { ChartsWrapper } from '@mui/x-charts'; // or import { ChartsWrapper } from '@mui/x-charts-pro'; // or import { ChartsWrapper } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | extendVertically | `bool` | ``false` if the `height` prop is set. And `true` otherwise.` | No | | | hideLegend | `bool` | `false` | No | | | legendDirection | `'horizontal' \| 'vertical'` | `'horizontal'` | No | | | legendPosition | `{ horizontal?: 'center' \| 'end' \| 'start', vertical?: 'bottom' \| 'middle' \| 'top' }` | `{ horizontal: 'center', vertical: 'bottom' }` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsWrapper/ChartsWrapper.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsWrapper/ChartsWrapper.tsx) --- # Source: https://mui.com/x/api/charts/charts-x-axis.md # ChartsXAxis API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Axis](/x/react-charts/axis/) ## Import ```jsx import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; // or import { ChartsXAxis } from '@mui/x-charts'; // or import { ChartsXAxis } from '@mui/x-charts-pro'; // or import { ChartsXAxis } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | axisId | `number \| string` | - | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | disableLine | `bool` | `false` | No | | | disableTicks | `bool` | `false` | No | | | label | `string` | - | No | | | labelStyle | `object` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tickInterval | `'auto' \| array \| func` | `'auto'` | No | | | tickLabelInterval | `'auto' \| func` | `'auto'` | No | | | tickLabelMinGap | `number` | `4` | No | | | tickLabelPlacement | `'middle' \| 'tick'` | `'middle'` | No | | | tickLabelStyle | `object` | - | No | | | tickMaxStep | `number` | - | No | | | tickMinStep | `number` | - | No | | | tickNumber | `number` | - | No | | | tickPlacement | `'end' \| 'extremities' \| 'middle' \| 'start'` | `'extremities'` | No | | | tickSize | `number` | `6` | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsXAxis/ChartsXAxis.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsXAxis/ChartsXAxis.tsx) --- # Source: https://mui.com/x/api/charts/charts-y-axis.md # ChartsYAxis API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Axis](/x/react-charts/axis/) ## Import ```jsx import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; // or import { ChartsYAxis } from '@mui/x-charts'; // or import { ChartsYAxis } from '@mui/x-charts-pro'; // or import { ChartsYAxis } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | axisId | `number \| string` | - | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | disableLine | `bool` | `false` | No | | | disableTicks | `bool` | `false` | No | | | label | `string` | - | No | | | labelStyle | `object` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tickInterval | `'auto' \| array \| func` | `'auto'` | No | | | tickLabelInterval | `'auto' \| func` | `'auto'` | No | | | tickLabelPlacement | `'middle' \| 'tick'` | `'middle'` | No | | | tickLabelStyle | `object` | - | No | | | tickMaxStep | `number` | - | No | | | tickMinStep | `number` | - | No | | | tickNumber | `number` | - | No | | | tickPlacement | `'end' \| 'extremities' \| 'middle' \| 'start'` | `'extremities'` | No | | | tickSize | `number` | `6` | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsYAxis/ChartsYAxis.tsx) --- # Source: https://mui.com/x/react-data-grid/clipboard.md # Data Grid - Copy and paste Copy and paste data using clipboard. ## Clipboard copy You can copy selected grid data to the clipboard using the Ctrl+C (⌘ Command+C on macOS) keyboard shortcut. The copied cell values are separated by a tab (`\t`) character and the rows are separated by a new line (`\n`) character. The priority of the data copied to the clipboard is the following, from highest to lowest: 1. If more than one cell is selected (see [Cell selection](/x/react-data-grid/cell-selection/)), the selected cells are copied 2. If one or more rows are selected (see [Row selection](/x/react-data-grid/row-selection/)), the selected rows are copied 3. If there is a single cell selected, the single cell is copied ```tsx import * as React from 'react'; import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; import Alert from '@mui/material/Alert'; import AlertTitle from '@mui/material/AlertTitle'; export default function ClipboardCopy() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 20, }); const [copiedData, setCopiedData] = React.useState(''); const initialState = { ...data.initialState, columns: { columnVisibilityModel: { id: false, desk: false, }, }, }; return (
setCopiedData(copiedString)} ignoreValueFormatterDuringExport />
Copied data: {copiedData}
); } ``` ## Clipboard paste [](/x/introduction/licensing/#premium-plan 'Premium plan') :::info
Video preview
::: :::warning To make sure the copied cells are formatted correctly and can be parsed, it is recommended to set the `ignoreValueFormatterDuringExport` prop to `true`. During clipboard copy operation, the raw cell values will be copied instead of the formatted values, so that the values can be parsed correctly during the paste operation. ```tsx ``` ::: You can paste data from clipboard using the Ctrl+V (⌘ Command+V on macOS) keyboard shortcut. The paste operation only affects cells in the columns that are [`editable`](/x/react-data-grid/editing/#making-a-column-editable). Same as with editing, you can use `valueParser` to modify the pasted value and `valueSetter` to update the row with new values. See [Value parser and value setter](/x/react-data-grid/editing/#value-parser-and-value-setter) section of the editing documentation for more details. The behavior of the clipboard paste operation depends on the selection state of the Data Grid and the data pasted from clipboard. The priority is the following, from highest to lowest: 1. If multiple cells are selected (see [Cell selection](/x/react-data-grid/cell-selection/)), the selected cells are updated with the pasted values. 2. If one or more rows are selected (see [Row selection](/x/react-data-grid/row-selection/)), the selected rows are updated with the pasted values. 3. If a single cell is selected, the values are pasted starting from the selected cell. ```tsx import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function ClipboardPaste() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 20, editable: true, }); const initialState = { ...data.initialState, columns: { columnVisibilityModel: { id: false, desk: false, }, }, }; return (
); } ``` ### Disable clipboard paste To disable clipboard paste, set the `disableClipboardPaste` prop to `true`: ```tsx import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function ClipboardPasteDisabled() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 6, editable: true, }); return (
); } ``` ### Disable pasting to the specific cells within a row The clipboard paste operation respects the [cell editing rules](/x/react-data-grid/editing/#disable-editing-of-specific-cells-within-a-row). Use this to prevent pasting into certain cells based on row data or other conditions. The demo below shows a product inventory grid with the following paste restrictions: - **Price column:** Cannot be pasted in archived products - **Status column:** Cannot be pasted in any row - **Last Modified column:** Cannot be pasted in any row Try selecting multiple cells and pasting data. Cells marked as non-editable by `isCellEditable` will not be updated. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Chip from '@mui/material/Chip'; import { DataGridPremium, GridColDef, DataGridPremiumProps, } from '@mui/x-data-grid-premium'; interface Row { id: number; product: string; quantity: number; price: number; status: 'active' | 'archived'; lastModified: string; } const rows: Row[] = [ { id: 1, product: 'Laptop', quantity: 10, price: 999.99, status: 'active', lastModified: '2024-01-15', }, { id: 2, product: 'Mouse', quantity: 50, price: 29.99, status: 'active', lastModified: '2024-01-16', }, { id: 3, product: 'Keyboard', quantity: 30, price: 79.99, status: 'archived', lastModified: '2024-01-10', }, { id: 4, product: 'Monitor', quantity: 15, price: 299.99, status: 'active', lastModified: '2024-01-17', }, { id: 5, product: 'Headphones', quantity: 25, price: 149.99, status: 'archived', lastModified: '2024-01-05', }, ]; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 70 }, { field: 'product', headerName: 'Product', width: 150, editable: true }, { field: 'quantity', headerName: 'Quantity', width: 120, editable: true }, { field: 'price', headerName: 'Price', width: 120, editable: true }, { field: 'status', headerName: 'Status', width: 120, editable: false, renderCell: (params) => ( ), }, { field: 'lastModified', headerName: 'Last Modified', width: 150, editable: false, }, ]; const isCellEditable: DataGridPremiumProps['isCellEditable'] = (params) => { // Price cannot be edited for archived products if (params.field === 'price' && params.row.status === 'archived') { return false; } return true; }; export default function ClipboardPasteIsCellEditable() { return ( ); } ``` ### Persisting pasted data Clipboard paste uses the same API for persistence as [Editing](/x/react-data-grid/editing/persistence/)—use the `processRowUpdate` prop to persist the updated row in your data source: ```tsx processRowUpdate?: (newRow: R, oldRow: R) => Promise | R; ``` The row will be updated with a value returned by the `processRowUpdate` callback. If the callback throws or returns a rejected promise, the row will not be updated. The demo below shows how to persist the pasted data in the browser's `sessionStorage`. ```tsx import * as React from 'react'; import { DataGridPremium, GridValidRowModel, DataGridPremiumProps, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; import Button from '@mui/material/Button'; const initialRows = [ { id: '9feb3743-fbf1-585b-ae15-25a1e91126d1', desk: 'D-7702', commodity: 'Frozen Concentrated Orange Juice', traderName: 'Jeffrey Nichols', traderEmail: 'weg@tozezew.mz', quantity: 22542, filledQuantity: 0.6027859107443883, }, { id: '6aa80501-f0f1-50e4-95d9-94eac5536d24', desk: 'D-5855', commodity: 'Oats', traderName: 'Henrietta Gill', traderEmail: 'ha@ovuewadip.ca', quantity: 39244, filledQuantity: 0.5139893996534503, }, { id: 'd4d49ff6-9a37-5490-94b3-c3dea5c8f787', desk: 'D-8853', commodity: 'Cocoa', traderName: 'Harriet Peters', traderEmail: 'wezbibil@meced.pt', quantity: 81111, filledQuantity: 0.24879486136282378, }, { id: '1db4a0e5-aca2-5ae7-89f1-aca3756c6c2c', desk: 'D-3882', commodity: 'Wheat', traderName: 'Polly Sims', traderEmail: 'ujaacazas@pobgag.ye', quantity: 91665, filledQuantity: 0.7220967653957344, }, { id: 'cc24d3fc-0d9b-56f1-8cdd-89199092e711', desk: 'D-94', commodity: 'Sugar No.14', traderName: 'Jim Pratt', traderEmail: 'irno@re.iq', quantity: 98763, filledQuantity: 0.9177019734110953, }, { id: '181ae856-c185-5895-a996-9ed822f31721', desk: 'D-8570', commodity: 'Frozen Concentrated Orange Juice', traderName: 'Erik Kelley', traderEmail: 'pado@dawom.ar', quantity: 8524, filledQuantity: 0.5193571093383388, }, { id: '3a199260-246e-5bb7-a20e-04d4dfae798d', desk: 'D-2253', commodity: 'Adzuki bean', traderName: 'Victor Howell', traderEmail: 'zi@orager.cl', quantity: 60806, filledQuantity: 0.9243989080024998, }, { id: 'ad1bdfe2-4dbd-58bb-b432-f4c50b2e8de8', desk: 'D-6307', commodity: 'Soybeans', traderName: 'Ethan Clark', traderEmail: 'wij@nepocreh.tt', quantity: 48391, filledQuantity: 0.7982062780269058, }, { id: '6040095c-da9b-507f-8bc2-5c0511019d2c', desk: 'D-2429', commodity: 'Corn', traderName: 'Katie Long', traderEmail: 'doga@raecu.gg', quantity: 51252, filledQuantity: 0.08549910247404979, }, { id: '1f90134c-c9b0-556f-b60b-cd7d150f124c', desk: 'D-4598', commodity: 'Soybeans', traderName: 'Etta Marsh', traderEmail: 'riztuw@rol.jo', quantity: 59123, filledQuantity: 0.619099166145155, }, { id: 'f3fb76f5-82b4-562e-b873-bec5f9a09e07', desk: 'D-9116', commodity: 'Soybean Meal', traderName: 'Emma Wilkerson', traderEmail: 'vispuhgoh@adkimac.kr', quantity: 4861, filledQuantity: 0.756222999382843, }, { id: '468f03c0-ee5a-51d4-807e-e65b108ed7ca', desk: 'D-9046', commodity: 'Robusta coffee', traderName: 'Douglas Boone', traderEmail: 'givuce@jisalta.jp', quantity: 41630, filledQuantity: 0.5862118664424694, }, { id: '856c6022-f062-57fe-a618-b8a044d94995', desk: 'D-5940', commodity: 'Coffee C', traderName: 'Delia Collins', traderEmail: 'ga@pukop.kg', quantity: 42184, filledQuantity: 0.17279063151905935, }, { id: 'e67a7da2-623e-5a37-afe7-d9d61f6c6707', desk: 'D-166', commodity: 'Oats', traderName: 'Carl Allison', traderEmail: 'biviv@loucu.jm', quantity: 42818, filledQuantity: 0.24769956560325096, }, { id: 'fde4e74d-77f8-5325-8401-8093cea3b48d', desk: 'D-2177', commodity: 'Soybean Oil', traderName: 'Jeffrey Stone', traderEmail: 'vaj@wazvi.fr', quantity: 66766, filledQuantity: 0.3001977054189258, }, { id: '874e66e5-435d-555c-9ccf-4a776446b1c3', desk: 'D-1732', commodity: 'Oats', traderName: 'Jason Holland', traderEmail: 'lef@nameteh.com', quantity: 79141, filledQuantity: 0.3829999620929733, }, { id: '95379b05-69e2-56da-997c-3e5c3892af8d', desk: 'D-5479', commodity: 'Rapeseed', traderName: 'Alfred Cortez', traderEmail: 'loeg@ufooni.eu', quantity: 77715, filledQuantity: 0.35680370584829185, }, { id: 'b71a1c39-dd89-59e4-90ed-0eba4708d2bf', desk: 'D-7786', commodity: 'Frozen Concentrated Orange Juice', traderName: 'Eddie Olson', traderEmail: 'sigjap@vas.sc', quantity: 78507, filledQuantity: 0.7016953902199804, }, { id: '8d3305fd-40a5-5b91-a677-7c3a12f42abb', desk: 'D-3166', commodity: 'Frozen Concentrated Orange Juice', traderName: 'Louisa Coleman', traderEmail: 'nezcen@mihrotab.pa', quantity: 47797, filledQuantity: 0.16090968052388224, }, { id: '1da5290b-1990-58a5-bcba-bd0ab6a38ce9', desk: 'D-6935', commodity: 'Soybean Oil', traderName: 'Franklin Barrett', traderEmail: 'be@fejafo.au', quantity: 95833, filledQuantity: 0.47529556624544783, }, ]; const visibleFields = [ 'commodity', 'traderName', 'traderEmail', 'quantity', 'filledQuantity', ]; const useSessionStorageData = () => { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 0, maxColumns: 7, editable: true, visibleFields, }); const [rows] = React.useState(() => { try { const lsData = sessionStorage.getItem('clipboardImportRows'); if (lsData) { const parsedData = JSON.parse(lsData); if (Array.isArray(parsedData)) { return parsedData; } } } catch (error) { // session storage is not available } return initialRows; }); const rowsRef = React.useRef([...rows]); const updateRow = React.useCallback((newRow: GridValidRowModel) => { const index = rowsRef.current.findIndex((row) => row.id === newRow.id); rowsRef.current[index] = newRow; sessionStorage.setItem('clipboardImportRows', JSON.stringify(rowsRef.current)); }, []); return { data: { ...data, rows }, updateRow, }; }; export default function ClipboardPastePersistence() { const { data, updateRow } = useSessionStorageData(); const processRowUpdate: NonNullable = ( newRow, ) => { updateRow(newRow); return newRow; }; return (
); } ``` ### Events The following events are fired during the clipboard paste operation: - `clipboardPasteStart` - fired when the clipboard paste operation starts - `clipboardPasteEnd` - fired when all row updates from clipboard paste have been processed For convenience, you can also listen to these events using their respective props: - `onClipboardPasteStart` - `onClipboardPasteEnd` Additionally, there is the `onBeforeClipboardPasteStart` prop, which is called before the clipboard paste operation starts and can be used to cancel or confirm the paste operation: ```tsx const onBeforeClipboardPasteStart = async () => { const confirmed = window.confirm('Are you sure you want to paste?'); if (!confirmed) { throw new Error('Paste operation cancelled'); } }; ; ``` The demo below uses the [`Dialog`](/material-ui/react-dialog/) component for paste confirmation. If confirmed, the Data Grid displays a loading indicator during the paste operation. ```tsx import * as React from 'react'; import { DataGridPremium, DataGridPremiumProps } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; import Dialog from '@mui/material/Dialog'; import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; import Button from '@mui/material/Button'; export default function ClipboardPasteEvents() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 6, editable: true, }); const [loading, setLoading] = React.useState(false); const processRowUpdate = React.useCallback< NonNullable >(async (newRow) => { await new Promise((resolve) => { setTimeout(resolve, 1000); }); return newRow; }, []); const initialState = { ...data.initialState, columns: { columnVisibilityModel: { id: false, desk: false, }, }, }; const confirm = useConfirm(); const confirmPaste = React.useCallback<() => Promise>(() => { return new Promise((resolve, reject) => { confirm.open((confirmed) => { if (confirmed) { resolve(); } else { reject(); } }); }); }, [confirm]); return (
setLoading(true)} onClipboardPasteEnd={() => setLoading(false)} ignoreValueFormatterDuringExport disableRowSelectionOnClick /> {'Are you sure you want to paste?'} This will overwrite the selected cells.
); } const useConfirm = () => { const [isOpen, setIsOpen] = React.useState(false); const callbackRef = React.useRef<((confirmed: boolean) => void) | null>(null); const open = React.useCallback((callback: (confirmed: boolean) => void) => { setIsOpen(true); callbackRef.current = callback; }, []); const cancel = React.useCallback(() => { setIsOpen(false); callbackRef.current?.(false); callbackRef.current = null; }, []); const confirm = React.useCallback(() => { setIsOpen(false); callbackRef.current?.(true); callbackRef.current = null; }, []); return { open, isOpen, cancel, confirm, }; }; ``` ## Format of the clipboard data By default, the clipboard copy and paste operations use the following format: - The cell values are separated by a tab (`\t`) character. - The rows are separated by a new line (`\n`) character. You can use `clipboardCopyCellDelimiter` and `splitClipboardPastedText` props to change the format: ```tsx text.split('\n').map((row) => row.split(','))} /> ``` The demo below uses `,` (comma) character as a cell delimiter for both copy and paste operations: ```tsx import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function ClipboardPasteDelimiter() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 20, editable: true, }); const initialState = { ...data.initialState, columns: { columnVisibilityModel: { id: false, desk: false, }, }, }; return (
text.split('\n').map((row) => row.split(',')) } />
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-definition.md # Data Grid - Column definition Define your columns. The columns are defined with the `columns` prop which has the type `GridColDef[]`. `field` is the only required property since it's the column identifier. It's also used to match with `GridRowModel` values. ```ts interface GridColDef { /** * The column identifier. It's used to match with [[GridRowModel]] values. */ field: string; … } ``` ```tsx import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; export default function BasicColumnsGrid() { return ( ); } ``` :::warning The `columns` prop should keep the same reference between two renders. The columns are designed to be definitions, to never change once the component is mounted. Otherwise, you take the risk of losing elements like column width or order. You can create the array outside the render function or memoize it. ::: ## Providing content By default, the Data Grid uses the field of a column to get its value. For instance, the column with field `name` will render the value stored in `row.name`. But for some columns, it can be useful to manually get and format the value to render. ### Value getter :::warning Note that the signature of `valueGetter` has changed in v7 – see the [migration guide](https://mui.com/x/migration/migration-data-grid-v6/) for details. If you're using v6, please use the [v6 documentation](https://v6.mui.com/x/react-data-grid/column-definition/#value-getter). ::: Sometimes a column might not have a desired value. You can use the `valueGetter` attribute of `GridColDef` to: 1. Transform the value ```tsx const columns: GridColDef[] = [ { field: 'taxRate', valueGetter: (value) => { if (!value) { return value; } // Convert the decimal value to a percentage return value * 100; }, }, ]; ``` 2. Render a combination of different fields ```tsx const columns: GridColDef[] = [ { field: 'fullName', valueGetter: (value, row) => { return `${row.firstName || ''} ${row.lastName || ''}`; }, }, ]; ``` 3. Derive a value from a complex value ```tsx const columns: GridColDef[] = [ { field: 'profit', valueGetter: (value, row) => { if (!row.gross || !row.costs) { return null; } return row.gross - row.costs; }, }, ]; ``` The value returned by `valueGetter` is used for: - Filtering - Sorting - Rendering (unless enhanced further by [`valueFormatter`](/x/react-data-grid/column-definition/#value-formatter) or [`renderCell`](/x/react-data-grid/column-definition/#rendering-cells)) ```tsx import Box from '@mui/material/Box'; import { DataGrid, GridColDef, GridValueGetter } from '@mui/x-data-grid'; const rows = [ { id: 1, lastName: 'Snow', firstName: 'Jon' }, { id: 2, lastName: 'Lannister', firstName: 'Cersei' }, { id: 3, lastName: 'Lannister', firstName: 'Jaime' }, { id: 4, lastName: 'Stark', firstName: 'Arya' }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys' }, ]; const getFullName: GridValueGetter<(typeof rows)[number], unknown> = ( value, row, ) => { return `${row.firstName || ''} ${row.lastName || ''}`; }; const columns: GridColDef[] = [ { field: 'firstName', headerName: 'First name', width: 130 }, { field: 'lastName', headerName: 'Last name', width: 130 }, { field: 'fullName', headerName: 'Full name', width: 160, valueGetter: getFullName, }, ]; export default function ValueGetterGrid() { return ( ); } ``` :::warning `valueGetter` can be called for autogenerated rows, which are created when features like [row grouping](/x/react-data-grid/row-grouping/) or [aggregation](/x/react-data-grid/aggregation/) are used. Read more in the [handling autogenerated rows](/x/react-data-grid/column-definition/#autogenerated-rows) section. ::: :::warning [Row grouping](/x/react-data-grid/row-grouping/) uses the [`groupingValueGetter()`](/x/react-data-grid/row-grouping/#using-groupingvaluegetter-for-complex-grouping-value) instead of `valueGetter` to get the value for the grouping. The value passed to the `groupingValueGetter()` is the raw row value (`row[field]`) even if the column definition has a `valueGetter` defined. ::: ### Value formatter :::warning Note that the signature of `valueFormatter` has changed in v7 – see the [migration guide](https://mui.com/x/migration/migration-data-grid-v6/) for details. If you're using v6, please use the [v6 documentation](https://v6.mui.com/x/react-data-grid/column-definition/#value-formatter). ::: The value formatter lets you convert the value before displaying it. Common use cases include converting a JavaScript `Date` object to a date string or a `Number` into a formatted number (for example "1,000.50"). Note, that the value returned by `valueFormatter` is only used for rendering purposes. Filtering and sorting are based on the raw value (`row[field]`) or the value returned by [`valueGetter`](/x/react-data-grid/column-definition/#value-getter). In the following demo, `valueGetter` is used to convert the tax rate (for example `0.2`) to a decimal value (for example `20`), and `valueFormatter` is used to display it as a percentage (for example `20%`). ```tsx import { DataGrid } from '@mui/x-data-grid'; const rows = [ { id: 1, taxRate: 0.1, }, { id: 2, taxRate: 0.2, }, { id: 3, taxRate: 0.3, }, ]; export default function ValueFormatterGrid() { return (
{ if (!value) { return value; } return value * 100; }, valueFormatter: (value?: number) => { if (value == null) { return ''; } return `${value.toLocaleString()} %`; }, }, ]} />
); } ``` :::warning `valueFormatter` can be called for autogenerated rows, which are created when features like [row grouping](/x/react-data-grid/row-grouping/) or [aggregation](/x/react-data-grid/aggregation/) are used. Read more in the [handling autogenerated rows](/x/react-data-grid/column-definition/#autogenerated-rows) section. ::: ## Rendering cells By default, the Data Grid renders the value as a string in the cell. It resolves the rendered output in the following order: 1. `renderCell() => ReactElement` 2. `valueFormatter() => string` 3. `valueGetter() => string` 4. `row[field]` The `renderCell` method of the column definitions is similar to `valueFormatter`. However, it trades the ability to only render in a cell in exchange for letting you return a React node (instead of a string). ```tsx const columns: GridColDef[] = [ { field: 'date', headerName: 'Year', renderCell: (params: GridRenderCellParams) => ( {params.value.getFullYear()} ), }, ]; ``` ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import { DataGrid, GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; import { TouchRippleActions } from '@mui/material/ButtonBase/TouchRipple'; function RenderDate(props: GridRenderCellParams) { const { hasFocus, value } = props; const buttonElement = React.useRef(null); const rippleRef = React.useRef(null); React.useLayoutEffect(() => { if (hasFocus) { const input = buttonElement.current!.querySelector('input'); input?.focus(); } else if (rippleRef.current) { // Only available in @mui/material v5.4.1 or later rippleRef.current.stop({} as any); } }, [hasFocus]); return ( {value?.getFullYear() ?? ''} ); } const columns: GridColDef[] = [ { field: 'date', headerName: 'Year', width: 150, renderCell: RenderDate, }, ]; const rows = [ { id: 1, date: new Date(1979, 0, 1), }, { id: 2, date: new Date(1984, 1, 1), }, { id: 3, date: new Date(1992, 2, 1), }, ]; export default function RenderCellGrid() { return (
); } ``` :::warning When using `renderCell`, if the type of the value returned by `valueGetter` does not correspond to the column's `type`, you should: - handle [sorting](/x/react-data-grid/sorting/#custom-comparator) by providing `sortComparator` to the column. - set a `valueFormatter` providing a representation for the value to be used when [exporting](/x/react-data-grid/export/#exported-cells) the data. ::: :::warning `renderCell` can be called for autogenerated rows, which are created when features like [row grouping](/x/react-data-grid/row-grouping/) or [aggregation](/x/react-data-grid/aggregation/) are used. Read more in the [handling autogenerated rows](/x/react-data-grid/column-definition/#autogenerated-rows) section. ::: ### Styling cells You can check the [styling cells](/x/react-data-grid/style/#styling-cells) section for more information. ### Making accessible cells Cell content should not be in the tab sequence except if cell is focused. You can check the [tab sequence](/x/react-data-grid/accessibility/#tab-sequence) section for more information. ### Using hooks inside a renderer The `renderCell` property is a function that returns a React node, not a React component. If you want to use React hooks inside your renderer, you should wrap them inside a component. ```tsx // ❌ Not valid const column = { // ...other properties, renderCell: () => { const [count, setCount] = React.useState(0); return ( ); }, }; // ✅ Valid const CountButton = () => { const [count, setCount] = React.useState(0); return ( ); }; const column = { // ...other properties, renderCell: () => , }; ``` :::warning Because of pagination and virtualization, cells can be unmounted when scrolling or switching pages. The internal state of the component returned by renderCell will be lost. If you want the cell information to persist, you should save it either in the Data Grid state or in the Data Grid parent. ::: ### Expand cell renderer By default, the Data Grid cuts the content of a cell and renders an ellipsis if the content of the cell does not fit in the cell. As a workaround, you can create a cell renderer that lets users see the full content of the cell in the Data Grid. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; import Popper from '@mui/material/Popper'; import { DataGrid, GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; interface GridCellExpandProps { value: string; width: number; } function isOverflown(element: Element): boolean { return ( element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth ); } const GridCellExpand = React.memo(function GridCellExpand( props: GridCellExpandProps, ) { const { width, value } = props; const wrapper = React.useRef(null); const cellDiv = React.useRef(null); const cellValue = React.useRef(null); const [anchorEl, setAnchorEl] = React.useState(null); const [showFullCell, setShowFullCell] = React.useState(false); const [showPopper, setShowPopper] = React.useState(false); const handleMouseEnter = () => { const isCurrentlyOverflown = isOverflown(cellValue.current!); setShowPopper(isCurrentlyOverflown); setAnchorEl(cellDiv.current); setShowFullCell(true); }; const handleMouseLeave = () => { setShowFullCell(false); }; React.useEffect(() => { if (!showFullCell) { return undefined; } function handleKeyDown(nativeEvent: KeyboardEvent) { if (nativeEvent.key === 'Escape') { setShowFullCell(false); } } document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('keydown', handleKeyDown); }; }, [setShowFullCell, showFullCell]); return ( {value} {showPopper && ( {value} )} ); }); function renderCellExpand(params: GridRenderCellParams) { return ( ); } const columns: GridColDef[] = [ { field: 'col1', headerName: 'Column 1', width: 80, renderCell: renderCellExpand }, { field: 'col2', headerName: 'Column 2', width: 100, renderCell: renderCellExpand, }, { field: 'col3', headerName: 'Column 3', width: 150, renderCell: renderCellExpand, }, ]; const rows: any = [ { id: 1, col1: 'Hello', col2: 'World', col3: 'In publishing and graphic design, Lorem ipsum is a placeholder text commonly used.', }, { id: 2, col1: 'DataGridPro', col2: 'is Awesome', col3: 'In publishing and graphic design, Lorem ipsum is a placeholder text or a typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before final copy is available.', }, { id: 3, col1: 'MUI', col2: 'is Amazing', col3: 'Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before final copy is available.', }, { id: 4, col1: 'Hello', col2: 'World', col3: 'In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form.', }, { id: 5, col1: 'DataGridPro', col2: 'is Awesome', col3: 'Typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before final copy is available.', }, { id: 6, col1: 'MUI', col2: 'is Amazing', col3: 'Lorem ipsum may be used as a placeholder before final copy is available.', }, ]; export default function RenderExpandCellGrid() { return (
); } ``` :::warning Because of pagination and virtualization, cells can be unmounted when scrolling or switching pages. The internal state of the component returned by `renderCell` will be lost. If you want to persist cell information, you should save it either in the Data Grid parent or in the row model. Updating the row will rerender the row and so call renderCell with updated params. ::: ## Column types To facilitate the configuration of the columns, some column types are predefined. By default, columns are assumed to hold strings, so the default column string type will be applied. As a result, column sorting will use the string comparator, and the column content will be aligned to the left side of the cell. Some column types require that their value have a specific type. The following are the native column types with their required value types: | Column type | Value type | | :------------------- | :------------------------- | | `'string'` (default) | `string` | | `'longText'` | `string` | | `'number'` | `number` | | `'date'` | `Date() object` | | `'dateTime'` | `Date() object` | | `'boolean'` | `boolean` | | `'singleSelect'` | A value in `.valueOptions` | | `'actions'` | Not applicable | ```tsx import * as React from 'react'; import { DataGrid, GridActionsCellItem, GridRowId, GridColDef, GridActionsCell, GridRenderCellParams, } from '@mui/x-data-grid'; import DeleteIcon from '@mui/icons-material/Delete'; import SecurityIcon from '@mui/icons-material/Security'; import FileCopyIcon from '@mui/icons-material/FileCopy'; import { randomCreatedDate, randomUpdatedDate } from '@mui/x-data-grid-generator'; const initialRows = [ { id: 1, name: 'Damien', age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), isAdmin: true, country: 'Spain', discount: '', bio: 'Damien is a software engineer with 5 years of experience in web development. He specializes in React and Node.js.', }, { id: 2, name: 'Nicolas', age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), isAdmin: false, country: 'France', discount: '', bio: 'Nicolas is a product manager who loves building user-centric products. He has led multiple successful product launches.', }, { id: 3, name: 'Kate', age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), isAdmin: false, country: 'Brazil', discount: 'junior', bio: 'Kate is a junior developer passionate about learning new technologies. She is currently focused on frontend development.', }, ]; type Row = (typeof initialRows)[number]; interface ActionHandlers { deleteUser: (id: GridRowId) => void; toggleAdmin: (id: GridRowId) => void; duplicateUser: (id: GridRowId) => void; } const ActionHandlersContext = React.createContext({ deleteUser: () => {}, toggleAdmin: () => {}, duplicateUser: () => {}, }); function ActionsCell(props: GridRenderCellParams) { const { deleteUser, toggleAdmin, duplicateUser } = React.useContext(ActionHandlersContext); return ( } label="Delete" onClick={() => deleteUser(props.id)} /> } label="Toggle Admin" onClick={() => toggleAdmin(props.id)} showInMenu /> } label="Duplicate User" onClick={() => duplicateUser(props.id)} showInMenu /> ); } const columns: GridColDef[] = [ { field: 'name', type: 'string' }, { field: 'bio', type: 'longText', width: 200, }, { field: 'age', type: 'number' }, { field: 'dateCreated', type: 'date', width: 130 }, { field: 'lastLogin', type: 'dateTime', width: 180 }, { field: 'isAdmin', type: 'boolean', width: 120 }, { field: 'country', type: 'singleSelect', width: 120, valueOptions: [ 'Bulgaria', 'Netherlands', 'France', 'United Kingdom', 'Spain', 'Brazil', ], }, { field: 'discount', type: 'singleSelect', width: 120, editable: true, valueOptions: ({ row }) => { if (row === undefined) { return ['EU-resident', 'junior']; } const options: string[] = []; if (!['United Kingdom', 'Brazil'].includes(row.country)) { options.push('EU-resident'); } if (row.age < 27) { options.push('junior'); } return options; }, }, { field: 'actions', type: 'actions', width: 80, renderCell: (params) => , }, ]; export default function ColumnTypesGrid() { const [rows, setRows] = React.useState(initialRows); const deleteUser = React.useCallback((id: GridRowId) => { setTimeout(() => { setRows((prevRows) => prevRows.filter((row) => row.id !== id)); }); }, []); const toggleAdmin = React.useCallback((id: GridRowId) => { setRows((prevRows) => prevRows.map((row) => row.id === id ? { ...row, isAdmin: !row.isAdmin } : row, ), ); }, []); const duplicateUser = React.useCallback((id: GridRowId) => { setRows((prevRows) => { const rowToDuplicate = prevRows.find((row) => row.id === id)!; return [...prevRows, { ...rowToDuplicate, id: Date.now() }]; }); }, []); const actionHandlers = React.useMemo( () => ({ deleteUser, toggleAdmin, duplicateUser, }), [deleteUser, toggleAdmin, duplicateUser], ); return (
); } ``` ### Long text keyboard interactions The `'longText'` column type supports keyboard interactions to expand, collapse, and edit content when the cell is focused via click or keyboard navigation. View mode (expand button focused): - Space – Toggle popup - Escape – Close popup Edit mode (textarea focused): - Shift+Enter – Insert newline - Enter – Commit changes - Escape – Cancel editing ### Converting types Default methods, such as filtering and sorting, assume that the type of the values will match the type of the column specified in `type`. For example, values of column with `type: 'dateTime'` are expecting to be stored as a `Date()` objects. If for any reason, your data type is not the correct one, you can use `valueGetter` to parse the value to the correct type. ```tsx { field: 'lastLogin', type: 'dateTime', valueGetter: (value) => value && new Date(value), } ``` ### Special properties To use most of the column types, you only need to define the `type` property in your column definition. However, some types require additional properties to be set to make them work correctly: #### Single select If the column type is `'singleSelect'`, you also need to set the `valueOptions` property in the respective column definition. These values are options used for filtering and editing. ```tsx { field: 'country', type: 'singleSelect', valueOptions: ['United Kingdom', 'Spain', 'Brazil'] } ``` :::warning When using objects values for `valueOptions` you need to provide the `value` and `label` attributes for each option. However, you can customize which attribute is used as value and label by using `getOptionValue` and `getOptionLabel`, respectively. ```tsx // Without getOptionValue and getOptionLabel { valueOptions: [ { value: 'BR', label: 'Brazil' }, { value: 'FR', label: 'France' } ] } // With getOptionValue and getOptionLabel { getOptionValue: (value: any) => value.code, getOptionLabel: (value: any) => value.name, valueOptions: [ { code: 'BR', name: 'Brazil' }, { code: 'FR', name: 'France' } ] } ``` ::: #### Actions If the column type is `'actions'`, you need to provide a `renderCell` function that renders a `GridActionsCell` component with `GridActionsCellItem` elements as children. You can add the `showInMenu` prop on the `GridActionsCellItem` elements to signal the Data Grid to group these actions inside a row menu. ```tsx { field: 'actions', type: 'actions', renderCell: (params) => ( ) } ``` :::warning This is the recommended way to define actions in the column definition starting from v8.19.0. The `getActions` method that returned an array of actions is deprecated, and will be removed in a future version. ::: By default, actions shown in the menu will close the menu on click. But in some cases, you might want to keep the menu open after clicking an action. You can achieve this by setting the `closeMenuOnClick` prop to `false`. In the following example, the "Delete" action opens a confirmation dialog and therefore needs to keep the menu mounted: ```tsx import * as React from 'react'; import { DataGrid, GridActionsCellItem, GridRowId, GridColDef, GridActionsCell, GridRenderCellParams, } from '@mui/x-data-grid'; import DeleteIcon from '@mui/icons-material/Delete'; import { randomUserName } from '@mui/x-data-grid-generator'; import Dialog from '@mui/material/Dialog'; import DialogTitle from '@mui/material/DialogTitle'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; const initialRows = [ { id: 1, name: randomUserName() }, { id: 2, name: randomUserName() }, { id: 3, name: randomUserName() }, ]; type Row = (typeof initialRows)[number]; const ActionHandlersContext = React.createContext< ((id: GridRowId) => void) | undefined >(undefined); function ActionsCell(props: GridRenderCellParams) { const setActionRowId = React.useContext(ActionHandlersContext); if (!setActionRowId) { throw new Error('ActionHandlersContext is empty'); } return ( } onClick={() => setActionRowId(props.id)} closeMenuOnClick={false} /> ); } const columns: GridColDef[] = [ { field: 'name', type: 'string' }, { field: 'actions', type: 'actions', width: 80, renderCell: (params) => , }, ]; export default function ActionsWithModalGrid() { const [rows, setRows] = React.useState(initialRows); const [actionRowId, setActionRowId] = React.useState(null); const deleteActiveRow = React.useCallback( (rowId: GridRowId) => setRows((prevRows) => prevRows.filter((row) => row.id !== rowId)), [], ); const handleCloseDialog = React.useCallback(() => { setActionRowId(null); }, []); const handleConfirmDelete = React.useCallback(() => { deleteActiveRow(actionRowId!); handleCloseDialog(); }, [actionRowId, deleteActiveRow, handleCloseDialog]); return (
Delete this user? This action cannot be undone.
); } ``` :::success In the example above, the React Context API is used to pass the action handlers to the `ActionsCell` component. This is a recommended pattern to keep the column definitions stable. ::: ### Custom column types Please refer to the [custom columns](/x/react-data-grid/custom-columns/) page for documentation and integration examples. ## Autogenerated rows Some features like [row grouping](/x/react-data-grid/row-grouping/) or [aggregation](/x/react-data-grid/aggregation/) create autogenerated rows. These rows also call functions like `valueGetter`, `valueFormatter` and `renderCell`, and that can cause issues if you're not expecting it because the `row` parameter will be an empty object and the `value` parameter will be `undefined`. If we take for example the movie dataset, you can detect autogenerated rows using `isAutogeneratedRow()`: ```tsx { field: 'title', valueGetter: (value, row) => { if (isAutogeneratedRow(row)) { return '[this is an autogenerated row]'; } return `title: ${value}`; }, } ``` ```tsx import { DataGridPremium, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, GridColDef, isAutogeneratedRow, useGridApiRef, useKeepGroupedColumnsHidden, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const columns: GridColDef[] = [ { field: GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, width: 200 }, { field: 'company', width: 200 }, { field: 'title', minWidth: 250, cellClassName: 'highlighted', valueGetter: (value, row) => { if (isAutogeneratedRow(row)) { return '[this is an autogenerated row]'; } return `title: ${value}`; }, }, { field: 'year' }, ]; export default function AutogeneratedRows() { const { rows } = useMovieData(); const apiRef = useGridApiRef(); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { rowGrouping: { model: ['company'], }, }, }); return (
); } ``` ## Selectors ### Visible columns Those selectors do not take into account hidden columns. {{"component": "modules/components/SelectorsDocs.js", "category": "Visible Columns"}} ### Defined columns Those selectors consider all the defined columns, including hidden ones. {{"component": "modules/components/SelectorsDocs.js", "category": "Columns"}} More information about the selectors and how to use them on the [dedicated page](/x/react-data-grid/state/#access-the-state). ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-dimensions.md # Data Grid - Column dimensions Customize the dimensions and resizing behavior of your columns. ## Column width By default, the columns have a width of 100px. This is an arbitrary, easy-to-remember value. To change the width of a column, use the `width` property available in `GridColDef`. ```tsx import { DataGrid } from '@mui/x-data-grid'; const rows = [ { id: 1, username: '@MUI', age: 38, }, ]; export default function ColumnWidthGrid() { return (
); } ``` ### Minimum width By default, the columns have a minimum width of 50px. This is an arbitrary, easy-to-remember value. To change the minimum width of a column, use the `minWidth` property available in `GridColDef`. ```tsx import { DataGrid } from '@mui/x-data-grid'; const rows = [ { id: 1, username: '@MUI', age: 38, }, ]; export default function ColumnMinWidthGrid() { return (
); } ``` ### Fluid width Column fluidity or responsiveness can be achieved by setting the `flex` property in `GridColDef`. The `flex` property accepts a value between 0 and ∞. It works by dividing the remaining space in the Data Grid among all flex columns in proportion to their `flex` value. For example, consider a grid with a total width of 500px that has three columns: the first with `width: 200`; the second with `flex: 1`; and the third with `flex: 0.5`. The first column will be 200px wide, leaving 300px remaining. The column with `flex: 1` is twice the size of `flex: 0.5`, which means that final sizes will be: 200px, 200px, 100px. To set a minimum and maximum width for a `flex` column set the `minWidth` and the `maxWidth` property in `GridColDef`. :::warning Before using fluid width, note that: - `flex` doesn't work together with `width`. If you set both `flex` and `width` in `GridColDef`, `flex` will override `width`. - `flex` doesn't work if the combined width of the columns that have `width` is more than the width of the Data Grid itself. If that is the case a scroll bar will be visible, and the columns that have `flex` will default back to their base value of 100px. ::: ```tsx import { DataGrid } from '@mui/x-data-grid'; const rows = [ { id: 1, username: '@MUI', age: 20, }, ]; export default function ColumnFluidWidthGrid() { return (
); } ``` ## Resizing By default, users can resize all columns in the Data Grid by dragging the right portion of the column separator. To prevent the resizing of a column, set `resizable: false` in the `GridColDef`. Alternatively, to disable all columns resize, set the prop `disableColumnResize={true}`. To restrict resizing a column under a certain width set the `minWidth` property in `GridColDef`. To restrict resizing a column above a certain width set the `maxWidth` property in `GridColDef`. ```tsx import { DataGrid } from '@mui/x-data-grid'; const rows = [ { id: 1, username: '@MUI', age: 20, }, ]; export default function ColumnSizingGrid() { return (
); } ``` To capture changes in the width of a column there are two callbacks that are called: - `onColumnResize`: Called while a column is being resized. - `onColumnWidthChange`: Called after the width of a column is changed, but not during resizing. ## Autosizing Autosizing is the feature to adjust the width of a column to fit its content including the header and the outliers (cells with long content). It respects the `minWidth` and `maxWidth` options defined in the `columns` definition prop. To configure autosizing behavior, use the `autosizeOptions` with the following options: - `columns`: An array of column field names to autosize. If not provided, all columns will be autosized. - `includeHeaders`: A boolean to indicate whether to include the header content when autosizing. Default is **true**. - `includeOutliers`: A boolean to indicate whether to include outlier cells when autosizing. Default is **false**. - `outliersFactor`: A number representing the factor to determine outliers. Default is **1.5**. - `expand`: A boolean, if the total width is less than the available width, expand columns to fill it. Default is **false**. - `disableColumnVirtualization`: A boolean to include virtualized columns (not rendered in the DOM) when autosizing. Default is **true**. - `includeHeaderFilters` [](/x/introduction/licensing/#pro-plan 'Pro plan'): A boolean to indicate whether to include the header filter content when autosizing. Default is **false**. ```tsx ``` ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; import Rating from '@mui/material/Rating'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import { DataGrid, useGridApiRef, DEFAULT_GRID_AUTOSIZE_OPTIONS, } from '@mui/x-data-grid'; import { randomRating, randomTraderName } from '@mui/x-data-grid-generator'; function renderRating(params: any) { return ; } function useData(length: number) { return React.useMemo(() => { const names = [ 'Nike', 'Adidas', 'Puma', 'Reebok', 'Fila', 'Lululemon Athletica Clothing', 'Varley', ]; const rows = Array.from({ length }).map((_, id) => ({ id, brand: names[id % names.length], rep: randomTraderName(), rating: randomRating(), })); const columns = [ { field: 'id', headerName: 'Brand ID' }, { field: 'brand', headerName: 'Brand name' }, { field: 'rep', headerName: 'Representative' }, { field: 'rating', headerName: 'Rating', renderCell: renderRating, display: 'flex' as const, }, ]; return { rows, columns }; }, [length]); } export default function ColumnAutosizing() { const apiRef = useGridApiRef(); const data = useData(100); const [includeHeaders, setIncludeHeaders] = React.useState( DEFAULT_GRID_AUTOSIZE_OPTIONS.includeHeaders, ); const [includeOutliers, setExcludeOutliers] = React.useState( DEFAULT_GRID_AUTOSIZE_OPTIONS.includeOutliers, ); const [outliersFactor, setOutliersFactor] = React.useState( String(DEFAULT_GRID_AUTOSIZE_OPTIONS.outliersFactor), ); const [expand, setExpand] = React.useState(DEFAULT_GRID_AUTOSIZE_OPTIONS.expand); const autosizeOptions = { includeHeaders, includeOutliers, outliersFactor: Number.isNaN(parseFloat(outliersFactor)) ? 1 : parseFloat(outliersFactor), expand, }; return (
setIncludeHeaders(ev.target.checked)} /> } label="Include headers" /> setExcludeOutliers(event.target.checked)} /> } label="Include outliers" /> setOutliersFactor(ev.target.value)} sx={{ width: '12ch' }} /> setExpand(ev.target.checked)} /> } label="Expand" />
); } ``` :::info The `autosizeOptions` only applies to the [column header separator](#column-header-separator) and the `autosizeOnMount` prop. It **does not** apply to the `autosizeColumns()` method when you call it programmatically, you have to pass the options directly. ::: ### Column header separator Autosizing can be triggered by double-clicking the column header separator. To disable this behavior, use the `disableAutosize` prop. ```jsx ``` Note that for the separator double-click method, the `autosizeOptions.columns` will be replaced by the respective column user double-clicked on. ### Autosizing on mount To automatically autosize columns when the Data Grid is mounted, use the `autosizeOnMount` prop. ```jsx ``` ### Autosizing programmatically Use API method `apiRef.current.autosizeColumns(autosizeOptions)` to adjust the column size programmatically. Common usage could be to bind it with specified events, for example when receiving row data from the server. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Rating from '@mui/material/Rating'; import Stack from '@mui/material/Stack'; import { DataGridPro, useGridApiRef, GridColDef } from '@mui/x-data-grid-pro'; import { randomInt, randomRating, randomTraderName, } from '@mui/x-data-grid-generator'; import * as ReactDOM from 'react-dom'; import { GridData } from 'docsx/data/data-grid/virtualization/ColumnVirtualizationGrid'; const columns: GridColDef[] = [ { field: 'id', headerName: 'Brand ID' }, { field: 'brand', headerName: 'Brand name' }, { field: 'rep', headerName: 'Representative' }, { field: 'rating', headerName: 'Rating', renderCell: renderRating, display: 'flex', }, ]; function renderRating(params: any) { return ; } function getFakeData(length: number): Promise<{ rows: GridData['rows'] }> { return new Promise((resolve) => { setTimeout(() => { const names = [ 'Nike', 'Adidas', 'Puma', 'Reebok', 'Fila', 'Lululemon Athletica Clothing', 'Varley', ]; const rows = Array.from({ length }).map((_, id) => ({ id, brand: names[randomInt(0, names.length - 1)], rep: randomTraderName(), rating: randomRating(), })); resolve({ rows }); }, 1000); }); } export default function ColumnAutosizingAsync() { const apiRef = useGridApiRef(); const [isLoading, setIsLoading] = React.useState(false); const [rows] = React.useState([]); const fetchData = React.useCallback(() => { setIsLoading(true); getFakeData(100) .then((data) => { ReactDOM.flushSync(() => { setIsLoading(false); apiRef.current?.updateRows(data.rows); }); }) // `sleep`/`setTimeout` is required because `.updateRows` is an // async function throttled to avoid choking on frequent changes. .then(() => sleep(0)) .then(() => apiRef.current?.autosizeColumns({ includeHeaders: true, includeOutliers: true, }), ); }, [apiRef]); React.useEffect(() => { fetchData(); }, [fetchData]); return (
); } function sleep(ms: number) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } ``` :::warning This example uses `ReactDOM.flushSync`. If used incorrectly it can hurt the performance of your application. Please refer to the official [React docs](https://react.dev/reference/react-dom/flushSync) for further information. ::: ### Autosizing virtualized columns Use `autoSizeColumns({ disableColumnVirtualization: true})` to include columns that are not visible in the DOM due to column virtualization. :::warning The time to complete the autosizing operation exponentially depends on the number of virtualized columns. ::: ```tsx import * as React from 'react'; import { DataGrid, GridColDef, GridRowId, useGridApiRef } from '@mui/x-data-grid'; import Button from '@mui/material/Button'; export interface DataRowModel { id: GridRowId; [price: string]: number | string; } export interface GridData { columns: GridColDef[]; rows: DataRowModel[]; } function useData(rowLength: number, columnLength: number) { const [data, setData] = React.useState({ columns: [], rows: [] }); React.useEffect(() => { const rows: DataRowModel[] = []; for (let i = 0; i < rowLength; i += 1) { const row: DataRowModel = { id: i, }; for (let j = 1; j <= columnLength; j += 1) { row[`price${j}M`] = `${i.toString()}, ${j} `; } rows.push(row); } const columns: GridColDef[] = []; for (let j = 1; j <= columnLength; j += 1) { columns.push({ field: `price${j}M`, headerName: `${j}M` }); } setData({ rows, columns, }); }, [rowLength, columnLength]); return data; } export default function ColumnAutosizingVirtualized() { const apiRef = useGridApiRef(); const data = useData(100, 1000); return (
); } ``` ### Autosizing with dynamic row height Column autosizing is compatible with the [Dynamic row height](/x/react-data-grid/row-height/#dynamic-row-height) feature. ```tsx import Button from '@mui/material/Button'; import { DataGrid, GridColDef, gridClasses, useGridApiRef, GridAutosizeOptions, } from '@mui/x-data-grid'; import { randomInt, randomArrayItem } from '@mui/x-data-grid-generator'; const lines = [ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'Aliquam dapibus, lorem vel mattis aliquet, purus lorem tincidunt mauris, in blandit quam risus sed ipsum.', 'Maecenas non felis venenatis, porta velit quis, consectetur elit.', 'Vestibulum commodo et odio a laoreet.', 'Nullam cursus tincidunt auctor.', 'Sed feugiat venenatis nulla, sit amet dictum nulla convallis sit amet.', 'Nulla venenatis justo non felis vulputate, eu mollis metus ornare.', 'Nam ullamcorper ligula id consectetur auctor.', 'Phasellus et ultrices dui.', 'Fusce facilisis egestas massa, et eleifend magna imperdiet et.', 'Pellentesque ac metus velit.', 'Vestibulum in massa nibh.', 'Vestibulum pulvinar aliquam turpis, ac faucibus risus varius a.', ]; const columns: GridColDef[] = [{ field: 'id' }, { field: 'bio', width: 400 }]; const rows: object[] = []; for (let i = 0; i < 200; i += 1) { const bio = []; for (let j = 0; j < randomInt(1, 5); j += 1) { bio.push(randomArrayItem(lines)); } rows.push({ id: i, bio: bio.join(' ') }); } const autosizeOptions: GridAutosizeOptions = { includeOutliers: true, }; export default function ColumnAutosizingDynamicRowHeight() { const apiRef = useGridApiRef(); return (
'auto'} autosizeOptions={autosizeOptions} sx={{ [`& .${gridClasses.cell}`]: { py: 0.5, }, }} />
); } ``` :::warning When autosizing columns with long content, consider setting the `maxWidth` for the column to avoid it becoming too wide. ::: ### Autosizing header filters [](/x/introduction/licensing/#pro-plan 'Pro plan') To include the header filter content when autosizing columns, pass the `includeHeaderFilters` to the `autosizeOptions`. ```tsx ``` ```tsx import * as React from 'react'; import Rating from '@mui/material/Rating'; import { DataGridPremium } from '@mui/x-data-grid-premium'; import { randomRating, randomTraderName } from '@mui/x-data-grid-generator'; const columns = [ { field: 'id', headerName: 'Brand ID' }, { field: 'brand', headerName: 'Brand name' }, { field: 'rep', headerName: 'Representative' }, { field: 'rating', headerName: 'Rating', renderCell: renderRating, display: 'flex' as const, }, ]; function renderRating(params: any) { return ; } function useRows(length: number) { return React.useMemo(() => { const names = [ 'Nike', 'Adidas', 'Puma', 'Reebok', 'Fila', 'Lululemon Athletica Clothing', 'Varley', ]; const rows = Array.from({ length }).map((_, id) => ({ id, brand: names[id % names.length], rep: randomTraderName(), rating: randomRating(), })); return rows; }, [length]); } export default function ColumnAutosizingHeaderFilters() { const rows = useRows(100); return (
); } ``` or when calling the `autosizeColumns()` method programmatically: ```tsx apiRef.current.autosizeColumns({ includeHeaderFilters: true, }); ``` ### Autosizing with grouped rows [](/x/introduction/licensing/#premium-plan 'Premium plan') When using [row grouping](/x/react-data-grid/row-grouping/) you can utilize the `autosizeColumns` method to adjust the column width of the expanded rows dynamically. The demo below shows how you can subscribe to the `rowExpansionChange` event. The provided handler function then calls the `autosizeColumns` method from the gridApi. ```tsx import * as React from 'react'; import { DataGridPremium, GridGroupingColDefOverride, GridValidRowModel, useGridApiRef, useKeepGroupedColumnsHidden, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const groupingColDef: GridGroupingColDefOverride = { width: 250, }; export default function ColumnAutosizingGroupedRows() { const data = useMovieData(); const apiRef = useGridApiRef(); const columns = React.useMemo(() => { return data.columns.map((col) => ({ ...col, width: 50 })); }, [data.columns]); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { rowGrouping: { model: ['company'] } }, }); React.useEffect(() => { return apiRef.current?.subscribeEvent('rowExpansionChange', (params) => { if (params.childrenExpanded) { apiRef.current?.autosizeColumns({ includeOutliers: true }); } }); }, [apiRef]); return (
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-groups.md # Data Grid - Column groups Group your columns. Grouping columns lets you have a multi-level hierarchy of columns in your header. ## Define column groups You can define column groups with the `columnGroupingModel` prop. This prop receives an array of column groups. A column group is defined by at least two properties: - `groupId`: a string used to identify the group - `children`: an array containing the children of the group The `children` attribute can contain two types of objects: - leaves with type `{ field: string }`, which add the column with the corresponding `field` to this group - other column groups, making it possible to create nested groups :::warning A column can only be associated with one group. ::: ```jsx ``` ```tsx import { DataGrid, GridColDef, GridColumnGroupingModel } from '@mui/x-data-grid'; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 90 }, { field: 'firstName', headerName: 'First name', width: 150, }, { field: 'lastName', headerName: 'Last name', width: 150, }, { field: 'age', headerName: 'Age', type: 'number', width: 110, }, ]; const rows = [ { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 }, { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, ]; const columnGroupingModel: GridColumnGroupingModel = [ { groupId: 'Internal', description: '', children: [{ field: 'id' }], }, { groupId: 'Basic info', children: [ { groupId: 'Full name', children: [{ field: 'lastName' }, { field: 'firstName' }], }, { field: 'age' }, ], }, ]; export default function BasicGroupingDemo() { return (
); } ``` ## Customize column group In addition to the required `groupId` and `children`, you can use the following optional properties to customize a column group: - `headerName`: the string displayed as the column's name (instead of `groupId`). - `description`: a text for the tooltip. - `headerClassName`: a CSS class for styling customization. - `renderHeaderGroup`: a function returning custom React component. ```tsx import * as React from 'react'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import { DataGrid, GridColDef, GridColumnGroupHeaderParams, GridColumnGroupingModel, } from '@mui/x-data-grid'; import BuildIcon from '@mui/icons-material/Build'; import PersonIcon from '@mui/icons-material/Person'; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 150 }, { field: 'firstName', headerName: 'First name', width: 150, }, { field: 'lastName', headerName: 'Last name', width: 150, }, { field: 'age', headerName: 'Age', type: 'number', width: 110, }, ]; const rows = [ { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 }, { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, ]; interface HeaderWithIconProps extends GridColumnGroupHeaderParams { icon: React.ReactNode; } const HeaderWithIconRoot = styled('div')(({ theme }) => ({ overflow: 'hidden', display: 'flex', alignItems: 'center', '& span': { overflow: 'hidden', textOverflow: 'ellipsis', marginRight: theme.spacing(0.5), }, })); function HeaderWithIcon(props: HeaderWithIconProps) { const { icon, ...params } = props; return ( {params.headerName ?? params.groupId} {icon} ); } const columnGroupingModel: GridColumnGroupingModel = [ { groupId: 'internal_data', headerName: 'Internal', description: '', renderHeaderGroup: (params) => ( } /> ), children: [{ field: 'id' }], }, { groupId: 'character', description: 'Information about the character', headerName: 'Basic info', renderHeaderGroup: (params) => ( } /> ), children: [ { groupId: 'naming', headerName: 'Names', headerClassName: 'my-super-theme--naming-group', children: [{ field: 'lastName' }, { field: 'firstName' }], }, { field: 'age' }, ], }, ]; export default function CustomizationDemo() { return ( ); } ``` ## Group header height By default, column group headers are the same height as [column headers](/x/react-data-grid/column-header/#header-height). This will be the default 56 pixels or a custom value set with the `columnHeaderHeight` prop. The `columnGroupHeaderHeight` prop can be used to size column group headers independently of column headers. ```tsx import { DataGrid, GridColDef, GridColumnGroupingModel } from '@mui/x-data-grid'; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 90 }, { field: 'firstName', headerName: 'First name', width: 150, }, { field: 'lastName', headerName: 'Last name', width: 150, }, { field: 'age', headerName: 'Age', type: 'number', width: 110, }, ]; const rows = [ { id: 1, lastName: 'Snow', firstName: 'Jon', age: 14 }, { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, { id: 4, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 }, { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, ]; const columnGroupingModel: GridColumnGroupingModel = [ { groupId: 'Internal', description: '', children: [{ field: 'id' }], }, { groupId: 'Basic info', children: [ { groupId: 'Full name', children: [{ field: 'lastName' }, { field: 'firstName' }], }, { field: 'age' }, ], }, ]; export default function GroupHeaderHeight() { return (
); } ``` ## Column reordering [](/x/introduction/licensing/#pro-plan 'Pro plan') By default, the columns that are part of a group cannot be dragged to outside their group. You can customize this behavior on specific groups by setting `freeReordering: true` in a column group object. In the example below, the `Full name` column group can be divided, but not other column groups. ```tsx import { DataGridPro, GridColDef, GridColumnGroupingModel, } from '@mui/x-data-grid-pro'; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 100 }, { field: 'isAdmin', type: 'boolean', headerName: 'is admin', width: 100 }, { field: 'firstName', headerName: 'First name', width: 150, }, { field: 'lastName', headerName: 'Last name', width: 150, }, { field: 'age', headerName: 'Age', type: 'number', width: 110, }, ]; const rows = [ { id: 1, isAdmin: false, lastName: 'Snow', firstName: 'Jon', age: 14 }, { id: 2, isAdmin: true, lastName: 'Lannister', firstName: 'Cersei', age: 31 }, { id: 3, isAdmin: false, lastName: 'Lannister', firstName: 'Jaime', age: 31 }, { id: 4, isAdmin: false, lastName: 'Stark', firstName: 'Arya', age: 11 }, { id: 5, isAdmin: true, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, isAdmin: true, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, isAdmin: false, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, { id: 8, isAdmin: false, lastName: 'Frances', firstName: 'Rossini', age: 36 }, { id: 9, isAdmin: false, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, ]; const columnGroupingModel: GridColumnGroupingModel = [ { groupId: 'internal_data', headerName: 'Internal (not freeReordering)', description: '', children: [{ field: 'id' }, { field: 'isAdmin' }], }, { groupId: 'naming', headerName: 'Full name (freeReordering)', freeReordering: true, children: [{ field: 'lastName' }, { field: 'firstName' }], }, ]; export default function BreakingGroupDemo() { return (
); } ``` ## Collapsible column groups The demo below uses [`renderHeaderGroup`](/x/react-data-grid/column-groups/#customize-column-group) to add a button to collapse/expand the column group. ```tsx import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import IconButton from '@mui/material/IconButton'; import { DataGrid, GridColDef, GridColumnGroupHeaderParams, GridColumnGroupingModel, gridColumnVisibilityModelSelector, useGridApiContext, } from '@mui/x-data-grid'; import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight'; import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'; const COLLAPSIBLE_COLUMN_GROUPS: Record> = { character: ['lastName', 'age'], naming: ['lastName'], }; const ColumnGroupRoot = styled('div')({ overflow: 'hidden', display: 'flex', alignItems: 'center', }); const ColumnGroupTitle = styled('span')({ overflow: 'hidden', textOverflow: 'ellipsis', }); function CollapsibleHeaderGroup({ groupId, headerName, }: GridColumnGroupHeaderParams) { const apiRef = useGridApiContext(); const columnVisibilityModel = gridColumnVisibilityModelSelector(apiRef); if (!groupId) { return null; } const isCollapsible = Boolean(COLLAPSIBLE_COLUMN_GROUPS[groupId]); const isGroupCollapsed = COLLAPSIBLE_COLUMN_GROUPS[groupId].every( (field) => columnVisibilityModel[field] === false, ); return ( {headerName ?? groupId}{' '} {isCollapsible && ( { const newModel = { ...columnVisibilityModel }; COLLAPSIBLE_COLUMN_GROUPS[groupId].forEach((field) => { newModel[field] = !!isGroupCollapsed; }); apiRef.current.setColumnVisibilityModel(newModel); }} > {isGroupCollapsed ? ( ) : ( )} )} ); } const columnGroupingModel: GridColumnGroupingModel = [ { groupId: 'Internal', description: '', children: [{ field: 'id' }], }, { groupId: 'character', description: 'Information about the character', headerName: 'Basic info', renderHeaderGroup: (params) => { return ; }, children: [ { groupId: 'naming', headerName: 'Names', renderHeaderGroup: (params) => , children: [{ field: 'lastName' }, { field: 'firstName' }], }, { field: 'age' }, ], }, ]; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 150 }, { field: 'firstName', headerName: 'First name', width: 150 }, { field: 'lastName', headerName: 'Last name', width: 150 }, { field: 'age', headerName: 'Age', type: 'number', width: 110 }, ]; const rows = [ { id: 1, lastName: 'Snow', firstName: 'Jon', age: 35 }, { id: 2, lastName: 'Lannister', firstName: 'Cersei', age: 42 }, { id: 3, lastName: 'Lannister', firstName: 'Jaime', age: 45 }, { id: 4, lastName: 'Stark', firstName: 'Arya', age: 16 }, { id: 5, lastName: 'Targaryen', firstName: 'Daenerys', age: null }, { id: 6, lastName: 'Melisandre', firstName: null, age: 150 }, { id: 7, lastName: 'Clifford', firstName: 'Ferrara', age: 44 }, { id: 8, lastName: 'Frances', firstName: 'Rossini', age: 36 }, { id: 9, lastName: 'Roxie', firstName: 'Harvey', age: 65 }, ]; export default function CollapsibleColumnGroups() { return ( ); } ``` ## Manage group visibility 🚧 :::warning This feature isn't available yet, but it is planned—you can 👍 upvote [this GitHub issue](https://github.com/mui/mui-x/issues/6651) to help us prioritize it. Please don't hesitate to leave a comment there to describe your needs, especially if you have a use case we should address or you're facing specific pain points with your current solution. ::: With this feature, users would be able to expand and collapse grouped columns to toggle their visibility. ## Column group ordering [](/x/introduction/licensing/#pro-plan 'Pro plan')🚧 :::warning This feature isn't available yet, but it is planned—you can 👍 upvote [this GitHub issue](https://github.com/mui/mui-x/issues/9448) to help us prioritize it. Please don't hesitate to leave a comment there to describe your needs, especially if you have a use case we should address or you're facing specific pain points with your current solution. ::: With this feature, users would be able to drag and drop grouped headers to move all grouped children at once (which is [already possible for normal columns](/x/react-data-grid/column-ordering/)). ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-header.md # Data Grid - Column header Customize your columns header. You can configure the headers with: - `headerName`: The title of the column rendered in the column header cell. - `description`: The description of the column rendered as tooltip if the column header name is not fully displayed. ```tsx import { DataGrid } from '@mui/x-data-grid'; const rows = [ { id: 1, username: '@MUI', age: 20, }, ]; export default function HeaderColumnsGrid() { return (
); } ``` ## Custom header renderer You can customize the look of each header with the `renderHeader` method. It takes precedence over the `headerName` property. ```tsx const columns: GridColDef[] = [ { field: 'date', width: 150, type: 'date', renderHeader: (params: GridColumnHeaderParams) => ( {'Birthday '} 🎂 ), }, ]; ``` ```tsx import { DataGrid, GridColDef } from '@mui/x-data-grid'; const columns: GridColDef[] = [ { field: 'date', width: 150, type: 'date', renderHeader: () => ( {'Birthday '} 🎂 ), }, ]; const rows = [ { id: 1, date: new Date(1979, 0, 1), }, { id: 2, date: new Date(1984, 1, 1), }, { id: 3, date: new Date(1992, 2, 1), }, ]; export default function RenderHeaderGrid() { return (
); } ``` ## Header height By default, column headers have a height of 56 pixels. This matches the height from the [Material Design guidelines](https://m2.material.io/components/data-tables). The `columnHeaderHeight` prop can be used to override the default value. ```tsx import { DataGrid, GridColDef } from '@mui/x-data-grid'; const rows = [ { id: 1, username: '@MUI', age: 20, }, ]; const columns: GridColDef[] = [ { field: 'username', headerName: 'Username', description: 'The identification used by the person with access to the online service.', }, { field: 'age', headerName: 'Age' }, ]; export default function HeaderHeight() { return (
); } ``` ## Styling header You can check the [styling header](/x/react-data-grid/style/#styling-column-headers) section for more information. ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-menu.md # Data Grid - Column menu Customize your columns menu. ## Column menu Each column header comes with a column menu with quickly accessible Data Grid features like column visibility, sorting, filtering, and others. It can be accessed by clicking on the 3-dots icon that appears on hover on a header cell or when focusing on a column header and pressing Ctrl+Enter (or ⌘ Command+Enter on macOS). ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function ColumnMenuGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 5, }); return (
); } ``` ## Customize column menu items You can customize the column menu items by passing the `slots` and `slotProps` props to the `` component: - `slots` - use this prop to override default column menu slots or add new slots. - `slotProps` - use this prop to override or pass [`displayOrder`](/x/react-data-grid/column-menu/#reordering-menu-items) for column menu items. You can also use this to pass extra props to custom column menu slots. ### Adding a menu item To add a new menu item, create a new item slot and pass it to the `slots` prop. In the example below, the new slot is called `columnMenuUserItem` but you can choose any name and it'll be added to the menu automatically. You can also set the `displayOrder` (default `100`) or pass new props to the slots using the `slotProps` prop. ```tsx function CustomColumnMenu(props: GridColumnMenuProps) { return ( alert('Custom handler fired'), }, }} /> ); } ``` ```tsx import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import SettingsApplicationsIcon from '@mui/icons-material/SettingsApplications'; import { DataGrid, GridColumnMenu, GridColumnMenuProps, GridColumnMenuItemProps, } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; function CustomUserItem(props: GridColumnMenuItemProps) { const { myCustomHandler, myCustomValue } = props; return ( {myCustomValue} ); } function CustomColumnMenu(props: GridColumnMenuProps) { return ( alert('Custom handler fired'), }, }} /> ); } export default function AddNewColumnMenuGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 5, }); return (
); } ``` ### Overriding default menu items Use the `slots` prop to override default menu items. Check [this table](/x/react-data-grid/column-menu/#default-column-menu-items) to know the overridable slot name for each menu item. ```tsx function CustomColumnMenu(props: GridColumnMenuProps) { return ( ); } ``` ```tsx import * as React from 'react'; import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import IconFilter from '@mui/icons-material/FilterAlt'; import { DataGrid, GridColumnMenu, GridColumnMenuProps, GridColumnMenuItemProps, useGridApiContext, } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; function CustomFilterItem(props: GridColumnMenuItemProps) { const { onClick, colDef } = props; const apiRef = useGridApiContext(); const handleClick = React.useCallback( (event: React.MouseEvent) => { apiRef.current.showFilterPanel(colDef.field); onClick(event); }, [apiRef, colDef.field, onClick], ); return ( Show Filters ); } function CustomColumnMenu(props: GridColumnMenuProps) { return ( ); } export default function OverrideColumnMenuGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 5, }); return (
); } ``` ### Hiding a menu item To hide a menu item, you can set its respective slot in `slots` to `null`. Check [this table](/x/react-data-grid/column-menu/#default-column-menu-items) to know the slot name for each menu item. ```tsx function CustomColumnMenu(props: GridColumnMenuProps) { return ( ); } ``` ```tsx import { DataGrid, GridColumnMenu, GridColumnMenuProps } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; function CustomColumnMenu(props: GridColumnMenuProps) { return ( ); } export default function HideColumnMenuGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 5, }); return (
); } ``` ### Reordering menu items Every item is assigned a `displayOrder` based on which it is shown before or after other items. It works in ascending order; the smaller the number is, the earlier it is displayed on the list. For new items default value for `displayOrder` is **100**. You can override `displayOrder` for the default or new items in `slotProps`. Check [this table](/x/react-data-grid/column-menu/#default-column-menu-items) to see default `displayOrder` for each menu item. ```tsx function CustomColumnMenu(props: GridColumnMenuProps) { return ( ); } ``` ```tsx import { DataGrid, GridColumnMenu, GridColumnMenuProps } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; function CustomColumnMenu(props: GridColumnMenuProps) { return ( ); } export default function ReorderColumnMenuGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 5, }); return (
); } ``` ### Default column menu items As a reference, here are the column menu `slots` along with the default item components and `displayOrder`. ```tsx import { DataGridPremium, GridRenderCellParams, GridColDef, } from '@mui/x-data-grid-premium'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; const getPlanProps = (plan: string) => { switch (plan.toLowerCase()) { case 'premium': return { href: '/x/introduction/licensing/#premium-plan', className: 'plan-premium', title: 'Premium plan', }; case 'pro': return { href: '/x/introduction/licensing/#pro-plan', className: 'plan-pro', title: 'Pro plan', }; default: return null; } }; function PlanIcon(props: { plan?: string }) { if (!props.plan) { return null; } const planProps = getPlanProps(props.plan); if (!planProps) { return null; } return ( ); } function ComponentTag(props: { value?: string; plan?: string }) { if (!props.value) { return null; } const components = props.value.split(','); return ( {components.map((c, key) => (
{c}
))}
); } const columns: GridColDef[] = [ { field: 'slot', headerName: 'Slot', width: 240, renderCell: (params: GridRenderCellParams) => ( ), }, { field: 'defaultComponent', headerName: 'Default Component', width: 300, renderCell: (params: GridRenderCellParams) => ( ), }, { field: 'displayOrder', headerName: 'Display Order', width: 140, type: 'number' }, ]; const rows = [ { id: 1, slot: 'columnMenuSortItem', defaultComponent: 'GridColumnMenuSortItem', displayOrder: 10, plan: 'Community', }, { id: 3, slot: 'columnMenuFilterItem', defaultComponent: 'GridColumnMenuFilterItem', displayOrder: 20, plan: 'Community', }, { id: 7, slot: 'columnMenuColumnsItem', defaultComponent: 'GridColumnMenuColumnsItem', displayOrder: 30, plan: 'Community', }, { id: 9, slot: 'columnMenuPinningItem', defaultComponent: 'GridColumnMenuPinningItem', displayOrder: 15, plan: 'Pro', }, { id: 11, slot: 'columnMenuAggregationItem', defaultComponent: 'GridColumnMenuAggregationItem', displayOrder: 23, plan: 'Premium', }, { id: 13, slot: 'columnMenuGroupingItem', defaultComponent: 'GridColumnMenuGroupingItem', displayOrder: 27, plan: 'Premium', }, ]; export default function ColumnMenuGridReferencesNoSnap() { return (
); } ``` ## Custom menu component You can also customize and replace the column menu by [passing a fully custom component](/x/react-data-grid/components/#component-slots) to the `columnMenu` slot of the Data Grid. If you want to add some of the default menu items to your custom component, you can import and re-use them. ```tsx import * as React from 'react'; import { DataGrid, GridColumnMenuFilterItem, GridColumnMenuSortItem, GridColumnMenuColumnsItem, GridColumnMenuItemProps, GridColumnMenuProps, } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import Divider from '@mui/material/Divider'; function MenuCloseComponent(props: GridColumnMenuItemProps) { return ( ); } function CustomColumnMenu(props: GridColumnMenuProps) { const itemProps = { colDef: props.colDef, onClick: props.hideMenu, }; return ( {/* Only provide filtering on desk */} {itemProps.colDef.field === 'desk' ? ( ) : null} ); } export default function CustomColumnMenuGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 5, }); return (
); } ``` :::info Tip: The `columnMenu` component and its components slots receive the `colDef` prop corresponding to the current column; you can use this to conditionally render some items or change some logic. ::: ## Disable column menu By default, each column header has the column menu enabled. To disable the column menu, set the prop `disableColumnMenu={true}`. ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function DisabledColumnMenuGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 5, }); return (
); } ``` ## Column menu with Pro/Premium features [](/x/introduction/licensing/#pro-plan 'Pro plan')[](/x/introduction/licensing/#premium-plan 'Premium plan') In the following demo, in addition to Data Grid MIT features, you can see commercial features like [grouping](/x/react-data-grid/row-grouping/), and [aggregation](/x/react-data-grid/aggregation/) in action. Try tweaking the values from respective column menu items. ```tsx import { DataGridPremium, GridGroupingColDefOverride, GridValidRowModel, useGridApiRef, useKeepGroupedColumnsHidden, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const groupingColDef: GridGroupingColDefOverride = { leafField: 'title', }; export default function ColumnMenuGridPremium() { const apiRef = useGridApiRef(); const data = useMovieData(); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { aggregation: { model: { gross: 'avg', }, }, columns: { columnVisibilityModel: { cinematicUniverse: false, title: false, }, }, rowGrouping: { model: ['company'], }, }, }); return (
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-ordering.md --- title: Data Grid - Drag-and-drop column reordering --- # Data Grid - Drag-and-drop column reordering [](/x/introduction/licensing/#pro-plan 'Pro plan') The Data Grid Pro lets users drag and drop columns to reorder them. Columns are organized according to the order in which they're provided in the `columns` array. By default, the Data Grid Pro lets users reorder columns by dragging and dropping the header cells—give it a try in the demo below: ```tsx import { DataGridPro } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function ColumnOrderingGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 20, }); return (
); } ``` ## Column reordering events Column reordering emits the following events: - `columnHeaderDragStart`: emitted when the user starts dragging the header cell. - `columnHeaderDragEnter`: emitted when the cursor enters another header cell while dragging. - `columnHeaderDragOver`: emitted when the user drags a header cell over another header cell. - `columnHeaderDragEnd`: emitted when the user stops dragging the header cell. ## Disabling column reordering Drag-and-drop column reordering is enabled by default on the Data Grid Pro, but you can disable it for some or all columns. ### For all columns To disable reordering for all columns, set the `disableColumnReorder` prop to `true`: ```tsx ``` ### For specific columns To disable reordering for a specific column, set the `disableReorder` property to `true` in the column's `GridColDef`, as shown below: ```tsx import { DataGridPro } from '@mui/x-data-grid-pro'; const rows = [ { id: 1, username: '@MUI', age: 20, }, ]; export default function ColumnOrderingDisabledGrid() { return (
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-pinning.md --- title: Data Grid - Column pinning --- # Data Grid - Column pinning [](/x/introduction/licensing/#pro-plan 'Pro plan') Implement pinning to keep columns in the Data Grid visible at all times. Pinned columns (also known as sticky, frozen, and locked) are visible at all times while scrolling the Data Grid horizontally. Users can access this feature through the column menu to pin and unpin columns to either the left or right side. Pinned columns cannot be [reordered](/x/react-data-grid/column-ordering/), except by unpinning and repinning. ## Implementing column pinning The Data Grid Pro provides column pinning to end users by default, and there are several different tools you can use to modify the experience to meet your needs: - The `initialState` prop – for pinning during initialization - The `pinnedColumns` and `onPinnedColumnsChange` props – for more control over pinning - The imperative `apiRef` API – for fully custom solutions ### Column pinning on initialization To set pinned columns when the Data Grid is initialized, pass a value to the `pinnedColumns` property of the `initialState` prop with the following shape: ```ts interface GridPinnedColumnFields { left?: string[]; // Optional field names to pin to the left right?: string[]; // Optional field names to pin to the right } ``` The demo below illustrates how this works: ```tsx import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import { DataGridPro, GridColDef, GridRowsProp, GridActionsCellItem, GridActionsCell, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomTraderName, randomEmail, randomUpdatedDate, } from '@mui/x-data-grid-generator'; export default function BasicColumnPinning() { return (
); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 160, editable: true }, { field: 'email', headerName: 'Email', width: 200, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, { field: 'actions', type: 'actions', width: 100, renderCell: (params) => ( } label="Edit" /> } label="Delete" /> ), }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), email: randomEmail(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), email: randomEmail(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), email: randomEmail(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), email: randomEmail(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), email: randomEmail(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 6, name: randomTraderName(), email: randomEmail(), age: 27, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 7, name: randomTraderName(), email: randomEmail(), age: 18, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 8, name: randomTraderName(), email: randomEmail(), age: 31, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 9, name: randomTraderName(), email: randomEmail(), age: 24, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 10, name: randomTraderName(), email: randomEmail(), age: 35, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` :::warning You may encounter issues if the sum of the widths of the pinned columns is larger than the width of the Grid. Make sure that the Data Grid can properly accommodate these columns at a minimum. ::: ### Controlled column pinning The `pinnedColumns` prop gives you more granular control over how the user can interact with the pinning feature. To implement this prop, pass an object to it with the same shape as that outlined in [the `initialState` section above](#column-pinning-on-initialization). Use it together with `onPinnedColumnsChange` to track when columns are pinned and unpinned, as shown in the demo below: ```tsx import * as React from 'react'; import { DataGridPro, GridColDef, GridPinnedColumnFields, GridRowsProp, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomTraderName, randomEmail, randomUpdatedDate, } from '@mui/x-data-grid-generator'; import Alert from '@mui/material/Alert'; import Box from '@mui/material/Box'; export default function ControlPinnedColumns() { const [pinnedColumns, setPinnedColumns] = React.useState({ left: ['name'], }); const handlePinnedColumnsChange = React.useCallback( (updatedPinnedColumns: GridPinnedColumnFields) => { setPinnedColumns(updatedPinnedColumns); }, [], ); return ( pinnedColumns: {JSON.stringify(pinnedColumns)} ); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 180, editable: true }, { field: 'email', headerName: 'Email', width: 200, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), email: randomEmail(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), email: randomEmail(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), email: randomEmail(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), email: randomEmail(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), email: randomEmail(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` ## Pinned columns appearance By default, the pinned columns sections are separated from non-pinned columns with a border and a shadow that appears when there is scroll. You can change the appearance by setting the [`pinnedColumnsSectionSeparator`](/x/api/data-grid/data-grid-pro/#data-grid-pro-prop-pinnedColumnsSectionSeparator) prop to `'border'`, `'shadow'`, or `'border-and-shadow'`. ```tsx import * as React from 'react'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import FormControl from '@mui/material/FormControl'; import RadioGroup from '@mui/material/RadioGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import Radio from '@mui/material/Radio'; import { DataGridPro, GridActionsCellItem, type GridColDef, type GridRowsProp, type DataGridProProps, GridActionsCell, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomTraderName, randomEmail, randomUpdatedDate, } from '@mui/x-data-grid-generator'; type SectionSeparator = NonNullable< DataGridProProps['pinnedColumnsSectionSeparator'] >; export default function ColumnPinningSectionSeparator() { const [separator, setSeparator] = React.useState('border-and-shadow'); return (
setSeparator(event.target.value as SectionSeparator)} name="pinned-columns-section-separator" > } label={"border-and-shadow"} /> } label={"border"} /> } label={"shadow"} />
); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 160, editable: true }, { field: 'email', headerName: 'Email', width: 200, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, { field: 'actions', type: 'actions', width: 100, renderCell: (params) => ( } label="Edit" /> } label="Delete" /> ), }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), email: randomEmail(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), email: randomEmail(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), email: randomEmail(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), email: randomEmail(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), email: randomEmail(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 6, name: randomTraderName(), email: randomEmail(), age: 27, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 7, name: randomTraderName(), email: randomEmail(), age: 18, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 8, name: randomTraderName(), email: randomEmail(), age: 31, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 9, name: randomTraderName(), email: randomEmail(), age: 24, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 10, name: randomTraderName(), email: randomEmail(), age: 35, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` You can override the scroll shadow's color and opacity by setting the `--color` and `--opacity` CSS variables on the `.MuiDataGrid-scrollShadow` class. For example: ```tsx ``` ## Disabling column pinning Column pinning is enabled by default on the Data Grid Pro, but you can disable it for some or all columns. ### For all columns To disable pinning for all columns, set the `disableColumnPinning` prop to `true`: ```tsx ``` ### For specific columns To disable pinning for a specific column, set the `pinnable` property to `false` in the column's `GridColDef`, as shown below: ```tsx // Default is `true` ``` ### Remove pinning from the column menu An alternative option for disabling pinning actions is to remove them from the user interface, which can be done in one of two ways: 1. Use the column menu API to hide the pinning actions. See [Column menu—Hiding a menu item](/x/react-data-grid/column-menu/#hiding-a-menu-item) for details. 2. Use the [`disableColumnMenu` prop](/x/react-data-grid/column-menu/#disable-column-menu) to completely remove the column menu altogether. ## Pinning non-pinnable columns programmatically When [pinning is disabled](#disabling-column-pinning) in the UI for some or all columns (via `disableColumnPinning` or `colDef.pinnable`), it's still possible to implement it programmatically. You can do this in one of three ways: 1. Initialized pinning with `initialState` 2. Controlled pinning with `pinnedColumns` 3. Using the [`setPinnedColumns()` method](#apiref) The code snippets below illustrate these three approaches: ```tsx // 1. Initialized pinning // 2. Controlled pinning // 3. Using the `setPinnedColumns()` method ``` In the following demo, pinning is disabled but the Grid is initialized with the **Name** column pinned to the left: ```tsx import { DataGridPro, GridColDef, GridRowsProp } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomTraderName, randomEmail, randomUpdatedDate, } from '@mui/x-data-grid-generator'; export default function DisableColumnPinningButtons() { return (
); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 160, editable: true }, { field: 'email', headerName: 'Email', width: 200, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), email: randomEmail(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), email: randomEmail(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), email: randomEmail(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), email: randomEmail(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), email: randomEmail(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` ## Pinning autogenerated columns Certain features (such as [checkbox selection](/x/react-data-grid/row-selection/#checkbox-selection) and [row reordering](/x/react-data-grid/row-ordering/)) add autogenerated columns in the Data Grid. You can pin these by adding `GRID_CHECKBOX_SELECTION_COL_DEF.field` and `GRID_REORDER_COL_DEF.field`, respectively, to the list of pinned columns, as shown in the demo below: ```tsx import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import { DataGridPro, GridColDef, GridRowsProp, GridActionsCellItem, GRID_CHECKBOX_SELECTION_COL_DEF, GRID_REORDER_COL_DEF, GridActionsCell, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomTraderName, randomEmail, randomUpdatedDate, } from '@mui/x-data-grid-generator'; export default function ColumnPinningAutogeneratedColumns() { return (
); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 160, editable: true }, { field: 'email', headerName: 'Email', width: 200, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, { field: 'actions', type: 'actions', width: 100, renderCell: (params) => ( } label="Edit" /> } label="Delete" /> ), }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), email: randomEmail(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), email: randomEmail(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), email: randomEmail(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), email: randomEmail(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), email: randomEmail(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` ## Pinning columns with dynamic row height The Data Grid supports use cases involving both column pinning and [dynamic row height](/x/react-data-grid/row-height/#dynamic-row-height). However, if row contents change after the initial calculation, you may need to trigger a manual recalculation to avoid incorrect measurements. You can do this by calling `apiRef.current.resetRowHeights()` whenever the content changes. The demo below contains an example of both features enabled: ```tsx import * as React from 'react'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; import PrintIcon from '@mui/icons-material/Print'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { DataGridPro, GridColDef, GridRowsProp, useGridApiRef, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomTraderName, randomEmail, randomUpdatedDate, } from '@mui/x-data-grid-generator'; export default function ColumnPinningDynamicRowHeight() { const apiRef = useGridApiRef(); const [showEditDelete, setShowEditDelete] = React.useState(true); const columns: GridColDef[] = React.useMemo( () => [ { field: 'name', headerName: 'Name', width: 160, editable: true }, { field: 'email', headerName: 'Email', width: 200, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, { field: 'actions', headerName: 'Actions', width: 100, renderCell: () => ( {showEditDelete && ( )} ), }, ], [showEditDelete], ); const handleToggleClick = React.useCallback(() => { setShowEditDelete((prevShowEditDelete) => !prevShowEditDelete); }, []); React.useLayoutEffect(() => { apiRef.current?.resetRowHeights?.(); }, [apiRef, showEditDelete]); return (
'auto'} initialState={{ pinnedColumns: { left: ['name'], right: ['actions'] } }} />
); } const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), email: randomEmail(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), email: randomEmail(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), email: randomEmail(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), email: randomEmail(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), email: randomEmail(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 6, name: randomTraderName(), email: randomEmail(), age: 27, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 7, name: randomTraderName(), email: randomEmail(), age: 18, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 8, name: randomTraderName(), email: randomEmail(), age: 31, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 9, name: randomTraderName(), email: randomEmail(), age: 24, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 10, name: randomTraderName(), email: randomEmail(), age: 35, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` ## apiRef The Data Grid exposes a set of methods via the `apiRef` object that are used internally in the implementation of the column pinning 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. ::: ```jsx import ApiDocs from 'docsx/src/modules/components/ApiDocs'; import api from 'docsx/pages/x/api/data-grid/grid-column-pinning-api.json'; export default function ColumnPinningApiNoSnap() { return ; } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-recipes.md --- title: Data Grid - Column recipes --- # Data Grid - Column customization recipes Advanced column customization recipes. ## 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. ```tsx import * as React from 'react'; import { DataGridPro, useGridApiRef, GridColDef, GridColumnResizeParams, gridColumnFieldsSelector, GridApiPro, } from '@mui/x-data-grid-pro'; import Button from '@mui/material/Button'; const rows = [ { id: 1, username: '@MUI', age: 20, }, ]; export default function ColumnSizingPersistWidthOrder() { const apiRef = useGridApiRef(); const [index, setIndex] = React.useState(0); const inputColumns = React.useMemo( () => [ { field: 'id' }, { field: 'username', width: 200, key: index }, { field: 'age', disableReorder: true }, ], [index], ); const columnsState = useColumnsState(apiRef, inputColumns); return (
); } const useColumnsState = ( apiRef: React.RefObject, columns: GridColDef[], ) => { const [widths, setWidths] = React.useState>( {}, ); const [orderedFields, setOrderedFields] = React.useState( () => columns.map((column) => column.field), ); const onColumnWidthChange = React.useCallback( ({ colDef, width }: GridColumnResizeParams) => { setWidths((prev) => ({ ...prev, [colDef.field]: width })); }, [setWidths], ); const onColumnOrderChange = React.useCallback(() => { setOrderedFields(gridColumnFieldsSelector(apiRef)); }, [apiRef, setOrderedFields]); const computedColumns = React.useMemo( () => orderedFields.reduce((acc, field) => { const column = columns.find((col) => col.field === field); if (!column) { return acc; } if (widths[field]) { acc.push({ ...column, width: widths[field], }); return acc; } acc.push(column); return acc; }, []), [columns, widths, orderedFields], ); return { columns: computedColumns, onColumnWidthChange, onColumnOrderChange }; }; ``` :::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 [](/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. ```tsx import * as React from 'react'; import { DataGridPremium, useGridApiRef, GridColDef, GridColumnResizeParams, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, } from '@mui/x-data-grid-premium'; import Button from '@mui/material/Button'; const rows = [ { id: 1, product: 'Apples', region: 'North', quarter: 'Q1', sales: 1000, profit: 100, size: 'L', }, { id: 2, product: 'Apples', region: 'South', quarter: 'Q1', sales: 1200, profit: 120, size: 'M', }, { id: 3, product: 'Oranges', region: 'North', quarter: 'Q1', sales: 800, profit: 80, size: 'M', }, { id: 4, product: 'Oranges', region: 'South', quarter: 'Q1', sales: 900, profit: 90, size: 'S', }, { id: 5, product: 'Apples', region: 'North', quarter: 'Q2', sales: 1100, profit: 110, size: 'L', }, { id: 6, product: 'Apples', region: 'South', quarter: 'Q2', sales: 1300, profit: 130, size: 'L', }, { id: 7, product: 'Oranges', region: 'North', quarter: 'Q2', sales: 850, profit: 85, size: 'M', }, { id: 8, product: 'Oranges', region: 'South', quarter: 'Q2', sales: 950, profit: 95, size: 'S', }, ]; const pivotModel = { rows: [{ field: 'product' }, { field: 'size' }], columns: [{ field: 'region' }, { field: 'quarter' }], values: [ { field: 'sales', aggFunc: 'sum' }, { field: 'profit', aggFunc: 'avg' }, ], }; export default function ColumnSizingPersistWidthPivoting() { const apiRef = useGridApiRef(); const [index, setIndex] = React.useState(0); const inputColumns: GridColDef[] = React.useMemo( () => [ { field: 'product', headerName: 'Product', key: index }, { field: 'region', headerName: 'Region' }, { field: 'quarter', headerName: 'Quarter' }, { field: 'sales', headerName: 'Sales', type: 'number', }, { field: 'profit', headerName: 'Profit', type: 'number', valueFormatter: (value: number) => { if (!value) { return ''; } return `${value}%`; }, }, { field: 'size', headerName: 'Size', }, ], [index], ); const columnsState = useColumnsState(inputColumns); const pivotingColDef = React.useCallback( (field: GridColDef['field'], group: string[]) => { const pivotingField = [...group, field].join('>->'); const fieldWidth = columnsState.getColumnWidth(pivotingField); return fieldWidth ? { width: fieldWidth } : {}; }, [columnsState], ); const groupingColDef = React.useCallback(() => { const column = apiRef.current?.getColumn( GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, ); return column?.width ? { width: column.width } : {}; }, [apiRef]); return (
); } const useColumnsState = (columns: GridColDef[]) => { const [widths, setWidths] = React.useState>( {}, ); const onColumnWidthChange = React.useCallback( ({ colDef, width }: GridColumnResizeParams) => { setWidths((prev) => ({ ...prev, [colDef.field]: width })); }, [setWidths], ); const getColumnWidth = React.useCallback( (field: string): number | undefined => widths[field], [widths], ); const computedColumns = React.useMemo( () => columns.reduce((acc, column) => { if (widths[column.field]) { acc.push({ ...column, width: widths[column.field], }); return acc; } acc.push(column); return acc; }, []), [columns, widths], ); return { columns: computedColumns, getColumnWidth, onColumnWidthChange, }; }; ``` ## 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 ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { DataGrid, GridColDef, GridLongTextCell } from '@mui/x-data-grid'; import { styled } from '@mui/material/styles'; import Markdown from 'markdown-to-jsx'; const rows = [ { id: 1, title: 'Introduction to React', notes: 'React is a JavaScript library for building user interfaces. It uses a component-based architecture and virtual DOM for efficient updates.', markdown: '# Getting Started\n\nTo create a new React app:\n\n```bash\nnpx create-react-app my-app\n```\n\n**Key concepts:**\n- Components\n- Props\n- State', }, { id: 2, title: 'TypeScript Basics', notes: 'TypeScript adds static type definitions to JavaScript. It helps catch errors early and improves code maintainability in large codebases.', markdown: '## Type Annotations\n\nBasic types:\n\n```typescript\nlet name: string = "John";\nlet age: number = 30;\nlet active: boolean = true;\n```\n\n*TypeScript compiles to plain JavaScript.*', }, { id: 3, title: 'MUI Data Grid', notes: 'The MUI X Data Grid is a powerful component for displaying and editing tabular data. It supports sorting, filtering, pagination, and many other features out of the box.', markdown: '### Features\n\n1. Sorting & Filtering\n2. Pagination\n3. Column resizing\n4. Row selection\n\n> The Data Grid is highly customizable!', }, ]; const CharacterCountWrapper = styled('div')({ display: 'flex', flexDirection: 'column', height: '100%', }); const CharacterCountText = styled('span')(({ theme }) => ({ marginTop: 'auto', paddingTop: theme.spacing(1), fontSize: '0.75rem', color: theme.palette.text.secondary, })); const MarkdownPreview = styled('div')(({ theme }) => ({ fontFamily: theme.typography.fontFamily, '& h1, & h2, & h3': { marginTop: 0, marginBottom: theme.spacing(1), fontSize: '1rem', fontWeight: 600, }, '& p': { marginTop: 0, marginBottom: theme.spacing(1), }, '& ul, & ol': { marginTop: 0, marginBottom: theme.spacing(1), paddingLeft: theme.spacing(2), }, '& code': { backgroundColor: theme.palette.action.hover, padding: theme.spacing(0.25, 0.5), borderRadius: theme.shape.borderRadius, fontSize: '0.85em', }, '& pre': { backgroundColor: theme.palette.action.hover, padding: theme.spacing(1), borderRadius: theme.shape.borderRadius, overflow: 'auto', '& code': { backgroundColor: 'transparent', padding: 0, }, }, '& blockquote': { margin: 0, marginBottom: theme.spacing(1), paddingLeft: theme.spacing(1.5), borderLeft: `3px solid ${theme.palette.divider}`, color: theme.palette.text.secondary, }, '& strong': { fontWeight: 600, }, '& em': { fontStyle: 'italic', }, })); const columns: GridColDef[] = [ { field: 'title', headerName: 'Title', width: 180 }, { field: 'notes', headerName: 'Notes (with character count)', type: 'longText', width: 250, editable: true, renderCell: (params) => ( (
{value}
{value?.length ?? 0} characters
)} /> ), }, { field: 'markdown', headerName: 'Markdown (with preview)', type: 'longText', width: 250, editable: true, renderCell: (params) => ( ( {value ?? ''} )} slotProps={{ popperContent: { style: { minWidth: 375, maxHeight: 'initial', }, }, }} /> ), }, ]; export default function LongTextCustomPopupContent() { return ( ); } ``` --- # Source: https://mui.com/x/react-data-grid/column-spanning.md # Data Grid - Column spanning Span cells across several columns. By default, each cell takes up the width of one column. You can modify this behavior with column spanning, which makes it possible for cells to span multiple columns. This is very close to the "column spanning" in an HTML ``. To change the number of columns a cell should span, use the `colSpan` property available in `GridColDef`: ```ts interface GridColDef { /** * Number of columns a cell should span. * @default 1 */ colSpan?: number | ((params: GridCellParams) => number | undefined); … } ``` :::warning When using `colSpan`, some other features may be pointless or may not work as expected (depending on the data model). To avoid a confusing grid layout, consider disabling the following features for any columns that are affected by `colSpan`: - [sorting](/x/react-data-grid/sorting/#disable-the-sorting) - [filtering](/x/react-data-grid/filtering/#disable-the-filters) - [column reorder](/x/react-data-grid/column-ordering/) - [hiding columns](/x/react-data-grid/column-visibility/) - [column pinning](/x/react-data-grid/column-pinning/#disabling-column-pinning) ::: ## Number signature The number signature sets **all cells in the column** to span a given number of columns. ```ts interface GridColDef { colSpan?: number; } ``` ```tsx import { DataGrid } from '@mui/x-data-grid'; const other = { showCellVerticalBorder: true, showColumnVerticalBorder: true, }; const rows = [ { id: 1, username: '@MUI', age: 20 }, { id: 2, username: '@MUI-X', age: 25 }, ]; export default function ColumnSpanningNumber() { return (
); } ``` ## Function signature The function signature makes it possible to only span specific cells in the column. The function receives [`GridCellParams`](/x/api/data-grid/grid-cell-params/) as argument. ```ts interface GridColDef { colSpan?: (params: GridCellParams) => number | undefined; } ``` ```tsx import Box from '@mui/material/Box'; import { DataGrid, DataGridProps, GridColDef } from '@mui/x-data-grid'; const items = [ { id: 1, item: 'Paperclip', quantity: 100, price: 1.99 }, { id: 2, item: 'Paper', quantity: 10, price: 30 }, { id: 3, item: 'Pencil', quantity: 100, price: 1.25 }, ]; type Item = (typeof items)[number]; interface SubtotalHeader { id: 'SUBTOTAL'; label: string; subtotal: number; } interface TaxHeader { id: 'TAX'; label: string; taxRate: number; taxTotal: number; } interface TotalHeader { id: 'TOTAL'; label: string; total: number; } type Row = Item | SubtotalHeader | TaxHeader | TotalHeader; const rows: Row[] = [ ...items, { id: 'SUBTOTAL', label: 'Subtotal', subtotal: 624 }, { id: 'TAX', label: 'Tax', taxRate: 10, taxTotal: 62.4 }, { id: 'TOTAL', label: 'Total', total: 686.4 }, ]; const baseColumnOptions = { sortable: false, pinnable: false, hideable: false, }; const columns: GridColDef[] = [ { field: 'item', headerName: 'Item/Description', ...baseColumnOptions, flex: 3, colSpan: (value, row) => { if (row.id === 'SUBTOTAL' || row.id === 'TOTAL') { return 3; } if (row.id === 'TAX') { return 2; } return undefined; }, valueGetter: (value, row) => { if (row.id === 'SUBTOTAL' || row.id === 'TAX' || row.id === 'TOTAL') { return row.label; } return value; }, }, { field: 'quantity', headerName: 'Quantity', ...baseColumnOptions, flex: 1, sortable: false, }, { field: 'price', headerName: 'Price', flex: 1, ...baseColumnOptions, valueGetter: (value, row) => { if (row.id === 'TAX') { return `${row.taxRate}%`; } return value; }, }, { field: 'total', headerName: 'Total', flex: 1, ...baseColumnOptions, valueGetter: (value, row) => { if (row.id === 'SUBTOTAL') { return row.subtotal; } if (row.id === 'TAX') { return row.taxTotal; } if (row.id === 'TOTAL') { return row.total; } return row.price * row.quantity; }, }, ]; const getCellClassName: DataGridProps['getCellClassName'] = ({ row, field }) => { if (row.id === 'SUBTOTAL' || row.id === 'TOTAL' || row.id === 'TAX') { if (field === 'item') { return 'bold'; } } return ''; }; export default function ColumnSpanningFunction() { return ( ); } ``` Function signature can also be useful to derive `colSpan` value from row data: ```tsx import Box from '@mui/material/Box'; import { DataGridPro, GridColDef } from '@mui/x-data-grid-pro'; const slotTimesLookup = { 0: '09:00 - 10:00', 1: '10:00 - 11:00', 2: '11:00 - 12:00', 3: '12:00 - 13:00', 4: '13:00 - 14:00', 5: '14:00 - 15:00', 6: '15:00 - 16:00', 7: '16:00 - 17:00', }; type Subject = | 'Maths' | 'English' | 'Lab' | 'Chemistry' | 'Physics' | 'Music' | 'Dance'; type Row = { id: number; day: string; slots: Array }; const rows: Array = [ { id: 1, day: 'Monday', slots: ['Maths', 'English', 'English', 'Lab', '', 'Lab', 'Music', 'Music'], }, { id: 2, day: 'Tuesday', slots: [ 'Chemistry', 'Chemistry', 'Chemistry', 'Physics', '', 'Maths', 'Lab', 'Dance', ], }, { id: 3, day: 'Wednesday', slots: ['Physics', 'English', 'Maths', 'Maths', '', 'Chemistry', 'Chemistry'], }, { id: 4, day: 'Thursday', slots: [ 'Music', 'Music', 'Chemistry', 'Chemistry', '', 'Chemistry', 'English', 'English', ], }, { id: 5, day: 'Friday', slots: ['Maths', 'Dance', 'Dance', 'Physics', '', 'English'], }, ]; const slotColumnCommonFields: Partial = { sortable: false, filterable: false, pinnable: false, hideable: false, minWidth: 140, cellClassName: (params) => params.value, colSpan: (value, row, column) => { const index = Number(column.field); let colSpan = 1; for (let i = index + 1; i < row.slots.length; i += 1) { const nextValue = row.slots[i]; if (nextValue === value) { colSpan += 1; } else { break; } } return colSpan; }, }; const columns: GridColDef[] = [ { field: 'day', headerName: 'Day', }, { field: '0', headerName: slotTimesLookup[0], valueGetter: (value, row) => row.slots[0], ...slotColumnCommonFields, }, { field: '1', headerName: slotTimesLookup[1], valueGetter: (value, row) => row.slots[1], ...slotColumnCommonFields, }, { field: '2', headerName: slotTimesLookup[2], valueGetter: (value, row) => row.slots[2], ...slotColumnCommonFields, }, { field: '3', headerName: slotTimesLookup[3], valueGetter: (value, row) => row.slots[3], ...slotColumnCommonFields, }, { field: '4', headerName: slotTimesLookup[4], valueGetter: (value, row) => row.slots[4], ...slotColumnCommonFields, }, { field: '5', headerName: slotTimesLookup[5], valueGetter: (value, row) => row.slots[5], ...slotColumnCommonFields, }, { field: '6', headerName: slotTimesLookup[6], valueGetter: (value, row) => row.slots[6], ...slotColumnCommonFields, }, { field: '7', headerName: slotTimesLookup[7], valueGetter: (value, row) => row.slots[7], ...slotColumnCommonFields, }, ]; const rootStyles = { display: 'flex', flexDirection: 'column', height: 'fit-content', width: '100%', '& .Maths': { backgroundColor: 'rgba(157, 255, 118, 0.49)', }, '& .English': { backgroundColor: 'rgba(255, 255, 10, 0.49)', }, '& .Lab': { backgroundColor: 'rgba(150, 150, 150, 0.49)', }, '& .Chemistry': { backgroundColor: 'rgba(255, 150, 150, 0.49)', }, '& .Physics': { backgroundColor: 'rgba(10, 150, 255, 0.49)', }, '& .Music': { backgroundColor: 'rgba(224, 183, 60, 0.55)', }, '& .Dance': { backgroundColor: 'rgba(200, 150, 255, 0.49)', }, }; export default function ColumnSpanningDerived() { return ( ); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/column-visibility.md # Data Grid - Column visibility Define which columns are visible. By default, all the columns are visible. The column's visibility can be switched through the user interface in two ways: - By opening the column menu and clicking the _Hide_ menu item. - By clicking the _Columns_ menu and toggling the columns to show or hide. You can prevent the user from hiding a column through the user interface by setting the `hideable` in `GridColDef` to `false`. In the following demo, the "username" column cannot be hidden. ```tsx import { DataGrid } from '@mui/x-data-grid'; const rows = [ { id: 1, username: '@MUI', age: 38, desk: 'D-546', }, { id: 2, username: '@MUI-X', age: 25, desk: 'D-042', }, ]; export default function VisibleColumnsBasicExample() { return (
); } ``` ## Initialize the visible columns To initialize the visible columns without controlling them, provide the model to the `initialState` prop. :::info Passing the visible columns to the `initialState` prop will only have an impact when the Data Grid is rendered for the first time. In order to update the visible columns after the first render, you need to use the [`columnVisibilityModel`](#controlled-visible-columns) prop. ::: ```tsx ``` ```tsx import { useDemoData } from '@mui/x-data-grid-generator'; import { DataGrid } from '@mui/x-data-grid'; export default function VisibleColumnsModelInitialState() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 20, }); return (
); } ``` ## Controlled visible columns Use the `columnVisibilityModel` prop to control the visible columns. You can use the `onColumnVisibilityModelChange` prop to listen to the changes to the visible columns and update the prop accordingly. ```tsx ``` ```tsx import * as React from 'react'; import { useDemoData } from '@mui/x-data-grid-generator'; import { DataGrid, GridColumnVisibilityModel } from '@mui/x-data-grid'; export default function VisibleColumnsModelControlled() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 20, maxColumns: 20, }); const [columnVisibilityModel, setColumnVisibilityModel] = React.useState({ id: false, brokerId: false, status: false, }); return (
setColumnVisibilityModel(newModel) } />
); } ``` ## Column visibility panel The column visibility panel lets users control which columns are visible in the Data Grid. The panel can be opened by: - Clicking the _Columns_ button in the [toolbar](/x/react-data-grid/components/#toolbar). - Clicking the _Manage columns_ button in the [column menu](/x/react-data-grid/column-menu/). ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function ColumnSelectorGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 10, }); return (
); } ``` ### Disable the column visibility panel Sometimes, the intention is to disable the columns panel or control the visible columns programmatically based on the application state. To disable the column visibility panel, set the prop `disableColumnSelector={true}` and use the [`columnVisibilityModel`](#controlled-visible-columns) prop to control the visible columns. ```tsx ``` In the following demo, the columns panel is disabled, and access to columns `id`, `quantity`, and `filledQuantity` is only permitted for the `Admin` type user. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import FormControl from '@mui/material/FormControl'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import MenuItem from '@mui/material/MenuItem'; import InputLabel from '@mui/material/InputLabel'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const UserType = { Regular: 0, Admin: 1, }; export default function ColumnSelectorDisabledGrid() { const [userType, setUserType] = React.useState(UserType.Regular); const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 7, }); const columnVisibilityModel = React.useMemo(() => { if (userType === UserType.Admin) { return { quantity: true, filledQuantity: true, id: true, }; } return { quantity: false, filledQuantity: false, id: false, }; }, [userType]); return ( User Type
); } ``` ### Customize the list of columns in columns management To show or hide specific columns in the column visibility panel, use the `slotProps.columnsManagement.getTogglableColumns` prop. It should return an array of column field names. ```tsx import { DataGridPremium, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, } from '@mui/x-data-grid-premium'; // stop `id`, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, and `status` columns from being togglable const hiddenFields = ['id', GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, 'status']; const getTogglableColumns = (columns: GridColDef[]) => { return columns .filter((column) => !hiddenFields.includes(column.field)) .map((column) => column.field); }; ; ``` ```tsx import { DataGridPremium, GridColDef, useKeepGroupedColumnsHidden, useGridApiRef, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; const hiddenFields = ['id', GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, 'status']; const getTogglableColumns = (columns: GridColDef[]) => { return columns .filter((column) => !hiddenFields.includes(column.field)) .map((column) => column.field); }; export default function ColumnSelectorGridCustomizeColumns() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 10, }); const apiRef = useGridApiRef(); const initialState = useKeepGroupedColumnsHidden({ apiRef, initialState: { ...data.initialState, rowGrouping: { model: ['status'], }, }, }); return (
); } ``` ### Disable actions in footer To disable `Show/Hide All` checkbox or `Reset` button in the footer of the columns management component, pass `disableShowHideToggle` or `disableResetButton` to `slotProps.columnsManagement`. ```tsx ``` ### Customize action buttons behavior when search is active By default, the `Show/Hide All` checkbox toggles the visibility of all columns, including the ones that are not visible in the current search results. To only toggle the visibility of the columns that are present in the current search results, pass `toggleAllMode: 'filteredOnly'` to `slotProps.columnsManagement`. ```tsx ``` ```tsx import { DataGridPremium } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function ColumnSelectorGridToggleAllMode() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 10, }); return (
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/api/data-grid/columns-panel-trigger.md # ColumnsPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Data Grid - Columns Panel component 🚧](/x/react-data-grid/components/columns-panel) ## Import ```jsx import { ColumnsPanelTrigger } from '@mui/x-data-grid/components'; // or import { ColumnsPanelTrigger } from '@mui/x-data-grid'; // or import { ColumnsPanelTrigger } from '@mui/x-data-grid-pro'; // or import { ColumnsPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/columnsPanel/ColumnsPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/columnsPanel/ColumnsPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/components/columns-panel.md --- productId: x-data-grid components: ColumnsPanelTrigger packageName: '@mui/x-data-grid' githubLabel: 'scope: data grid' --- # Data Grid - Columns Panel component 🚧 Customize the Data Grid's columns panel. :::warning This component is incomplete. Currently, the Columns Panel Trigger is the only part of the Columns Panel component available. Future versions of the Columns Panel component will make it possible to compose each of its parts to create a custom columns panel. In the meantime, it's still possible to deeply customize the panel's subcomponents using custom slots. See [Custom subcomponents—Columns panel](/x/react-data-grid/components/#columns-panel) for more details. ::: The columns panel is part of the [column visibility feature](/x/react-data-grid/column-visibility/) and is enabled by default. Users can trigger the columns panel via the column menu, as well as from the toolbar when `showToolbar` is passed to the `` component. You can use the Columns Panel Trigger and [Toolbar](/x/react-data-grid/components/toolbar/) components when you need to customize the columns panel trigger, or when implementing a custom toolbar. ## Basic usage The demo below shows how to add a columns panel trigger to a custom toolbar. ```tsx import { DataGrid, Toolbar, ToolbarButton, ColumnsPanelTrigger, } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import Tooltip from '@mui/material/Tooltip'; import ViewColumnIcon from '@mui/icons-material/ViewColumn'; function CustomToolbar() { return ( }> ); } export default function GridColumnsPanelTrigger() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 10, }); return (
); } ``` ## Anatomy ```tsx import { ColumnsPanelTrigger } from '@mui/x-data-grid'; ; ``` ### Columns Panel Trigger `` is a button that opens and closes the columns panel. It renders the `baseButton` slot. ## Custom elements Use the `render` prop to replace default elements. See [Components usage—Customization](/x/react-data-grid/components/usage/#customization) for more details, and [Toolbar—Custom elements demo](/x/react-data-grid/components/toolbar/#custom-elements) for an example of a custom Columns Panel Trigger. ## Accessibility ### ARIA You must apply a text label or an `aria-label` attribute to the ``. # ColumnsPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Data Grid - Columns Panel component 🚧](/x/react-data-grid/components/columns-panel) ## Import ```jsx import { ColumnsPanelTrigger } from '@mui/x-data-grid/components'; // or import { ColumnsPanelTrigger } from '@mui/x-data-grid'; // or import { ColumnsPanelTrigger } from '@mui/x-data-grid-pro'; // or import { ColumnsPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/columnsPanel/ColumnsPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/columnsPanel/ColumnsPanelTrigger.tsx) --- # Source: https://mui.com/x/react-charts/components.md --- title: Charts - Custom components productId: x-charts components: ChartsClipPath, ChartsSurface --- # Charts - Custom components Create custom chart components using the provided hooks. 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(); ``` ```tsx import * as React from 'react'; import { styled } from '@mui/material/styles'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { LinePlot } from '@mui/x-charts/LineChart'; import { useDrawingArea } from '@mui/x-charts/hooks'; const StyledPath = styled('path')(({ theme }) => ({ fill: 'none', stroke: theme.palette.text.primary, shapeRendering: 'crispEdges', strokeWidth: 1, pointerEvents: 'none', })); const StyledText = styled('text')(({ theme }) => ({ stroke: 'none', fill: theme.palette.text.primary, shapeRendering: 'crispEdges', })); function DrawingAreaBox() { const { left, top, width, height } = useDrawingArea(); return ( ({left},{top}) ({left + width},{top + height}) ); } export default function BasicScaleDemo() { return ( ); } ``` ### 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); ``` ```tsx import * as React from 'react'; import { styled } from '@mui/material/styles'; import { ScaleLinear } from '@mui/x-charts-vendor/d3-scale'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { LinePlot } from '@mui/x-charts/LineChart'; import { useDrawingArea, useXScale, useYScale } from '@mui/x-charts/hooks'; const x = Array.from({ length: 21 }, (_, index) => -1 + 0.2 * index); const linear = x.map((v) => -1 + v); const poly = x.map((v) => -1 + v ** 2 - v); const StyledPath = styled('path')<{ color: 'primary' | 'secondary' }>( ({ theme, color }) => ({ fill: 'none', stroke: theme.palette.text[color], shapeRendering: 'crispEdges', strokeWidth: 1, pointerEvents: 'none', }), ); function CartesianAxis() { // Get the drawing area bounding box const { left, top, width, height } = useDrawingArea(); // Get the two scale const yAxisScale = useYScale() as ScaleLinear; const xAxisScale = useXScale() as ScaleLinear; const yOrigin = yAxisScale(0); const xOrigin = xAxisScale(0); const xTicks = [-2, -1, 1, 2, 3]; const yTicks = [-2, -1, 1, 2, 3, 4, 5]; return ( {yTicks.map((value) => ( ))} {xTicks.map((value) => ( ))} ); } export default function OriginDemo() { return ( ); } ``` #### 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 {leftAxisScale.invert(yCoordinate).toFixed(0)} ``` ```tsx import * as React from 'react'; import { ScaleLinear } from '@mui/x-charts-vendor/d3-scale'; import { styled } from '@mui/material/styles'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { LinePlot } from '@mui/x-charts/LineChart'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { useDrawingArea, useYScale } from '@mui/x-charts/hooks'; const StyledPath = styled('path')(({ theme }) => ({ fill: 'none', stroke: theme.palette.text.primary, shapeRendering: 'crispEdges', strokeWidth: 1, pointerEvents: 'none', strokeDasharray: '5 2', })); const StyledText = styled('text')(({ theme }) => ({ stroke: 'none', fill: theme.palette.text.primary, shapeRendering: 'crispEdges', })); function ValueHighlight(props: { svgRef: React.RefObject }) { const { svgRef } = props; // Get the drawing area bounding box const { left, top, width, height } = useDrawingArea(); // Get the two scale const leftAxisScale = useYScale('left_axis_id') as ScaleLinear; const rightAxisScale = useYScale('right_axis_id') as ScaleLinear; const [mouseY, setMouseY] = React.useState(null); React.useEffect(() => { const element = svgRef.current; if (element === null) { return () => {}; } const handleMouseOut = () => { setMouseY(null); }; const handleMouseMove = (event: MouseEvent) => { const x = event.offsetX; const y = event.offsetY; if (x < left || x > left + width) { setMouseY(null); return; } if (y < top - 10 || y > top + height + 10) { // Allows some margin if slightly on top/bottom of the drawing area setMouseY(null); return; } setMouseY(Math.max(Math.min(top + height, y), top)); // clamp to the drawing area }; element.addEventListener('mouseout', handleMouseOut); element.addEventListener('mousemove', handleMouseMove); return () => { element.removeEventListener('mouseout', handleMouseOut); element.removeEventListener('mousemove', handleMouseMove); }; }, [height, left, top, width, svgRef]); if (mouseY === null) { return null; } return ( {leftAxisScale.invert(mouseY).toFixed(0)} {rightAxisScale.invert(mouseY).toFixed(0)} ); } export default function ScaleDemo() { const svgRef = React.useRef(null); return ( ); } ``` ### 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: ```tsx import * as React from 'react'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { LinePlot } from '@mui/x-charts/LineChart'; import { useLineSeries, useXAxis, useXScale, useYScale } from '@mui/x-charts/hooks'; import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import { DefaultizedLineSeriesType } from '@mui/x-charts/models'; function ExtremaLabels() { const lineSeries = useLineSeries(); if (!lineSeries) { return null; } return ( {lineSeries.map((series) => ( ))} ); } function SingleSeriesExtremaLabels({ series, }: { series: DefaultizedLineSeriesType; }) { const xAxis = useXAxis('x'); const min = series.data.reduce( (acc, value, index) => value != null && value < acc.value ? { index, value } : acc, { index: -1, value: Infinity }, ); const max = series.data.reduce( (acc, value, index) => value != null && value > acc.value ? { index, value } : acc, { index: -1, value: -Infinity }, ); return ( ); } function PointLabel({ x, y, placement, color, }: { x: number; y: number; placement: 'above' | 'below'; color: string; }) { const xAxisScale = useXScale(); const yAxisScale = useYScale(); const left = xAxisScale(x) ?? 0; const top = (yAxisScale(y) ?? 0) + (placement === 'below' ? 20 : -20); return ( {y} ); } export default function SeriesDemo() { return ( ); } ``` ## HTML components Use the `ChartDataProvider` 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 `
` element, which can be customized in any way. ```tsx import Box from '@mui/material/Box'; import { useLegend } from '@mui/x-charts/hooks'; import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; import { BarPlot } from '@mui/x-charts/BarChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; function MyCustomLegend() { const { items } = useLegend(); return (
{items.map((v) => { return ( ); })}
{`${v.label}`}
); } const veryLongText = "Second Series. You should always try to avoid long sentences. But oftentimes, it's not possible. So, we need to handle them gracefully. This is a very long sentence that should be fully readable."; export default function HtmlLegend() { return ( ); } ``` :::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 `ChartDataProvider` component to get access to the data. ::: # ChartsClipPath API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Custom components](/x/react-charts/components/) ## Import ```jsx import { ChartsClipPath } from '@mui/x-charts/ChartsClipPath'; // or import { ChartsClipPath } from '@mui/x-charts'; // or import { ChartsClipPath } from '@mui/x-charts-pro'; // or import { ChartsClipPath } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | id | `string` | - | Yes | | | offset | `{ bottom?: number, left?: number, right?: number, top?: number }` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsClipPath/ChartsClipPath.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsClipPath/ChartsClipPath.tsx) # ChartsSurface API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Custom components](/x/react-charts/components/) - [Charts - Composition](/x/react-charts/composition/) ## Import ```jsx import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; // or import { ChartsSurface } from '@mui/x-charts'; // or import { ChartsSurface } from '@mui/x-charts-pro'; // or import { ChartsSurface } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsSurface/ChartsSurface.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsSurface/ChartsSurface.tsx) --- # Source: https://mui.com/x/react-charts/composition.md --- title: React Chart composition productId: x-charts githubLabel: 'scope: charts' components: ChartContainer, ChartContainerPro, ChartsGrid, ChartDataProvider, ChartDataProviderPro, ChartsSurface packageName: '@mui/x-charts' --- # Charts - Composition Learn how to use composition to build advanced custom Charts. 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 - `ChartDataProvider` provides data to descendants. - `ChartsSurface` renders the SVG element. - Helpers - `ChartContainer` combines the Data Provider and Surface components. - `ChartsWrapper` styled div that positions surface, tooltip, and legend on a grid. :::info Demos in this doc use the `ChartContainer` component. For demos using `ChartDataProvider` 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 `ChartDataProvider` and not `ChartsSurface`. `ChartsLegend` is placed inside `ChartDataProvider` to get access to the context, but outside `ChartsSurface` since it's not an SVG component. ```jsx {children} ``` ### Chart Container usage `ChartContainer` is the direct concatenation of `ChartDataProvider` and `ChartsSurface`. It takes care of dispatching props between the two components. Using `ChartContainer` 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 {children} // Only SVG component here ``` ### Chart Wrapper usage Charts are often constructed of a graphic with 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 {children} ``` ## Graphical components Graphical components are used to render the visual elements of a chart. They are descendants of [`ChartDataProvider`](#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 `ChartContainer` 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. ```tsx import * as React from 'react'; import Paper from '@mui/material/Paper'; import Box from '@mui/material/Box'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { BarPlot } from '@mui/x-charts/BarChart'; import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; export default function BasicComposition() { const [isResponsive, setIsResponsive] = React.useState(false); const sizingProps = isResponsive ? {} : { width: 500, height: 300 }; return ( setIsResponsive(event.target.checked)} /> } label="Use responsive container" labelPlacement="end" /> ); } ``` ### Properties `ChartContainer` 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—Color palette](/x/react-charts/styling/#color-palette) 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 ``` When composing a custom chart, `ChartContainer` 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 {/* Only displays the series with type: 'bar' */} {/* Only displays series with type: 'line' */} ``` 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 ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { BarPlot } from '@mui/x-charts/BarChart'; import { LinePlot } from '@mui/x-charts/LineChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; export default function SwitchSeriesType() { const [type, setType] = React.useState<'line' | 'bar'>('line'); return ( setType(event.target.value as 'line' | 'bar')} label="series type" sx={{ minWidth: 150 }} > line bar
); } ``` ## 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 `` 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 `` element. Set the `clipPath` attribute to `url(#${clipPathId})` to reference the previously defined clip path. Example: ```` ```jsx // The plotting to clip in the drawing area. // Defines the clip path of the drawing area. ``` 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. ```tsx import * as React from 'react'; import Slider from '@mui/material/Slider'; import Box from '@mui/material/Box'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import useId from '@mui/utils/useId'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { ScatterPlot } from '@mui/x-charts/ScatterChart'; import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; import { ChartsClipPath } from '@mui/x-charts/ChartsClipPath'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsGrid } from '@mui/x-charts/ChartsGrid'; import { Chance } from 'chance'; const chance = new Chance(42); const data = Array.from({ length: 100 }, () => ({ x: chance.floating({ min: -25, max: 25 }), y: chance.floating({ min: -25, max: 25 }), })).map((d, index) => ({ ...d, id: index })); const minDistance = 10; export default function LimitOverflow() { const [isLimited, setIsLimited] = React.useState(false); const [xLimits, setXLimites] = React.useState([-20, 20]); const id = useId(); const clipPathId = `${id}-clip-path`; const handleChange = ( event: Event, newValue: number | number[], activeThumb: number, ) => { if (!Array.isArray(newValue)) { return; } if (newValue[1] - newValue[0] < minDistance) { if (activeThumb === 0) { const clamped = Math.min(newValue[0], 100 - minDistance); setXLimites([clamped, clamped + minDistance]); } else { const clamped = Math.max(newValue[1], minDistance); setXLimites([clamped - minDistance, clamped]); } } else { setXLimites(newValue as number[]); } }; return ( setIsLimited(event.target.checked)} /> } label="Clip the plot" labelPlacement="end" /> {isLimited && } ); } ``` :::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/#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 `ChartDataProvider` 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 `ChartContainer`. You must use `ChartDataProvider` and `ChartsSurface` instead. ```jsx // ✅ Correct {/* SVG components */} // ❌ Incorrect ``` ::: 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. ```tsx import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; import { ChartsLegend } from '@mui/x-charts/ChartsLegend'; import { ChartsTooltip } from '@mui/x-charts/ChartsTooltip'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight'; import Box from '@mui/material/Box'; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function LegendTooltipComposition() { return ( ); } ``` :::info By default, `ChartContainer` 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 ``` ::: ## 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. ```tsx import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { ScatterPlot } from '@mui/x-charts/ScatterChart'; import { LinePlot } from '@mui/x-charts/LineChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; import { internetUsageByCountry } from '../dataset/internetUsageByCountry'; const data = Object.values(internetUsageByCountry); function calculateStatistics(values: number[]) { const n = values.length; const mean = values.reduce((sum, val) => sum + val, 0) / n; const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / n; const stdDev = Math.sqrt(variance); return { mean, stdDev }; } function normalDistribution(x: number, mean: number, stdDev: number) { const exponent = -Math.pow(x - mean, 2) / (2 * Math.pow(stdDev, 2)); return (1 / (stdDev * Math.sqrt(2 * Math.PI))) * Math.exp(exponent); } export default function BellCurveOverlay() { const { mean, stdDev } = calculateStatistics(data); // Generate bell curve data const min = Math.min(...data); const max = Math.max(...data); const range = max - min; const bellCurveData: number[] = []; const xValues: number[] = []; const numPoints = 100; for (let i = 0; i <= numPoints; i += 1) { const x = min - range * 0.1 + ((max - min + range * 0.2) * i) / numPoints; xValues.push(x); bellCurveData.push(normalDistribution(x, mean, stdDev)); } // Stack points that are close together const binWidth = range / 70; // Adjust this to control stacking sensitivity const sortedData = [...data].sort((a, b) => a - b); const bins: Map = new Map(); // Group values into bins sortedData.forEach((value) => { const binIndex = Math.round(value / binWidth); if (!bins.has(binIndex)) { bins.set(binIndex, []); } bins.get(binIndex)!.push(value); }); // Create scatter data with stacked y-positions const scatterData: Array<{ x: number; y: number; id: number }> = []; let globalIndex = 0; const baseY = 0.0005; const stackHeight = 0.001; bins.forEach((values) => { values.forEach((value, stackIndex) => { scatterData.push({ x: value, y: baseY + stackIndex * stackHeight, id: globalIndex, }); globalIndex += 1; }); }); return (
`${value}%`, }, ]} yAxis={[ { position: 'none', }, ]} height={400} >
); } ``` --- # Source: https://mui.com/x/react-charts/content-security-policy.md --- title: Content Security Policy (CSP) productId: x-charts --- # Charts - Content Security Policy (CSP) This section covers the details of setting up a Content Security Policy. ## What is CSP and why is it useful? CSP mitigates cross-site scripting (XSS) attacks by requiring developers to whitelist the sources their assets are retrieved from. This list is returned as a header from the server. For instance, say you have a site hosted at `https://example.com` the CSP header `default-src: 'self';` will allow all assets that are located at `https://example.com/*` and deny all others. If there is a section of your website that is vulnerable to XSS where unescaped user input is displayed, an attacker could input something like: ```html ``` This vulnerability would allow the attacker to execute anything. However, with a secure CSP header, the browser will not load this script. You can read more about CSP on the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP). ## Setting up a CSP MUI X Charts depends on Material UI, thus to set up a CSP, you need to follow Material UI's [CSP implementation guide](/material-ui/guides/content-security-policy/#how-does-one-implement-csp). ### CSP for exporting MUI X Charts allow [exporting charts](/x/react-charts/export/) as images or PDFs. When a Content Security Policy is set, exporting requires additional configuration to function. To enable exporting with CSP, you need to allow the use of `data:` and `blob:` URIs for images. This can be done by adding the following directives to your CSP header: ```text Content-Security-Policy: img-src 'self' data: blob:; ``` If your CSP defines a nonce for scripts or styles (for example, `script-src 'nonce-'`), you also need to provide the same nonce when exporting. This can be done by passing the nonce to the `printOptions` and `imageExportOptions` props of the `toolbar` slot. ```tsx ``` --- # Source: https://mui.com/x/api/charts/continuous-color-legend.md # ContinuousColorLegend API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Legend](/x/react-charts/legend/) ## Import ```jsx import { ContinuousColorLegend } from '@mui/x-charts/ChartsLegend'; // or import { ContinuousColorLegend } from '@mui/x-charts'; // or import { ContinuousColorLegend } from '@mui/x-charts-pro'; // or import { ContinuousColorLegend } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | axisDirection | `'x' \| 'y' \| 'z'` | `'z'` | No | | | axisId | `number \| string` | `The first axis item.` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | direction | `'horizontal' \| 'vertical'` | `'horizontal'` | No | | | gradientId | `string` | `auto-generated id` | No | | | labelPosition | `'start' \| 'end' \| 'extremes'` | `'end'` | No | | | maxLabel | `func \| string` | `formattedValue` | No | | | minLabel | `func \| string` | `formattedValue` | No | | | reverse | `bool` | `false` | No | | | rotateGradient | `bool` | - | No | | | thickness | `number` | `12` | No | | > **Note**: The `ref` is forwarded to the root element (HTMLUListElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiContinuousColorLegend` to change the default props of this component with the theme. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | end | Styles applied to the legend with the labels after the gradient. | | - | extremes | Styles applied to the legend with the labels on the extremes of the gradient. | | - | gradient | Styles applied to the list item with the gradient. | | - | horizontal | Styles applied to the legend in row layout. | | - | label | Styles applied to the series label. | | - | maxLabel | Styles applied to the list item that renders the `maxLabel`. | | - | minLabel | Styles applied to the list item that renders the `minLabel`. | | - | root | Styles applied to the root element. | | - | start | Styles applied to the legend with the labels before the gradient. | | - | vertical | Styles applied to the legend in column layout. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/ChartsLegend/ContinuousColorLegend.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/ChartsLegend/ContinuousColorLegend.tsx) --- # Source: https://mui.com/x/react-data-grid/custom-columns.md # Data Grid - Custom columns Create custom column types. You can extend the [built-in column types](/x/react-data-grid/column-definition/#column-types) with your own by simply spreading the necessary properties. The demo below defines a new column type: `usdPrice` that extends the native `number` column type. ```ts const usdPrice: GridColTypeDef = { type: 'number', width: 130, valueFormatter: (value) => valueFormatter.format(Number(value)), cellClassName: 'font-tabular-nums', }; ``` ```tsx import Box from '@mui/material/Box'; import { DataGrid, GridColTypeDef } from '@mui/x-data-grid'; import { randomStatusOptions, randomPrice } from '@mui/x-data-grid-generator'; const rows = [ { id: 1, status: randomStatusOptions(), subTotal: randomPrice(), total: randomPrice(), }, { id: 2, status: randomStatusOptions(), subTotal: randomPrice(), total: randomPrice(), }, { id: 3, status: randomStatusOptions(), subTotal: randomPrice(), total: randomPrice(), }, ]; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', }); const usdPrice: GridColTypeDef = { type: 'number', width: 130, valueFormatter: (value) => currencyFormatter.format(value), cellClassName: 'font-tabular-nums', }; export default function CustomColumnTypesGrid() { return ( ); } ``` :::info If an unsupported column type is used, the `string` column type will be used instead. ::: ## Sparkline Sparkline charts can be useful as an overview of data trends. In the demo below, we create a custom column type using the `GridColTypeDef` interface and use the [Sparkline](/x/react-charts/sparkline/) component from [`@mui/x-charts`](/x/react-charts/) package in the [`renderCell`](/x/react-data-grid/column-definition/#rendering-cells) property. ```tsx import * as React from 'react'; import { DataGrid, GridColDef, GridColTypeDef, GridRenderCellParams, GRID_STRING_COL_DEF, } from '@mui/x-data-grid'; import { SparkLineChart } from '@mui/x-charts/SparkLineChart'; type SparkLineChartProps = React.ComponentProps; function GridSparklineCell( props: GridRenderCellParams & { plotType?: SparkLineChartProps['plotType']; }, ) { if (props.value == null) { return null; } return ( ); } const sparklineColumnType: GridColTypeDef = { ...GRID_STRING_COL_DEF, type: 'custom', resizable: false, filterable: false, sortable: false, editable: false, groupable: false, display: 'flex', renderCell: (params) => , }; const columns: GridColDef<(typeof rows)[number]>[] = [ { field: 'name', headerName: 'Package name', width: 180 }, { field: 'monthlyDownloads', ...sparklineColumnType, headerName: 'Monthly DLs (line)', width: 150, }, { field: 'monthlyDownloadsBar', ...sparklineColumnType, headerName: 'Monthly DLs (bar)', renderCell: (params) => , width: 150, valueGetter: (value, row) => row.monthlyDownloads, }, { field: 'lastMonthDownloads', headerName: 'Last month DLs', type: 'number', valueGetter: (value, row) => row.monthlyDownloads[row.monthlyDownloads.length - 1], width: 150, }, ]; export default function SparklineColumn() { return (
); } const rows = [ { name: 'react-datepicker', monthlyDownloads: [ 469172, 488506, 592287, 617401, 640374, 632751, 668638, 807246, 749198, 944863, 911787, 844815, 992022, 1143838, 1446926, 1267886, 1362511, 1348746, 1560533, 1670690, 1695142, 1916613, 1823306, 1683646, 2025965, 2529989, 3263473, 3296541, 3041524, 2599497, 2719473, 2610351, 2912067, 3079330, 2871077, 2684197, 2852679, 3227844, 3867488, 3582735, 3454135, 3799207, 3813848, 3839009, 4054869, 4319042, 4388671, 4149743, 4519686, 4810266, 5621007, 5260194, 5563038, 5837767, 5342797, 6427653, 6611624, 6532709, 6886198, 6071253, 6730371, 7097963, 8001343, 6867713, 7688481, ], id: 0, }, { name: '@mui/x-date-pickers', monthlyDownloads: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 557488, 1341471, 2044561, 2206438, 2682543, 2772941, 2987705, 3264829, 2972821, 3489759, 3698191, 4410492, 4201780, 4892509, ], id: 1, }, { name: 'flatpickr', monthlyDownloads: [ 166896, 190041, 248686, 226746, 261744, 271890, 332176, 381123, 396435, 495620, 520278, 460839, 704158, 559134, 681089, 712384, 765381, 771374, 851314, 907947, 903675, 1049642, 1003160, 881573, 1072283, 1139115, 1382701, 1395655, 1355040, 1381571, 1495175, 1513409, 1673240, 1772826, 1712051, 1641944, 1718714, 1849475, 2226745, 2104910, 1967886, 2096636, 1991424, 2155674, 2263360, 2261195, 2324734, 2075858, 2297512, 2368925, 2886678, 2543833, 2835623, 2916036, 2638289, 3050516, 2950882, 3042688, 3290024, 2790747, 3196521, 3146755, 3562973, 3082832, 3477021, ], id: 2, }, { name: 'react-day-picker', monthlyDownloads: [ 264651, 311845, 436558, 439385, 520413, 533380, 562363, 533793, 558029, 791126, 649082, 566792, 723451, 737827, 890859, 935554, 1044397, 1022973, 1129827, 1145309, 1195630, 1358925, 1373160, 1172679, 1340106, 1396974, 1623641, 1687545, 1581634, 1550291, 1718864, 1578447, 1618394, 1697784, 1564166, 1400088, 1471853, 1730190, 1994936, 1786010, 1713263, 1839730, 1714299, 1753411, 1885780, 1902870, 1970994, 1762571, 1989425, 2043994, 2476663, 2151717, 2243360, 2371687, 2046381, 2468153, 2514297, 2660758, 2887687, 2337575, 2700261, 2873230, 3323961, 3026604, 3244131, ], id: 3, }, { name: 'react-dates', monthlyDownloads: [ 251871, 262216, 402383, 396459, 378793, 406720, 447538, 451451, 457111, 589821, 640744, 504879, 626099, 662007, 754576, 768231, 833019, 851537, 972306, 1014831, 1027570, 1189068, 1119099, 987244, 1197954, 1310721, 1480816, 1577547, 1854053, 1791831, 1817336, 1757624, 1859245, 1814024, 1925249, 1867506, 1892138, 2001963, 2538000, 2327809, 2277795, 2335804, 2278370, 2258587, 2314794, 2376233, 2315449, 1948923, 2114500, 2208357, 2471023, 2172957, 2349786, 2481612, 2283701, 2534949, 2351510, 2074785, 2170915, 1882137, 2087930, 2423606, 3085474, 2656079, 2861712, ], id: 4, }, { name: '@material-ui/pickers', monthlyDownloads: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 21003, 112544, 223356, 357258, 427403, 592436, 643442, 652000, 851649, 997585, 1237884, 1323019, 1329075, 1446751, 1603441, 1605489, 1770242, 1926553, 1957029, 1917431, 2047824, 2342019, 2952485, 2850314, 2905856, 3145594, 3162610, 3356708, 3574777, 3581429, 3588626, 3215994, 3209791, 3229263, 3577594, 2982893, 3072732, 3083998, 2802316, 3345024, 3224987, 2853866, 2931270, 2419496, 2624119, 2614166, 3072423, 2550430, 2605515, ], id: 5, }, { name: 'react-calendar', monthlyDownloads: [ 13671, 16918, 27272, 34315, 42212, 56369, 64241, 77857, 70680, 91093, 108306, 94734, 132289, 133860, 147706, 158504, 192578, 207173, 220052, 233496, 250091, 285557, 280329, 262382, 330528, 337111, 398561, 452800, 432857, 452775, 541950, 481764, 537173, 585916, 573412, 552463, 582320, 665610, 757420, 733958, 731212, 786886, 793785, 836271, 899076, 950749, 981813, 913076, 1037772, 1111379, 1372103, 1316354, 1353646, 1436614, 1349791, 1542007, 1549215, 1576125, 1701436, 1477188, 1756447, 1804657, 2024066, 1802328, 1975321, ], id: 6, }, { name: 'react-datetime', monthlyDownloads: [ 474506, 514529, 624998, 634955, 693156, 762051, 822194, 999794, 1028527, 1264039, 1074500, 874769, 945614, 841453, 859657, 822025, 886668, 810302, 849949, 872377, 783857, 887114, 789091, 698810, 800283, 789543, 919445, 1026095, 1130903, 1021922, 971668, 922021, 875551, 849529, 891653, 806460, 740611, 804504, 1008750, 1080174, 917512, 886872, 874670, 853764, 862825, 894367, 919854, 807459, 858222, 858151, 967551, 897111, 902405, 944057, 879880, 1090124, 1081206, 1026493, 1002294, 832895, 955662, 972831, 1166432, 1042367, 1025499, ], id: 7, }, { name: 'react-date-picker', monthlyDownloads: [ 49274, 48553, 64322, 58823, 59113, 66912, 70695, 74530, 66425, 84803, 86193, 69178, 94987, 89205, 105340, 98078, 112268, 111998, 122224, 127661, 133198, 138867, 128836, 120011, 158852, 154510, 175291, 197496, 224817, 194683, 220130, 210720, 233037, 252119, 240970, 233944, 256490, 298853, 340486, 318831, 317291, 335995, 336665, 343706, 356435, 376861, 379366, 355358, 408157, 425652, 499923, 471759, 512219, 511044, 470863, 531581, 534128, 531059, 613792, 527997, 594540, 637346, 788377, 721212, 644692, ], id: 8, }, { name: '@react-spectrum/datepicker', monthlyDownloads: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164, 691, 402, 1239, 1536, 1853, 2163, 4151, 9644, 15667, 16426, 17786, 21804, 21358, 24062, 30870, 34053, 35400, 37834, ], id: 9, }, ]; ``` ## Date pickers By default, the Data Grid uses native browser inputs for editing `date` and `dateTime` columns. While the [MUI X Date and Time Pickers](/x/react-date-pickers/) are not supported by the Data Grid out of the box yet, you can integrate them by creating [custom edit components](/x/react-data-grid/editing/custom-edit-component/) and [custom filter operators](/x/react-data-grid/filtering/customization/#create-a-custom-operator). The example below uses `@mui/x-date-pickers` for both `date` and `dateTime` column types: ```tsx import * as React from 'react'; import { DataGrid, GridColDef, GridRowsProp, useGridApiContext, GridRenderEditCellParams, GRID_DATE_COL_DEF, GRID_DATETIME_COL_DEF, GridColTypeDef, GridFilterInputValueProps, getGridDateOperators, } from '@mui/x-data-grid'; import { randomCreatedDate, randomTraderName, randomUpdatedDate, } from '@mui/x-data-grid-generator'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import { enUS as locale } from 'date-fns/locale'; import { format } from 'date-fns/format'; import useEnhancedEffect from '@mui/utils/useEnhancedEffect'; /** * `date` column */ const dateColumnType: GridColTypeDef = { ...GRID_DATE_COL_DEF, resizable: false, renderEditCell: (params) => { return ; }, filterOperators: getGridDateOperators(false).map((item) => ({ ...item, InputComponent: GridFilterDateInput, InputComponentProps: { showTime: false }, })), valueFormatter: (value) => { if (value) { return format(value, 'MM/dd/yyyy', { locale }); } return ''; }, }; function GridEditDateCell({ id, field, value, colDef, hasFocus, }: GridRenderEditCellParams) { const apiRef = useGridApiContext(); const inputRef = React.useRef(null); const Component = colDef.type === 'dateTime' ? DateTimePicker : DatePicker; const handleChange = (newValue: unknown) => { apiRef.current.setEditCellValue({ id, field, value: newValue }); }; useEnhancedEffect(() => { if (hasFocus) { inputRef.current!.focus(); } }, [hasFocus]); return ( ); } function GridFilterDateInput( props: GridFilterInputValueProps & { showTime?: boolean }, ) { const { item, showTime, applyValue, apiRef } = props; const Component = showTime ? DateTimePicker : DatePicker; const handleFilterChange = (newValue: unknown) => { applyValue({ ...item, value: newValue }); }; return ( ); } /** * `dateTime` column */ const dateTimeColumnType: GridColTypeDef = { ...GRID_DATETIME_COL_DEF, resizable: false, renderEditCell: (params) => { return ; }, filterOperators: getGridDateOperators(true).map((item) => ({ ...item, InputComponent: GridFilterDateInput, InputComponentProps: { showTime: true }, })), valueFormatter: (value) => { if (value) { return format(value, 'MM/dd/yyyy hh:mm a', { locale }); } return ''; }, }; const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 180, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', ...dateColumnType, headerName: 'Date Created', width: 180, editable: true, }, { field: 'lastLogin', ...dateTimeColumnType, headerName: 'Last Login', width: 230, editable: true, }, ]; export default function EditingWithDatePickers() { return (
); } const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` :::info You can change the date format by importing different locale (`en-US` locale is used in the example above). See [Localization](/x/react-date-pickers/localization/) for more information. ::: ## Full example The demo below shows the most common custom column renderers used across our demos. :::success You can copy the column definitions and custom cell renderers from the demo source code. All column definitions are located in the main component file, while each cell renderer is in a separate file. ::: ```tsx import { randomColor, randomEmail, randomInt, randomName, randomArrayItem, random, } from '@mui/x-data-grid-generator'; import { DataGrid, GridColDef, gridStringOrNumberComparator, } from '@mui/x-data-grid'; import { renderAvatar } from './cell-renderers/avatar'; import { renderEmail } from './cell-renderers/email'; import { renderEditRating, renderRating } from './cell-renderers/rating'; import { COUNTRY_ISO_OPTIONS, CountryIsoOption, renderCountry, renderEditCountry, } from './cell-renderers/country'; import { renderSparkline } from './cell-renderers/sparkline'; import { renderEditProgress, renderProgress } from './cell-renderers/progress'; import { renderEditStatus, renderStatus, STATUS_OPTIONS, } from './cell-renderers/status'; import { INCOTERM_OPTIONS, renderEditIncoterm, renderIncoterm, } from './cell-renderers/incoterm'; const columns: GridColDef<(typeof rows)[number]>[] = [ { field: 'name', headerName: 'Name', width: 120, editable: true, }, { field: 'avatar', headerName: 'Avatar', display: 'flex', renderCell: renderAvatar, valueGetter: (value, row) => row.name == null || row.avatar == null ? null : { name: row.name, color: row.avatar }, sortable: false, filterable: false, } as GridColDef, { field: 'email', headerName: 'Email', renderCell: renderEmail, width: 150, editable: true, }, { field: 'rating', headerName: 'Rating', display: 'flex', renderCell: renderRating, renderEditCell: renderEditRating, width: 180, type: 'number', editable: true, availableAggregationFunctions: ['avg', 'min', 'max', 'size'], }, { field: 'country', headerName: 'Country', type: 'singleSelect', valueOptions: COUNTRY_ISO_OPTIONS, valueFormatter: (value: CountryIsoOption) => value?.label, renderCell: renderCountry, renderEditCell: renderEditCountry, sortComparator: (v1, v2, param1, param2) => gridStringOrNumberComparator(v1.label, v2.label, param1, param2), width: 150, editable: true, } as GridColDef, { field: 'salary', headerName: 'Salary', type: 'number', valueFormatter: (value?: number) => { if (!value || typeof value !== 'number') { return value; } return `$${value.toLocaleString()}`; }, editable: true, }, { field: 'monthlyActivity', headerName: 'Monthly activity', type: 'custom', resizable: false, filterable: false, sortable: false, editable: false, groupable: false, display: 'flex', renderCell: renderSparkline, width: 150, valueGetter: (value, row) => row.monthlyActivity, }, { field: 'budget', headerName: 'Budget left', renderCell: renderProgress, renderEditCell: renderEditProgress, availableAggregationFunctions: ['min', 'max', 'avg', 'size'], type: 'number', width: 120, editable: true, }, { field: 'status', headerName: 'Status', renderCell: renderStatus, renderEditCell: renderEditStatus, type: 'singleSelect', valueOptions: STATUS_OPTIONS, width: 150, editable: true, }, { field: 'incoTerm', headerName: 'Incoterm', renderCell: renderIncoterm, renderEditCell: renderEditIncoterm, type: 'singleSelect', valueOptions: INCOTERM_OPTIONS, editable: true, }, ]; const rows = Array.from({ length: 10 }, (_, index) => ({ id: index, name: randomName({}, {}), avatar: randomColor(), email: randomEmail(), rating: randomInt(1, 5), country: randomArrayItem(COUNTRY_ISO_OPTIONS), salary: randomInt(35000, 80000), monthlyActivity: Array.from({ length: 30 }, () => randomInt(1, 25)), budget: random(0, 1).toPrecision(), status: randomArrayItem(STATUS_OPTIONS), incoTerm: randomArrayItem(INCOTERM_OPTIONS), })); export default function CustomColumnFullExample() { return (
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-date-pickers/custom-components.md --- productId: x-date-pickers title: Date and Time Pickers - Custom slots and subcomponents components: DateTimePickerTabs, PickersActionBar, DatePickerToolbar, TimePickerToolbar, DateTimePickerToolbar, PickerDay2, DateRangePickerDay2, PickersCalendarHeader, PickersRangeCalendarHeader, PickersShortcuts, DateRangePickerToolbar, MonthCalendar, YearCalendar, DateCalendar --- # Custom slots and subcomponents Learn how to override parts of the Date and Time Pickers. :::info The components that can be customized are listed under `slots` section in Date and Time Pickers [API Reference](/x/api/date-pickers/). For example, check [available Date Picker slots](/x/api/date-pickers/date-picker/#slots). ::: :::success See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Action bar ### Component props The action bar is available on all picker components. By default, it contains no action on desktop, and the actions **Cancel** and **Accept** on mobile. You can override the actions displayed by passing the `actions` prop to the `actionBar` within `slotProps`, as shown here: ```jsx ({ actions: pickerVariant === 'desktop' ? [] : ['clear'], }), }} /> ``` In the example below, the action bar contains only one button, which resets the selection to today's date: ```tsx import dayjs from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; export default function ActionBarComponentProps() { return ( ); } ``` #### Available actions The built-in `` component supports the following different actions: | Action | Behavior | | :------------- | :------------------------------------------------------------------------------- | | `accept` | Accept the current value and close the picker view. | | `cancel` | Reset to the last accepted date and close the picker view. | | `clear` | Reset to the empty value and close the picker view. | | `next` | Go to the next step in the value picking process. | | `nextOrAccept` | Shows the `accept` or `next` action depending on the value picking process step. | | `today` | Reset to today's date (and time if relevant) and close the picker view. | ### Component If you need to customize the date picker beyond the options described above, you can provide a custom component. This can be used in combination with `slotProps`. In the example below, the actions are the same as in the section above, but they are rendered inside a menu: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import useId from '@mui/utils/useId'; import Button from '@mui/material/Button'; import Menu from '@mui/material/Menu'; import MenuItem from '@mui/material/MenuItem'; import DialogActions from '@mui/material/DialogActions'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; import { PickersActionBarProps } from '@mui/x-date-pickers/PickersActionBar'; import { usePickerContext, usePickerTranslations } from '@mui/x-date-pickers/hooks'; function CustomActionBar(props: PickersActionBarProps) { const { actions, className } = props; const translations = usePickerTranslations(); const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges, goToNextStep, hasNextStep, } = usePickerContext(); const [anchorEl, setAnchorEl] = React.useState(null); const open = Boolean(anchorEl); const id = useId(); if (actions == null || actions.length === 0) { return null; } const menuItems = actions?.map((actionType) => { switch (actionType) { case 'clear': return ( { clearValue(); setAnchorEl(null); }} key={actionType} > {translations.clearButtonLabel} ); case 'cancel': return ( { setAnchorEl(null); cancelValueChanges(); }} key={actionType} > {translations.cancelButtonLabel} ); case 'accept': return ( { setAnchorEl(null); acceptValueChanges(); }} key={actionType} > {translations.okButtonLabel} ); case 'today': return ( { setAnchorEl(null); setValueToToday(); }} key={actionType} > {translations.todayButtonLabel} ); case 'next': return ( { setAnchorEl(null); goToNextStep(); }} key={actionType} > {translations.nextStepButtonLabel} ); case 'nextOrAccept': if (hasNextStep) { return ( { setAnchorEl(null); goToNextStep(); }} key={actionType} > {translations.nextStepButtonLabel} ); } return ( { setAnchorEl(null); acceptValueChanges(); }} key={actionType} > {translations.okButtonLabel} ); default: return null; } }); return ( setAnchorEl(null)} MenuListProps={{ 'aria-labelledby': `picker-actions-${id}`, }} > {menuItems} ); } export default function ActionBarComponent() { return ( ); } ``` ## Tabs Tabs are available on all date time picker components. They let users switch between date and time interfaces. ### Component props You can override the icons displayed by passing props to the `tabs` within `slotProps`, as shown here: ```jsx , timeIcon: , }, }} /> ``` By default, the tabs are `hidden` on desktop, and `visible` on mobile. This behavior can be overridden by setting the `hidden` prop: ```jsx ``` ### Component If you need to customize the date time picker beyond the options described above, you can provide a custom component. This can be used in combination with `slotProps`. In the example below, the tabs are using different icons and have an additional component: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import Box from '@mui/material/Box'; import { StaticDateTimePicker } from '@mui/x-date-pickers/StaticDateTimePicker'; import { DateTimePickerTabs, DateTimePickerTabsProps, } from '@mui/x-date-pickers/DateTimePicker'; import LightModeIcon from '@mui/icons-material/LightMode'; import AcUnitIcon from '@mui/icons-material/AcUnit'; function CustomTabs(props: DateTimePickerTabsProps) { return ( ); } export default function Tabs() { return ( , timeIcon: , }, }} /> ); } ``` ## Toolbar The toolbar is available on all date time picker components. It displays the current values and lets users switch between different views. ### Component props You can customize how the toolbar displays the current value with `toolbarFormat`. By default, empty values are replaced by `__`. This can be modified by using `toolbarPlaceholder` props. By default, the toolbar is `hidden` on desktop, and `visible` on mobile. This behavior can be overridden by setting the `hidden` prop: ```jsx ``` ### Component Each component comes with its own toolbar (`DatePickerToolbar`, `TimePickerToolbar`, and `DateTimePickerToolbar`) that you can reuse and customize. ```tsx import dayjs from 'dayjs'; import Box from '@mui/material/Box'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; import RocketLaunchIcon from '@mui/icons-material/RocketLaunch'; import { DatePickerToolbar, DatePickerToolbarProps, } from '@mui/x-date-pickers/DatePicker'; function CustomToolbar(props: DatePickerToolbarProps) { return ( ); } export default function ToolbarComponent() { return ( ); } ``` ## Calendar header The calendar header is available on any component that renders a calendar to select a date or a range of dates. It lets users navigate through months and switch to the month and year views when available. ### Component props You can pass props to the calendar header as shown below: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function CalendarHeaderComponentProps() { return ( ); } ``` ### Component You can pass a custom component to replace the header, as shown below: ```tsx import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import IconButton from '@mui/material/IconButton'; import ChevronLeft from '@mui/icons-material/ChevronLeft'; import ChevronRight from '@mui/icons-material/ChevronRight'; import KeyboardDoubleArrowLeftIcon from '@mui/icons-material/KeyboardDoubleArrowLeft'; import KeyboardDoubleArrowRightIcon from '@mui/icons-material/KeyboardDoubleArrowRight'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { PickersCalendarHeaderProps } from '@mui/x-date-pickers/PickersCalendarHeader'; const CustomCalendarHeaderRoot = styled('div')({ display: 'flex', justifyContent: 'space-between', padding: '8px 16px', alignItems: 'center', }); function CustomCalendarHeader(props: PickersCalendarHeaderProps) { const { currentMonth, onMonthChange } = props; const selectNextMonth = () => onMonthChange(currentMonth.add(1, 'month')); const selectNextYear = () => onMonthChange(currentMonth.add(1, 'year')); const selectPreviousMonth = () => onMonthChange(currentMonth.subtract(1, 'month')); const selectPreviousYear = () => onMonthChange(currentMonth.subtract(1, 'year')); return ( {currentMonth.format('MMMM YYYY')} ); } export default function CalendarHeaderComponent() { return ( ); } ``` When used with a date range component, you receive three additional props to let you handle scenarios where multiple months are rendered: - `calendars`: The number of calendars rendered - `month`: The month used for the header being rendered - `monthIndex`: The index of the month used for the header being rendered The demo below shows how to navigate the months two by two: ```tsx import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import ChevronLeft from '@mui/icons-material/ChevronLeft'; import ChevronRight from '@mui/icons-material/ChevronRight'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; import { PickersRangeCalendarHeaderProps } from '@mui/x-date-pickers-pro/PickersRangeCalendarHeader'; const CustomCalendarHeaderRoot = styled('div')({ display: 'flex', justifyContent: 'space-between', padding: '8px 16px', alignItems: 'center', }); function CustomCalendarHeader(props: PickersRangeCalendarHeaderProps) { const { currentMonth, onMonthChange, month, calendars, monthIndex } = props; const selectNextMonth = () => onMonthChange(currentMonth.add(calendars, 'month')); const selectPreviousMonth = () => onMonthChange(currentMonth.subtract(calendars, 'month')); return ( {month.format('MMMM YYYY')} ); } export default function CalendarHeaderComponentRange() { return ( ); } ``` ## Year button This button lets users change the selected year in the `year` view. ### Component props You can pass props to the year button as shown below: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function YearButtonComponentProps() { return ( ); } ``` ### Component You can pass a custom component to replace the year button, as shown below: ```tsx import { styled } from '@mui/material/styles'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; const CustomYearButton = styled('button')({ height: 36, width: 72, }); export default function YearButtonComponent() { return ( ); } ``` ## Day :::info The examples below use the new components, which might need further changes on your side to adjust to the new structure. Be sure to check that any custom styling configuration is compatible with the new structure. ::: The `day` slot lets users change the selected day in the calendar. You can use the `` and `` components to replace the day slot with a simplified DOM structure reduced to a single element. The `::before` pseudo element is used to create the highlighting effect on the days within the selected range. The `::after` pseudo element is used to create the previewing effect on hover. This new structure provides a better theming and customization experience. ```tsx import Box from '@mui/material/Box'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; import { PickerDay2 } from '@mui/x-date-pickers/PickerDay2'; import { DateRangePickerDay2 } from '@mui/x-date-pickers-pro/DateRangePickerDay2'; export default function PickerDay2Demo() { return ( ); } ``` Use the `--PickerDay-horizontalMargin` and `--PickerDay-size` CSS variables to easily customize the dimensions and spacing of the day slot. ```tsx import Box from '@mui/material/Box'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; import { PickerDay2, pickerDay2Classes } from '@mui/x-date-pickers/PickerDay2'; export default function PickerDay2DemoCSSVars() { return ( ); } ``` Customize the look and feel by creating a custom theme with `styleOverrides`. ```tsx import { ThemeProvider, createTheme, useTheme } from '@mui/material/styles'; import Box from '@mui/material/Box'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; import { DateRangePickerDay2 } from '@mui/x-date-pickers-pro/DateRangePickerDay2'; import { getDensePickerTheme } from './getDensePickerTheme'; export default function PickerDay2DemoCustomTheme() { const currentTheme = useTheme(); const theme = createTheme(getDensePickerTheme(currentTheme.palette.mode)); return ( ); } ``` ## Month button This button lets users change the selected month in the `month` view. :::success You can learn more about how to enable the `month` view on the [`DateCalendar` doc page](/x/react-date-pickers/date-calendar/#views). ::: ### Component props You can pass props to the month button as shown below: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function MonthButtonComponentProps() { return ( ); } ``` ### Component You can pass a custom component to replace the month button, as shown below: ```tsx import { styled } from '@mui/material/styles'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; const CustomMonthButton = styled('button')({ height: 36, width: 72, }); export default function MonthButtonComponent() { return ( ); } ``` ## Arrow switcher The following slots let you customize how to render the buttons and icons for an arrow switcher: the component used to navigate to the "Previous" and "Next" steps of the picker: `PreviousIconButton`, `NextIconButton`, `LeftArrowIcon`, `RightArrowIcon`. ### Component props You can pass props to the icons and buttons as shown below: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import Stack from '@mui/material/Stack'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import ToggleButton from '@mui/material/ToggleButton'; import Box from '@mui/material/Box'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { TimeClock, TimeClockSlotProps } from '@mui/x-date-pickers/TimeClock'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; const slotProps: TimeClockSlotProps = { leftArrowIcon: { fontSize: 'large' }, rightArrowIcon: { fontSize: 'large' }, previousIconButton: { size: 'medium', }, nextIconButton: { size: 'medium', }, }; type CurrentComponent = 'date' | 'time' | 'dateRange'; export default function ArrowSwitcherComponentProps() { const [currentComponent, setCurrentComponent] = React.useState('date'); const handleCurrentComponentChange = ( event: React.MouseEvent, nextCurrentComponent: CurrentComponent | null, ) => { if (nextCurrentComponent !== null) { setCurrentComponent(nextCurrentComponent); } }; return ( date time date range {currentComponent === 'date' && ( )} {currentComponent === 'time' && ( )} {currentComponent === 'dateRange' && ( )} ); } ``` ### Component You can pass custom components to replace the icons, as shown below: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import Stack from '@mui/material/Stack'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Box from '@mui/material/Box'; import ArrowLeft from '@mui/icons-material/ArrowLeft'; import ArrowRight from '@mui/icons-material/ArrowRight'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { TimeClock, TimeClockProps } from '@mui/x-date-pickers/TimeClock'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; const slots: TimeClockProps['slots'] = { leftArrowIcon: ArrowLeft, rightArrowIcon: ArrowRight, }; type CurrentComponent = 'date' | 'time' | 'dateRange'; export default function ArrowSwitcherComponent() { const [currentComponent, setCurrentComponent] = React.useState('date'); const handleCurrentComponentChange = ( event: React.MouseEvent, nextCurrentComponent: CurrentComponent | null, ) => { if (nextCurrentComponent !== null) { setCurrentComponent(nextCurrentComponent); } }; return ( date time date range {currentComponent === 'date' && ( )} {currentComponent === 'time' && ( )} {currentComponent === 'dateRange' && ( )} ); } ``` ## Access date adapter In case you are building a custom component that needs to work with multiple date libraries, you can access the date adapter instance by using the `usePickerAdapter` hook. This hook returns the date adapter instance used by the picker, which you can use to format dates, parse strings, and perform other date-related operations. :::success If your application uses a single date library, prefer using the date library directly in your components to avoid unnecessary complexity and possible breaking changes. ::: ```tsx import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import IconButton from '@mui/material/IconButton'; import ChevronLeft from '@mui/icons-material/ChevronLeft'; import ChevronRight from '@mui/icons-material/ChevronRight'; import KeyboardDoubleArrowLeftIcon from '@mui/icons-material/KeyboardDoubleArrowLeft'; import KeyboardDoubleArrowRightIcon from '@mui/icons-material/KeyboardDoubleArrowRight'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { PickersCalendarHeaderProps } from '@mui/x-date-pickers/PickersCalendarHeader'; import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns'; import { usePickerAdapter } from '@mui/x-date-pickers/hooks'; const CustomCalendarHeaderRoot = styled('div')({ display: 'flex', justifyContent: 'space-between', padding: '8px 16px', alignItems: 'center', }); function CustomCalendarHeader(props: PickersCalendarHeaderProps) { const adapter = usePickerAdapter(); const { currentMonth, onMonthChange, format = `${adapter.formats.month} ${adapter.formats.year}`, } = props; const selectNextMonth = () => onMonthChange(adapter.addMonths(currentMonth, 1)); const selectNextYear = () => onMonthChange(adapter.addYears(currentMonth, 1)); const selectPreviousMonth = () => onMonthChange(adapter.addMonths(currentMonth, -1)); const selectPreviousYear = () => onMonthChange(adapter.addYears(currentMonth, -1)); return ( {adapter.formatByString(currentMonth, format)} ); } export default function UsePickerAdapter() { return ( ); } ``` ## Shortcuts You can add shortcuts to every Picker component. For more information, check the [dedicated page](/x/react-date-pickers/shortcuts/). --- # Source: https://mui.com/x/react-date-pickers/custom-field.md --- productId: x-date-pickers title: Date and Time Pickers - Custom field githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' components: PickersSectionList, PickersTextField --- # Custom field The Date and Time Pickers let you customize the field by passing props or custom components. :::success See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Customize the default field ### Customize the `TextField` You can use the `textField` slot to pass custom props to the `TextField`: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function TextFieldSlotProps() { return ( ); } ``` ### Change the separator of range fields [](/x/introduction/licensing/#pro-plan 'Pro plan') You can use the `dateSeparator` prop to change the separator rendered between the start and end dates: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; export default function RangeFieldDateSeparator() { return ( ); } ``` ### Change the format density You can control the field format spacing using the `formatDensity` prop. Setting `formatDensity` to `"spacious"` adds space before and after each `/`, `-` and `.` character. ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; export default function FieldFormatDensity() { return ( ); } ``` ## Multi input range field [](/x/introduction/licensing/#pro-plan 'Pro plan') ### Usage inside a range picker You can pass the multi input fields to the range picker to use it for keyboard editing: ```tsx import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; export default function MultiInputDateRangePicker() { return ( ); } ``` If you want to create a wrapper around the field, make sure to set the `fieldType` static property to `'multi-input'`. Otherwise, the picker will throw an error because it won't know how to adapt to this custom field: ```tsx import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { MultiInputDateRangeField, MultiInputDateRangeFieldProps, } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; function WrappedMultiInputDateRangeField( props: MultiInputDateRangeFieldProps, ) { return ; } WrappedMultiInputDateRangeField.fieldType = 'multi-input'; export default function MultiInputDateRangePickerWrapped() { return ( ); } ``` ### Customize the `start` and `end` fields differently You can pass conditional props to the `textField` slot to customize the input styling based on the `position`. ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; import { FieldOwnerState } from '@mui/x-date-pickers/models'; export default function MultiInputFieldTextFieldProps() { return ( ({ color: position === 'start' ? 'success' : 'warning', focused: true, }), }} defaultValue={[dayjs('2022-04-17'), null]} /> ({ color: position === 'start' ? 'success' : 'warning', focused: true, }), }} slots={{ field: MultiInputDateRangeField }} defaultValue={[dayjs('2022-04-17'), null]} /> ); } ``` ### Customize the separator You can use the `separator` slot to pass custom props to the `Typography` rendered between the two Text Fields: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; export default function MultiInputFieldSeparatorSlotProps() { return ( ); } ``` :::success When used inside a picker, the `separator` slot is not available directly and must be accessed using `slotProps.field.slotProps.separator`. ::: ## With Material UI ### Wrapping `PickersTextField` You can import the `PickersTextField` component to create custom wrappers: ```tsx import * as React from 'react'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { PickersTextField, PickersTextFieldProps, } from '@mui/x-date-pickers/PickersTextField'; import { DateField } from '@mui/x-date-pickers/DateField'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; const MyPickersTextField = React.forwardRef( (props: PickersTextFieldProps, ref: React.Ref) => ( ), ); export default function MaterialV7FieldWrapped() { return ( ); } ``` :::success This approach is only recommended if you need complex customizations on your `PickersTextField`. If you just need to set some default props, you can use [the `slotProps` prop](/x/react-date-pickers/custom-field/#customize-the-textfield). ::: ### Using Material `TextField` Pass the `enableAccessibleFieldDOMStructure={false}` to any Field or Picker component to use an `` for the editing instead of the new accessible DOM structure: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField } from '@mui/x-date-pickers/DateField'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function MaterialV6Field() { return ( ); } ``` :::warning The non-accessible DOM structure will be deprecated in a follow-up minor version and removed in `v9.x`. If you are unable to migrate for some reason, please open an issue to describe what is missing from the new DOM structure so that we can improve it before dropping the old one. ::: ## With another Design System ### Using a custom input :::warning You will need to use a component that supports the `sx` prop as a wrapper for your input to be able to benefit from the **hover** and **focus** behavior of the clear button. You will have access to the `clearable` and `onClear` props using native HTML elements, but the **focus** and **hover** behavior depends on styles applied via the `sx` prop. ::: ```tsx import useForkRef from '@mui/utils/useForkRef'; import { styled } from '@mui/material/styles'; import { CalendarIcon, ClearIcon } from '@mui/x-date-pickers/icons'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker, DatePickerFieldProps, DatePickerProps, } from '@mui/x-date-pickers/DatePicker'; import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField'; import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList'; import { usePickerContext } from '@mui/x-date-pickers/hooks'; const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({ display: 'flex', alignItems: 'center', '& .MuiInputAdornment-root': { height: 'auto', }, }); const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content' })( { border: '1px solid grey', fontSize: 13.33333, lineHeight: 'normal', padding: '1px 2px', whiteSpace: 'nowrap', }, ); const BrowserIconButton = styled('button', { name: 'BrowserField', slot: 'IconButton', })({ backgroundColor: 'transparent', border: 0, cursor: 'pointer', '&:hover, &:focus': { backgroundColor: 'rgba(0, 0, 0, 0.04)', }, }); function BrowserDateField(props: DatePickerFieldProps) { const fieldResponse = useDateField(props); const { // Should be ignored enableAccessibleFieldDOMStructure, // Should be passed to the PickersSectionList component elements, sectionListRef, contentEditable, onFocus, onBlur, tabIndex, onInput, onPaste, onKeyDown, // Should be passed to the button that opens the picker openPickerAriaLabel, // Can be passed to a hidden element onChange, value, // Can be passed to the button that clears the value onClear, clearable, // Can be used to style the component areAllSectionsEmpty, disabled, readOnly, focused, error, // The rest can be passed to the root element ...other } = fieldResponse; const pickerContext = usePickerContext(); const handleRef = useForkRef(pickerContext.triggerRef, pickerContext.rootRef); return ( {clearable && value && ( )} pickerContext.setOpen((prev) => !prev)} sx={{ marginLeft: 1 }} aria-label={openPickerAriaLabel} > ); } function BrowserDatePicker(props: DatePickerProps) { return ( ); } export default function BrowserV7Field() { return ( ); } ``` ```tsx import useForkRef from '@mui/utils/useForkRef'; import { styled } from '@mui/material/styles'; import { ClearIcon, DateRangeIcon } from '@mui/x-date-pickers/icons'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker, DateRangePickerFieldProps, DateRangePickerProps, } from '@mui/x-date-pickers-pro/DateRangePicker'; import { unstable_useSingleInputDateRangeField as useSingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { usePickerContext } from '@mui/x-date-pickers/hooks'; import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList'; const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({ display: 'flex', alignItems: 'center', '& .MuiInputAdornment-root': { height: 'auto', }, }); const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content' })( { border: '1px solid grey', fontSize: 13.33333, lineHeight: 'normal', padding: '1px 2px', whiteSpace: 'nowrap', }, ); const BrowserIconButton = styled('button', { name: 'BrowserField', slot: 'IconButton', })({ backgroundColor: 'transparent', border: 0, cursor: 'pointer', '&:hover, &:focus': { backgroundColor: 'rgba(0, 0, 0, 0.04)', }, }); interface BrowserSingleInputDateRangeFieldProps extends DateRangePickerFieldProps {} function BrowserSingleInputDateRangeField( props: BrowserSingleInputDateRangeFieldProps, ) { const fieldResponse = useSingleInputDateRangeField(props); const { // Should be ignored enableAccessibleFieldDOMStructure, // Should be passed to the PickersSectionList component elements, sectionListRef, contentEditable, onFocus, onBlur, tabIndex, onInput, onPaste, onKeyDown, // Should be passed to the button that opens the picker openPickerAriaLabel, // Can be passed to a hidden element onChange, value, // Can be passed to the button that clears the value onClear, clearable, // Can be used to style the component areAllSectionsEmpty, disabled, readOnly, focused, error, // The rest can be passed to the root element ...other } = fieldResponse; const pickerContext = usePickerContext(); const handleRef = useForkRef(pickerContext.triggerRef, pickerContext.rootRef); return ( {clearable && value && ( )} pickerContext.setOpen((prev) => !prev)} aria-label={openPickerAriaLabel} sx={{ marginLeft: 1 }} > ); } BrowserSingleInputDateRangeField.fieldType = 'single-input'; function BrowserSingleInputDateRangePicker(props: DateRangePickerProps) { return ( ); } export default function BrowserV7SingleInputRangeField() { return ( ); } ``` ```tsx import * as React from 'react'; import useSlotProps from '@mui/utils/useSlotProps'; import { styled } from '@mui/material/styles'; import Stack from '@mui/material/Stack'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { usePickerContext, useSplitFieldProps } from '@mui/x-date-pickers/hooks'; import { DateRangePicker, DateRangePickerFieldProps, DateRangePickerProps, } from '@mui/x-date-pickers-pro/DateRangePicker'; import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers'; import { unstable_useMultiInputRangeField as useMultiInputRangeField, UseMultiInputRangeFieldTextFieldProps, } from '@mui/x-date-pickers-pro/hooks'; import { Unstable_PickersSectionList as PickersSectionList } from '@mui/x-date-pickers/PickersSectionList'; import { MultiInputFieldSlotTextFieldProps, MultiInputFieldRefs, } from '@mui/x-date-pickers-pro/models'; const BrowserFieldRoot = styled('div', { name: 'BrowserField', slot: 'Root' })({ display: 'flex', alignItems: 'center', }); const BrowserFieldContent = styled('div', { name: 'BrowserField', slot: 'Content' })( { border: '1px solid grey', fontSize: 13.33333, lineHeight: 'normal', padding: '1px 2px', whiteSpace: 'nowrap', }, ); interface BrowserTextFieldProps extends UseMultiInputRangeFieldTextFieldProps< true, React.HTMLAttributes > { triggerRef?: React.Ref; } function BrowserTextField(props: BrowserTextFieldProps) { const { // Should be ignored enableAccessibleFieldDOMStructure, // Should be passed to the PickersSectionList component elements, sectionListRef, contentEditable, onFocus, onBlur, tabIndex, onInput, onPaste, onKeyDown, // Can be passed to a hidden element onChange, value, // Can be used to style the component areAllSectionsEmpty, disabled, readOnly, focused, error, triggerRef, // The rest can be passed to the root element ...other } = props; return ( ); } interface BrowserMultiInputDateRangeFieldProps extends Omit, MultiInputFieldRefs { slotProps: { textField: any; }; } function BrowserMultiInputDateRangeField( props: BrowserMultiInputDateRangeFieldProps, ) { const manager = useDateRangeManager(); const pickerContext = usePickerContext(); const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const { slotProps, ...otherForwardedProps } = forwardedProps; const startTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, ownerState: { position: 'start' } as any, }) as MultiInputFieldSlotTextFieldProps; const endTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, ownerState: { position: 'end' } as any, }) as MultiInputFieldSlotTextFieldProps; const fieldResponse = useMultiInputRangeField({ manager, internalProps, startTextFieldProps, endTextFieldProps, rootProps: { ref: pickerContext.rootRef, spacing: 2, direction: 'row' as const, overflow: 'auto', ...otherForwardedProps, }, }); return ( ); } BrowserMultiInputDateRangeField.fieldType = 'multi-input'; function BrowserDateRangePicker(props: DateRangePickerProps) { return ( ); } export default function BrowserV7MultiInputRangeField() { return ( ); } ``` ### Using Joy UI You can use the [Joy UI](https://mui.com/joy-ui/getting-started/) components instead of the Material UI ones: ```tsx import * as React from 'react'; import { ThemeProvider, createTheme, useColorScheme as useMaterialColorScheme, } from '@mui/material/styles'; import { extendTheme as extendJoyTheme, useColorScheme, CssVarsProvider, THEME_ID, } from '@mui/joy/styles'; import Input from '@mui/joy/Input'; import IconButton from '@mui/joy/IconButton'; import FormControl from '@mui/joy/FormControl'; import FormLabel from '@mui/joy/FormLabel'; import { createSvgIcon } from '@mui/joy/utils'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker, DatePickerFieldProps, DatePickerProps, } from '@mui/x-date-pickers/DatePicker'; import { unstable_useDateField as useDateField } from '@mui/x-date-pickers/DateField'; import { usePickerContext } from '@mui/x-date-pickers/hooks'; const CalendarIcon = createSvgIcon( , 'Calendar', ); const ClearIcon = createSvgIcon( , 'Clear', ); const joyTheme = extendJoyTheme(); function JoyDateField(props: DatePickerFieldProps) { const fieldResponse = useDateField(props); const { // Should be ignored enableAccessibleFieldDOMStructure, // Should be passed to the button that opens the picker openPickerAriaLabel, // Can be passed to the button that clears the value onClear, clearable, // Can be used to style the component disabled, readOnly, error, inputRef, // The rest can be passed to the root element id, value, ...other } = fieldResponse; const pickerContext = usePickerContext(); return ( {pickerContext.label} {clearable && value && ( )} pickerContext.setOpen((prev) => !prev)} aria-label={openPickerAriaLabel} > } slotProps={{ input: { ref: inputRef }, }} {...other} value={value} ref={pickerContext.triggerRef} /> ); } function JoyDatePicker(props: DatePickerProps) { return ( ); } /** * This component is for syncing the theme mode of this demo with the MUI docs mode. * You might not need this component in your project. */ function SyncThemeMode() { const { setMode } = useColorScheme(); const { mode } = useMaterialColorScheme(); React.useEffect(() => { if (mode) { setMode(mode); } }, [mode, setMode]); return null; } const theme = createTheme({ colorSchemes: { light: true, dark: true } }); export default function JoyV6Field() { return ( ); } ``` ```tsx import * as React from 'react'; import { ThemeProvider, createTheme, useColorScheme as useMaterialColorScheme, } from '@mui/material/styles'; import { extendTheme as extendJoyTheme, useColorScheme, CssVarsProvider, THEME_ID, } from '@mui/joy/styles'; import { createSvgIcon } from '@mui/joy/utils'; import Input from '@mui/joy/Input'; import FormControl from '@mui/joy/FormControl'; import FormLabel from '@mui/joy/FormLabel'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker, DateRangePickerFieldProps, DateRangePickerProps, } from '@mui/x-date-pickers-pro/DateRangePicker'; import { unstable_useSingleInputDateRangeField as useSingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { usePickerContext } from '@mui/x-date-pickers/hooks'; import IconButton from '@mui/joy/IconButton'; const DateRangeIcon = createSvgIcon( , 'DateRange', ); const ClearIcon = createSvgIcon( , 'Clear', ); const joyTheme = extendJoyTheme(); function JoySingleInputDateRangeField(props: DateRangePickerFieldProps) { const fieldResponse = useSingleInputDateRangeField(props); const { // Should be ignored enableAccessibleFieldDOMStructure, // Should be passed to the button that opens the picker openPickerAriaLabel, // Can be passed to the button that clears the value onClear, clearable, disabled, id, value, inputRef, ...other } = fieldResponse; const pickerContext = usePickerContext(); return ( {pickerContext.label} {clearable && value && ( )} pickerContext.setOpen((prev) => !prev)} aria-label={openPickerAriaLabel} > } slotProps={{ input: { ref: inputRef }, }} {...other} value={value} ref={pickerContext.triggerRef} /> ); } JoySingleInputDateRangeField.fieldType = 'single-input'; function JoySingleInputDateRangePicker(props: DateRangePickerProps) { return ( ); } /** * This component is for syncing the theme mode of this demo with the MUI docs mode. * You might not need this component in your project. */ function SyncThemeMode() { const { setMode } = useColorScheme(); const { mode } = useMaterialColorScheme(); React.useEffect(() => { if (mode) { setMode(mode); } }, [mode, setMode]); return null; } const theme = createTheme({ colorSchemes: { light: true, dark: true } }); export default function JoyV6SingleInputRangeField() { return ( ); } ``` ```tsx import * as React from 'react'; import { ThemeProvider, createTheme, useColorScheme as useMaterialColorScheme, } from '@mui/material/styles'; import useSlotProps from '@mui/utils/useSlotProps'; import { extendTheme as extendJoyTheme, useColorScheme, CssVarsProvider, THEME_ID, } from '@mui/joy/styles'; import Input, { InputProps } from '@mui/joy/Input'; import Stack from '@mui/joy/Stack'; import FormControl from '@mui/joy/FormControl'; import FormLabel from '@mui/joy/FormLabel'; import Typography from '@mui/joy/Typography'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { usePickerContext, useSplitFieldProps } from '@mui/x-date-pickers/hooks'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker, DateRangePickerFieldProps, DateRangePickerProps, } from '@mui/x-date-pickers-pro/DateRangePicker'; import { useDateRangeManager } from '@mui/x-date-pickers-pro/managers'; import { unstable_useMultiInputRangeField as useMultiInputRangeField, UseMultiInputRangeFieldTextFieldProps, } from '@mui/x-date-pickers-pro/hooks'; import { MultiInputFieldRefs, MultiInputFieldSlotTextFieldProps, } from '@mui/x-date-pickers-pro/models'; const joyTheme = extendJoyTheme(); interface JoyTextFieldProps extends UseMultiInputRangeFieldTextFieldProps, Omit> { label?: React.ReactNode; triggerRef?: React.Ref; } function JoyField(props: JoyTextFieldProps) { const { // Should be ignored enableAccessibleFieldDOMStructure, triggerRef, disabled, id, label, slotProps, inputRef, ...other } = props; return ( {label} ); } interface JoyMultiInputDateRangeFieldProps extends Omit, MultiInputFieldRefs { slotProps: { textField: any; }; } function JoyMultiInputDateRangeField(props: JoyMultiInputDateRangeFieldProps) { const manager = useDateRangeManager({ enableAccessibleFieldDOMStructure: false, }); const pickerContext = usePickerContext(); const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const { slotProps, ...otherForwardedProps } = forwardedProps; const startTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, additionalProps: { label: 'Start' }, ownerState: { position: 'start' } as any, }) as MultiInputFieldSlotTextFieldProps; const endTextFieldProps = useSlotProps({ elementType: 'input', externalSlotProps: slotProps?.textField, additionalProps: { label: 'End' }, ownerState: { position: 'end' } as any, }) as MultiInputFieldSlotTextFieldProps; const fieldResponse = useMultiInputRangeField({ manager, internalProps: { ...internalProps, enableAccessibleFieldDOMStructure: false }, rootProps: { ref: pickerContext.rootRef, spacing: 2, overflow: 'auto', direction: 'row' as const, alignItems: 'center', ...otherForwardedProps, }, startTextFieldProps, endTextFieldProps, }); return ( {' – '} ); } JoyMultiInputDateRangeField.fieldType = 'multi-input'; function JoyDateRangePicker(props: DateRangePickerProps) { return ( ); } /** * This component is for syncing the theme mode of this demo with the MUI docs mode. * You might not need this component in your project. */ function SyncThemeMode() { const { setMode } = useColorScheme(); const { mode } = useMaterialColorScheme(); React.useEffect(() => { if (mode) { setMode(mode); } }, [mode, setMode]); return null; } const theme = createTheme({ colorSchemes: { light: true, dark: true } }); export default function JoyV6MultiInputRangeField() { return ( ); } ``` :::warning All the Joy UI examples use the non-accessible DOM structure. The new accessible DOM structure will become compatible with Joy UI in the future. ::: ## With a custom editing experience ### Using an Autocomplete If your user can only select a value in a small list of available dates, you can replace the field with the [Autocomplete](/material-ui/react-autocomplete/) component to list those dates: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import useForkRef from '@mui/utils/useForkRef'; import TextField from '@mui/material/TextField'; import IconButton from '@mui/material/IconButton'; import Autocomplete from '@mui/material/Autocomplete'; import { CalendarIcon } from '@mui/x-date-pickers/icons'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerFieldProps, DatePickerProps, } from '@mui/x-date-pickers/DatePicker'; import { usePickerContext, usePickerTranslations, useSplitFieldProps, } from '@mui/x-date-pickers/hooks'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; interface AutocompleteFieldProps extends DatePickerFieldProps { /** * @typescript-to-proptypes-ignore */ options?: Dayjs[]; } function AutocompleteField(props: AutocompleteFieldProps) { const { forwardedProps, internalProps } = useSplitFieldProps(props, 'date'); const { value, setValue, timezone, triggerRef, rootRef, rootClassName, rootSx, open, label, name, setOpen, } = usePickerContext(); const pickerTranslations = usePickerTranslations(); const { options = [], ...other } = forwardedProps; const { hasValidationError, getValidationErrorForNewValue } = useValidation({ validator: validateDate, value, timezone, props: internalProps, }); const handleRef = useForkRef(triggerRef, rootRef); const formattedValue = value ? value.format('ll') : null; const openPickerAriaLabel = pickerTranslations.openDatePickerDialogue(formattedValue); return ( { const endAdornment = params.InputProps .endAdornment as React.ReactElement; return ( setOpen((prev) => !prev)} aria-label={openPickerAriaLabel} size="small" > {endAdornment.props.children} ), }), }} /> ); }} getOptionLabel={(option) => { if (!dayjs.isDayjs(option)) { return ''; } return option.format('MM/DD/YYYY'); }} value={value} onChange={(_, newValue) => { setValue(newValue, { validationError: getValidationErrorForNewValue(newValue), }); }} isOptionEqualToValue={(option, valueToCheck) => option.toISOString() === valueToCheck.toISOString() } /> ); } interface AutocompleteDatePickerProps extends DatePickerProps { /** * @typescript-to-proptypes-ignore */ options: Dayjs[]; } function AutocompleteDatePicker(props: AutocompleteDatePickerProps) { const { options, ...other } = props; const optionsLookup = React.useMemo( () => options.reduce( (acc, option) => { acc[option.toISOString()] = true; return acc; }, {} as Record, ), [options], ); return ( !optionsLookup[date.startOf('day').toISOString()]} {...other} /> ); } const today = dayjs().startOf('day'); export default function MaterialDatePicker() { return ( ); } ``` ### Using a masked Text Field If you want to use a simple mask approach for the field editing instead of the built-in logic, you can replace the default field with the [TextField](/material-ui/react-text-field/) component using a masked input value built with the [rifm](https://github.com/realadvisor/rifm) package. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { useRifm } from 'rifm'; import TextField from '@mui/material/TextField'; import InputAdornment from '@mui/material/InputAdornment'; import IconButton from '@mui/material/IconButton'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerProps, DatePickerFieldProps, } from '@mui/x-date-pickers/DatePicker'; import { useSplitFieldProps, useParsedFormat, usePickerContext, } from '@mui/x-date-pickers/hooks'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { CalendarIcon } from '@mui/x-date-pickers/icons'; const MASK_USER_INPUT_SYMBOL = '_'; const ACCEPT_REGEX = /[\d]/gi; const staticDateWith2DigitTokens = dayjs('2019-11-21T11:30:00.000'); const staticDateWith1DigitTokens = dayjs('2019-01-01T09:00:00.000'); function getInputValueFromValue(value: Dayjs | null, format: string) { if (value == null) { return ''; } return value.isValid() ? value.format(format) : ''; } function MaskedDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const pickerContext = usePickerContext(); const parsedFormat = useParsedFormat(); // Control the input text const [inputValue, setInputValue] = React.useState(() => getInputValueFromValue(pickerContext.value, pickerContext.fieldFormat), ); React.useEffect(() => { if (pickerContext.value && pickerContext.value.isValid()) { const newDisplayDate = getInputValueFromValue( pickerContext.value, pickerContext.fieldFormat!, ); setInputValue(newDisplayDate); } }, [pickerContext.fieldFormat, pickerContext.value]); const { hasValidationError, getValidationErrorForNewValue } = useValidation({ value: pickerContext.value, timezone: pickerContext.timezone, props: internalProps, validator: validateDate, }); const handleInputValueChange = (newInputValue: string) => { setInputValue(newInputValue); const newValue = dayjs(newInputValue, pickerContext.fieldFormat); pickerContext.setValue(newValue, { validationError: getValidationErrorForNewValue(newValue), }); }; const rifmFormat = React.useMemo(() => { const formattedDateWith1Digit = staticDateWith1DigitTokens.format( pickerContext.fieldFormat, ); const inferredFormatPatternWith1Digits = formattedDateWith1Digit.replace( ACCEPT_REGEX, MASK_USER_INPUT_SYMBOL, ); const inferredFormatPatternWith2Digits = staticDateWith2DigitTokens .format(pickerContext.fieldFormat) .replace(ACCEPT_REGEX, '_'); if (inferredFormatPatternWith1Digits !== inferredFormatPatternWith2Digits) { throw new Error( `Mask does not support numbers with variable length such as 'M'.`, ); } const maskToUse = inferredFormatPatternWith1Digits; return function formatMaskedDate(valueToFormat: string) { let outputCharIndex = 0; return valueToFormat .split('') .map((character, characterIndex) => { ACCEPT_REGEX.lastIndex = 0; if (outputCharIndex > maskToUse.length - 1) { return ''; } const maskChar = maskToUse[outputCharIndex]; const nextMaskChar = maskToUse[outputCharIndex + 1]; const acceptedChar = ACCEPT_REGEX.test(character) ? character : ''; const formattedChar = maskChar === MASK_USER_INPUT_SYMBOL ? acceptedChar : maskChar + acceptedChar; outputCharIndex += formattedChar.length; const isLastCharacter = characterIndex === valueToFormat.length - 1; if ( isLastCharacter && nextMaskChar && nextMaskChar !== MASK_USER_INPUT_SYMBOL ) { // when cursor at the end of mask part (e.g. month) prerender next symbol "21" -> "21/" return formattedChar ? formattedChar + nextMaskChar : ''; } return formattedChar; }) .join(''); }; }, [pickerContext.fieldFormat]); const rifmProps = useRifm({ value: inputValue, onChange: handleInputValueChange, format: rifmFormat, }); return ( pickerContext.setOpen((prev) => !prev)} edge="end" > ), }} /> ); } function MaskedFieldDatePicker(props: DatePickerProps) { return ( ); } export default function MaskedMaterialTextField() { return ( ); } ``` ### Using a read-only Text Field If you want users to select a value exclusively through the views but you still want the UI to look like a Text Field, you can replace the field with a read-only [Text Field](/material-ui/react-text-field/) component: ```tsx import TextField from '@mui/material/TextField'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerProps, DatePickerFieldProps, } from '@mui/x-date-pickers/DatePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useParsedFormat, usePickerContext, } from '@mui/x-date-pickers/hooks'; import { CalendarIcon } from '@mui/x-date-pickers/icons'; function ReadOnlyDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const pickerContext = usePickerContext(); const parsedFormat = useParsedFormat(); const { hasValidationError } = useValidation({ validator: validateDate, value: pickerContext.value, timezone: pickerContext.timezone, props: internalProps, }); return ( , sx: { cursor: 'pointer', '& *': { cursor: 'inherit' } }, }} error={hasValidationError} focused={pickerContext.open} onClick={() => pickerContext.setOpen((prev) => !prev)} className={pickerContext.rootClassName} sx={pickerContext.rootSx} ref={pickerContext.rootRef} name={pickerContext.name} label={pickerContext.label} /> ); } function ReadOnlyFieldDatePicker(props: DatePickerProps) { return ( ); } export default function MaterialDatePicker() { return ( ); } ``` ### Using a read-only Text Field on mobile If you want to keep the default behavior on desktop but have a read-only TextField on mobile, you can conditionally render the custom field presented in the previous section: ```tsx import TextField from '@mui/material/TextField'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerProps, DatePickerFieldProps, } from '@mui/x-date-pickers/DatePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useParsedFormat, usePickerContext, } from '@mui/x-date-pickers/hooks'; import { CalendarIcon } from '@mui/x-date-pickers/icons'; import { DateField } from '@mui/x-date-pickers/DateField'; function ReadOnlyDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const pickerContext = usePickerContext(); const parsedFormat = useParsedFormat(); const { hasValidationError } = useValidation({ validator: validateDate, value: pickerContext.value, timezone: pickerContext.timezone, props: internalProps, }); return ( , sx: { cursor: 'pointer', '& *': { cursor: 'inherit' } }, }} error={hasValidationError} focused={pickerContext.open} onClick={() => pickerContext.setOpen((prev) => !prev)} name={pickerContext.name} label={pickerContext.label} className={pickerContext.rootClassName} sx={pickerContext.rootSx} ref={pickerContext.rootRef} /> ); } function ReadOnlyOnMobileDateField(props: DatePickerFieldProps) { const pickerContext = usePickerContext(); if (pickerContext.variant === 'mobile') { return ; } return ; } function ReadOnlyFieldDatePicker(props: DatePickerProps) { return ( ); } export default function MaterialDatePicker() { return ( ); } ``` ### Using a Button If you want users to select a value exclusively through the views and you don't want the UI to look like a Text Field, you can replace the field with the [Button](/material-ui/react-button/) component: ```tsx import useForkRef from '@mui/utils/useForkRef'; import Button from '@mui/material/Button'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerProps, DatePickerFieldProps, } from '@mui/x-date-pickers/DatePicker'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; import { useSplitFieldProps, useParsedFormat, usePickerContext, } from '@mui/x-date-pickers/hooks'; function ButtonDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const pickerContext = usePickerContext(); const handleRef = useForkRef(pickerContext.triggerRef, pickerContext.rootRef); const parsedFormat = useParsedFormat(); const { hasValidationError } = useValidation({ validator: validateDate, value: pickerContext.value, timezone: pickerContext.timezone, props: internalProps, }); const valueStr = pickerContext.value == null ? parsedFormat : pickerContext.value.format(pickerContext.fieldFormat); return ( ); } function ButtonFieldDatePicker(props: DatePickerProps) { return ( ); } export default function MaterialDatePicker() { return ( ); } ``` The same logic can be applied to any Range Picker: ```tsx import { Dayjs } from 'dayjs'; import useForkRef from '@mui/utils/useForkRef'; import Button from '@mui/material/Button'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangePicker, DateRangePickerProps, DateRangePickerFieldProps, } from '@mui/x-date-pickers-pro/DateRangePicker'; import { useValidation } from '@mui/x-date-pickers/validation'; import { validateDateRange } from '@mui/x-date-pickers-pro/validation'; import { useSplitFieldProps, useParsedFormat, usePickerContext, } from '@mui/x-date-pickers/hooks'; function ButtonDateRangeField(props: DateRangePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const pickerContext = usePickerContext(); const handleRef = useForkRef(pickerContext.triggerRef, pickerContext.rootRef); const parsedFormat = useParsedFormat(); const { hasValidationError } = useValidation({ validator: validateDateRange, value: pickerContext.value, timezone: pickerContext.timezone, props: internalProps, }); const formattedValue = pickerContext.value .map((date: Dayjs) => date == null ? parsedFormat : date.format(pickerContext.fieldFormat), ) .join(' – '); return ( ); } // TODO v8: Will be removed before the end of the alpha since single input will become the default field. ButtonDateRangeField.fieldType = 'single-input'; function ButtonFieldDateRangePicker(props: DateRangePickerProps) { return ( ); } export default function MaterialDateRangePicker() { return ( ); } ``` ## Build your own custom field :::success The sections below show how to build a field for your Picker. Unlike the field components exposed by `@mui/x-date-pickers` and `@mui/x-date-pickers-pro`, those fields are not suitable for a standalone usage. ::: ### Typing Each Picker component exposes an interface describing the props it passes to its field. You can import it from the same endpoint as the Picker component and use it to type the props of your field: ```ts import { DatePickerFieldProps } from '@mui/x-date-pickers/DatePicker'; import { DateRangePickerFieldProps } from '@mui/x-date-pickers-pro/DateRangePicker'; function CustomDateField(props: DatePickerFieldProps) { // Your custom field } function CustomDateRangeField(props: DateRangePickerFieldProps) { // Your custom field } ``` #### Import | Picker component | Field props interface | | ---------------------: | :------------------------------ | | Date Picker | `DatePickerFieldProps` | | Time Picker | `TimePickerFieldProps` | | Date Time Picker | `DateTimePickerFieldProps` | | Date Range Picker | `DateRangePickerFieldProps` | | Date Time Range Picker | `DateTimeRangePickerFieldProps` | ### Validation You can use the `useValidation` hook to check if the current value passed to your field is valid or not: ```js import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; const { // The error associated with the current value. // For example: "minDate" if `props.value < props.minDate`. validationError, // `true` if the value is invalid. // On range Pickers it is true if the start date or the end date is invalid. hasValidationError, // Imperatively get the error of a value. getValidationErrorForNewValue, } = useValidation({ // If you have a value in an internal state, you should pass it here. // Otherwise, you can pass the value returned by `usePickerContext()`. value, timezone, props, validator: validateDate, }); ``` #### Import Each Picker component has a validator adapted to its value type: | Picker component | Import validator | | ---------------------: | :--------------------------------------------------------------------------- | | Date Picker | `import { validateDate } from '@mui/x-date-pickers/validation'` | | Time Picker | `import { validateTime } from '@mui/x-date-pickers/validation'` | | Date Time Picker | `import { validateDateTime } from '@mui/x-date-pickers/validation'` | | Date Range Picker | `import { validateDateRange } from '@mui/x-date-pickers-pro/validation'` | | Date Time Range Picker | `import { validateDateTimeRange } from '@mui/x-date-pickers-pro/validation'` | ### Localized placeholder You can use the `useParsedFormat` to get a clean placeholder. This hook applies two main transformations on the format: 1. It replaces all the localized tokens (for example `L` for a date with `dayjs`) with their expanded value (`DD/MM/YYYY` for the same date with `dayjs`). 2. It replaces each token with its token from the localization object (for example `YYYY` remains `YYYY` for the English locale but becomes `AAAA` for the French locale). :::warning The format returned by `useParsedFormat` cannot be parsed by your date library. ::: ```js import { useParsedFormat } from '@mui/x-date-pickers/hooks'; // Uses the format defined by your Picker const parsedFormat = useParsedFormat(); // Uses the custom format provided const parsedFormat = useParsedFormat({ format: 'MM/DD/YYYY' }); ``` ### Props forwarded by the picker The picker can receive some commonly used props that should be forwarded to the field DOM elements: ```jsx ``` If you are using any of those props in one of your pickers, make sure to retrieve them in your field using the `usePickerContext` hook: ```jsx const { label, name, rootClassName, rootSx, rootRef } = usePickerContext(); return ( ); ``` ### Spread props to the DOM The field receives a lot of props that cannot be forwarded to the DOM element without warnings. You can use the `useSplitFieldProps` hook to get the props that can be forwarded safely to the DOM: ```jsx const { internalProps, forwardedProps } = useSplitFieldProps( // The props received by the field component props, // The value type ("date", "time" or "date-time") 'date', ); return ; ``` ### Pass the field to the Picker You can pass your custom field to your Picker using the `field` slot: ```jsx function DatePickerWithCustomField() { return ; } // Also works with the other variants of the component function DesktopDatePickerWithCustomField() { return } ``` ### Full custom example Here is a live demo of the example created in all the previous sections: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import TextField from '@mui/material/TextField'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker, DatePickerProps, DatePickerFieldProps, } from '@mui/x-date-pickers/DatePicker'; import { useSplitFieldProps, useParsedFormat, usePickerContext, } from '@mui/x-date-pickers/hooks'; import { useValidation, validateDate } from '@mui/x-date-pickers/validation'; function CustomDateField(props: DatePickerFieldProps) { const { internalProps, forwardedProps } = useSplitFieldProps(props, 'date'); const pickerContext = usePickerContext(); const placeholder = useParsedFormat(); const [inputValue, setInputValue] = useInputValue(); // Check if the current value is valid or not. const { hasValidationError } = useValidation({ value: pickerContext.value, timezone: pickerContext.timezone, props: internalProps, validator: validateDate, }); const handleChange = (event: React.ChangeEvent) => { const newInputValue = event.target.value; const newValue = dayjs(newInputValue, pickerContext.fieldFormat); setInputValue(newInputValue); pickerContext.setValue(newValue); }; return ( ); } function useInputValue() { const pickerContext = usePickerContext(); const [lastValueProp, setLastValueProp] = React.useState(pickerContext.value); const [inputValue, setInputValue] = React.useState(() => createInputValue(pickerContext.value, pickerContext.fieldFormat), ); if (lastValueProp !== pickerContext.value) { setLastValueProp(pickerContext.value); if (pickerContext.value && pickerContext.value.isValid()) { setInputValue( createInputValue(pickerContext.value, pickerContext.fieldFormat), ); } } return [inputValue, setInputValue] as const; } function createInputValue(value: Dayjs | null, format: string) { if (value == null) { return ''; } return value.isValid() ? value.format(format) : ''; } function CustomFieldDatePicker(props: DatePickerProps) { return ( ); } export default function MaterialDatePicker() { return ( ); } ``` --- # Source: https://mui.com/x/react-date-pickers/custom-layout.md --- productId: x-date-pickers title: Date and Time Pickers - Custom layout components: PickersActionBar, PickersLayout githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Custom layout The Date and Time Pickers let you reorganize the layout. :::success See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Default layout structure By default, pickers are made of five subcomponents present in the following order: - The **toolbar** displays the selected date. Can be enforced with `slotProps: { toolbar: { hidden: false } }` prop. - The **shortcuts** let users quickly select some values. Can be added with [`slotProps.shortcuts`](/x/react-date-pickers/shortcuts/#adding-shortcuts) - The **content** displays the current view. Can be a calendar, or a clock. - The **tabs** let users switch between day and time views in Date Time Pickers. Can be enforced with `slotProps: { tabs: { hidden: false } }` prop. - The **action bar** lets users perform some interactions. Can be added with [`slotProps.actionBar`](/x/react-date-pickers/custom-components/#action-bar) prop. By default the `content` and `tabs` are wrapped together in a `contentWrapper` to simplify the layout. You can [customize those components](/x/react-date-pickers/custom-components/) individually by using `slots` and `slotProps`. ## Orientation Toggling layout can be achieved by changing `orientation` prop value between `'portrait'` or `'landscape'`. Here is a demonstration with the 3 main blocks outlined with color borders. ```jsx import * as React from 'react'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Divider from '@mui/material/Divider'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; import { StaticTimePicker } from '@mui/x-date-pickers/StaticTimePicker'; import { StaticDateTimePicker } from '@mui/x-date-pickers/StaticDateTimePicker'; import { useTheme } from '@mui/material/styles'; import useMediaQuery from '@mui/material/useMediaQuery'; import { pickersLayoutClasses } from '@mui/x-date-pickers/PickersLayout'; const highlighLayout = { sx: { [`& .${pickersLayoutClasses.toolbar}`]: { border: 'solid red 4px', }, [`& .${pickersLayoutClasses.contentWrapper}`]: { border: 'solid green 4px', }, [`& .${pickersLayoutClasses.actionBar}`]: { border: 'solid blue 4px', }, }, }; export default function LayoutBlocks() { const theme = useTheme(); const isDesktop = useMediaQuery(theme.breakpoints.up('md')); const [currentComponent, setCurrentComponent] = React.useState('date'); const [orientation, setOrientation] = React.useState('portrait'); return ( { if (value !== null) { setCurrentComponent(value); } }} exclusive > date picker time picker date time picker { if (value !== null) { setOrientation(value); } }} exclusive > landscape portrait {currentComponent === 'date' && ( )} {currentComponent === 'time' && ( )} {currentComponent === 'date-time' && ( )} ); } ``` ## Layout structure A `` wraps all the subcomponents to provide the structure. By default it renders a `div` with `display: grid`. Such that all subcomponents are placed in a 3 by 3 [CSS grid](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout). ```jsx {toolbar} {shortcuts} {tabs} {content} {actionBar} ``` ## CSS customization To move an element, you can override its position in the layout with [`gridColumn`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/grid-column) and [`gridRow`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/grid-row) properties. In the next example, the action bar is replaced by a list and then placed on the left side of the content. It's achieved by applying the `{ gridColumn: 1, gridRow: 2 }` style. :::warning If you are using custom components, you should pay attention to `className`. To make CSS selectors work, you can either propagate `className` to the root element like in the demo, or use your own CSS class. ::: ```tsx import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { pickersLayoutClasses } from '@mui/x-date-pickers/PickersLayout'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; import { PickersActionBarProps } from '@mui/x-date-pickers/PickersActionBar'; import { usePickerActionsContext } from '@mui/x-date-pickers/hooks'; function ActionList(props: PickersActionBarProps) { const { className } = props; const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } = usePickerActionsContext(); const actions = [ { text: 'Accept', method: acceptValueChanges }, { text: 'Clear', method: clearValue }, { text: 'Cancel', method: cancelValueChanges }, { text: 'Today', method: setValueToToday }, ]; return ( // Propagate the className such that CSS selectors can be applied {actions.map(({ text, method }) => ( ))} ); } export default function MovingActions() { return ( ); } ``` ## DOM customization It's important to note that by modifying the layout with CSS, the new positions can lead to inconsistencies between the visual render and the DOM structure. In the previous demonstration, the tab order is broken because the action bar appears before the calendar, whereas in the DOM the action bar is still after. To modify the DOM structure, you can create a custom `Layout` wrapper. Use the `usePickerLayout` hook to get the subcomponents React nodes. Then you can fully customize the DOM structure. ```jsx import { usePickerLayout, PickersLayoutRoot, pickersLayoutClasses, PickersLayoutContentWrapper, } from '@mui/x-date-pickers/PickersLayout'; function MyCustomLayout(props) { const { toolbar, tabs, content, actionBar, ownerState } = usePickerLayout(props); // Put the action bar before the content return ( {toolbar} {actionBar} {tabs} {content} ); } ``` :::info This slot can also be used to add additional information in the layout. ::: Here is the complete example with a fix for the tabulation order and an external element added to the layout. Notice the use of `pickersLayoutClasses`, `PickersLayoutRoot`, and `PickersLayoutContentWrapper` to avoid rewriting the default CSS. ```tsx import { Dayjs } from 'dayjs'; import Box from '@mui/material/Box'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; import RestaurantIcon from '@mui/icons-material/Restaurant'; import { PickersLayoutProps, usePickerLayout, pickersLayoutClasses, PickersLayoutRoot, PickersLayoutContentWrapper, } from '@mui/x-date-pickers/PickersLayout'; import { PickersActionBarProps } from '@mui/x-date-pickers/PickersActionBar'; import { usePickerActionsContext } from '@mui/x-date-pickers/hooks'; function ActionList(props: PickersActionBarProps) { const { className } = props; const { clearValue, setValueToToday, acceptValueChanges, cancelValueChanges } = usePickerActionsContext(); const actions = [ { text: 'Accept', method: acceptValueChanges }, { text: 'Clear', method: clearValue }, { text: 'Cancel', method: cancelValueChanges }, { text: 'Today', method: setValueToToday }, ]; return ( {actions.map(({ text, method }) => ( ))} ); } function RestaurantHeader() { return ( ); } function CustomLayout(props: PickersLayoutProps) { const { toolbar, tabs, content, actionBar, ownerState } = usePickerLayout(props); return ( {toolbar} {actionBar} {tabs} {content} ); } export default function AddComponent() { return ( ); } ``` --- # Source: https://mui.com/x/react-date-pickers/custom-opening-button.md --- productId: x-date-pickers title: Date and Time Pickers - Custom opening button --- # Custom opening button The date picker lets you customize the button to open the views. :::success See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Set a custom opening icon If you want to change the icon opening the picker without changing its behavior, you can use the `openPickerIcon` slot: ```tsx import { createSvgIcon } from '@mui/material/utils'; import FlightTakeoffIcon from '@mui/icons-material/FlightTakeoff'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; const FlightLandIcon = createSvgIcon( , 'FlightLandIcon', ); function MuiIcon() { return Date picker opening icon; } export default function CustomOpeningIcon() { return ( ); } ``` You can also change the icon rendered based on the current status of the picker: ```tsx import * as React from 'react'; import { Dayjs } from 'dayjs'; import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; import CheckIcon from '@mui/icons-material/Check'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function CustomOpeningIconConditional() { const [value, setValue] = React.useState(null); return ( ); } ``` ## Pass props to the opening button If you want to customize the opening button without redefining its whole behavior, you can use either: - the `openPickerButton` slot to target the [`IconButton`](/material-ui/api/icon-button/) component. - the `inputAdornment` slot to target the [`InputAdornment`](/material-ui/api/input-adornment/) component. ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function CustomPropsOpeningButton() { return ( ); } ``` :::warning If you want to track the opening of the picker, you should use the `onOpen` / `onClose` callbacks instead of modifying the opening button: ```tsx ``` ::: ## Render the opening button at the start of the input You can use the `openPickerButtonPosition` on the `field` slot to position the opening button at the start or the end of the input: ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function StartEdgeOpeningButton() { return ( ); } ``` ## Add an icon next to the opening button If you want to add an icon next to the opening button, you can use the `inputAdornment` slot. In the example below, the warning icon will be visible anytime the current value is invalid: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import InputAdornment, { InputAdornmentProps } from '@mui/material/InputAdornment'; import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { DateValidationError } from '@mui/x-date-pickers/models'; function CustomInputAdornment(props: InputAdornmentProps & { hasError?: boolean }) { const { hasError, children, sx, ...other } = props; return ( {children} ); } export default function AddWarningIconWhenInvalid() { const [error, setError] = React.useState(null); return ( ); } ``` To add the same behavior to a picker that does not have an input adornment (for example, a Date Range Picker when used with a multi-input field), you need to use the `textField` slot to add one: ```tsx import * as React from 'react'; import dayjs from 'dayjs'; import InputAdornment, { InputAdornmentProps } from '@mui/material/InputAdornment'; import PriorityHighIcon from '@mui/icons-material/PriorityHigh'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { DateRangeValidationError } from '@mui/x-date-pickers-pro/models'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; import { FieldOwnerState } from '@mui/x-date-pickers/models'; function CustomInputAdornment(props: InputAdornmentProps & { hasError?: boolean }) { const { hasError, children, sx, ...other } = props; return ( {children} ); } export default function AddWarningIconWhenInvalidRange() { const [error, setError] = React.useState([null, null]); return ( ({ InputProps: { endAdornment: ( ), }, }), }} /> ); } ``` --- # Source: https://mui.com/x/react-data-grid/filtering/customization.md # Source: https://mui.com/x/react-tree-view/rich-tree-view/customization.md # Source: https://mui.com/x/react-tree-view/simple-tree-view/customization.md --- productId: x-tree-view title: Simple Tree View - Customization components: SimpleTreeView, TreeItem packageName: '@mui/x-tree-view' githubLabel: 'scope: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ --- # Simple Tree View - Customization Learn how to customize the Simple Tree View component. :::success See [Common concepts—Slots and subcomponents](/x/common-concepts/custom-components/) to learn how to use slots. ::: ## Basics ### Custom icons Use the `collapseIcon` slot, the `expandIcon` slot and the `defaultEndIcon` prop to customize `SimpleTreeView` icons. The demo below shows how to add icons using both an existing icon library, such as [Material Icons](/material-ui/material-icons/), and creating an icon from scratch using Material UI's [`SvgIcon`](/material-ui/icons/#svgicon). ```tsx import Box from '@mui/material/Box'; import AddBoxIcon from '@mui/icons-material/AddBox'; import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox'; import SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon'; import { styled } from '@mui/material/styles'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem'; const CustomTreeItem = styled(TreeItem)({ [`& .${treeItemClasses.iconContainer}`]: { '& .close': { opacity: 0.3, }, }, }); function CloseSquare(props: SvgIconProps) { return ( {/* tslint:disable-next-line: max-line-length */} ); } export default function CustomIcons() { return ( ); } ``` ### Custom toggle animations Use the `groupTransition` slot on `SimpleTreeView` to pass a component that handles your animation. The demo below is animated using Material UI's [`Collapse`](/material-ui/transitions/#collapse) component together with the [react-spring](https://www.react-spring.dev/) library. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Collapse from '@mui/material/Collapse'; import { TransitionProps } from '@mui/material/transitions'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem, TreeItemProps } from '@mui/x-tree-view/TreeItem'; import { useSpring, animated } from '@react-spring/web'; function TransitionComponent(props: TransitionProps) { const style = useSpring({ to: { opacity: props.in ? 1 : 0, transform: `translate3d(${props.in ? 0 : 20}px,0,0)`, }, }); return ( ); } const CustomTreeItem = React.forwardRef( (props: TreeItemProps, ref: React.Ref) => ( ), ); export default function CustomAnimation() { return ( ); } ``` ### Custom styling Use `treeItemClasses` to target internal elements of a `TreeItem` and change its styles. ```tsx import Box from '@mui/material/Box'; import { styled, alpha } from '@mui/material/styles'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem'; const CustomTreeItem = styled(TreeItem)(({ theme }) => ({ color: theme.palette.grey[200], [`& .${treeItemClasses.content}`]: { borderRadius: theme.spacing(0.5), padding: theme.spacing(0.5, 1), margin: theme.spacing(0.2, 0), [`& .${treeItemClasses.label}`]: { fontSize: '0.8rem', fontWeight: 500, }, }, [`& .${treeItemClasses.iconContainer}`]: { borderRadius: '50%', backgroundColor: theme.palette.primary.dark, padding: theme.spacing(0, 1.2), ...theme.applyStyles('light', { backgroundColor: alpha(theme.palette.primary.main, 0.25), }), ...theme.applyStyles('dark', { color: theme.palette.primary.contrastText, }), }, [`& .${treeItemClasses.groupTransition}`]: { marginLeft: 15, paddingLeft: 18, borderLeft: `1px dashed ${alpha(theme.palette.text.primary, 0.4)}`, }, ...theme.applyStyles('light', { color: theme.palette.grey[800], }), })); export default function CustomStyling() { return ( ); } ``` ### Custom Tree Item You can use the `TreeItem` customization API to build new layouts and manage behaviors. See [Tree Item customization](/x/react-tree-view/tree-item-customization/) to learn more about the anatomy of `TreeItem` and the customization utilities provided. ### Headless API Use the `useTreeItem()` hook to create your own component. The demo below shows how to add an avatar and custom typography elements. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Avatar from '@mui/material/Avatar'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { TreeItemContent, TreeItemIconContainer, TreeItemGroupTransition, TreeItemLabel, TreeItemRoot, TreeItemCheckbox, } from '@mui/x-tree-view/TreeItem'; import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; interface CustomTreeItemProps extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: CustomTreeItemProps, ref: React.Ref, ) { const { id, itemId, label, disabled, children, ...other } = props; const { getContextProviderProps, getRootProps, getContentProps, getIconContainerProps, getCheckboxProps, getLabelProps, getGroupTransitionProps, status, } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); return ( ({ background: theme.palette.primary.main, width: 24, height: 24, fontSize: '0.8rem', })} > {(label as string)[0]} {children && } ); }); export default function HeadlessAPI() { return ( ); } ``` ## Common examples ### Connection border Target the `treeItemClasses.groupTransition` class to add connection borders between `TreeItem` components. ```tsx import * as React from 'react'; import IndeterminateCheckBoxRoundedIcon from '@mui/icons-material/IndeterminateCheckBoxRounded'; import DisabledByDefaultRoundedIcon from '@mui/icons-material/DisabledByDefaultRounded'; import AddBoxRoundedIcon from '@mui/icons-material/AddBoxRounded'; import { styled, alpha } from '@mui/material/styles'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem, treeItemClasses } from '@mui/x-tree-view/TreeItem'; const CustomTreeItem = styled(TreeItem)(({ theme }) => ({ [`& .${treeItemClasses.content}`]: { padding: theme.spacing(0.5, 1), margin: theme.spacing(0.2, 0), }, [`& .${treeItemClasses.iconContainer}`]: { '& .close': { opacity: 0.3, }, }, [`& .${treeItemClasses.groupTransition}`]: { marginLeft: 15, paddingLeft: 18, borderLeft: `1px dashed ${alpha(theme.palette.text.primary, 0.4)}`, }, })); function ExpandIcon(props: React.PropsWithoutRef) { return ; } function CollapseIcon( props: React.PropsWithoutRef, ) { return ; } function EndIcon(props: React.PropsWithoutRef) { return ; } export default function BorderedTreeView() { return ( ); } ``` ### Gmail clone The Gmail sidebar is one of the most well-known examples of a tree view. The demo below shows how to recreate it with `SimpleTreeView`: ```tsx import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import MailIcon from '@mui/icons-material/Mail'; import DeleteIcon from '@mui/icons-material/Delete'; import Label from '@mui/icons-material/Label'; import SupervisorAccountIcon from '@mui/icons-material/SupervisorAccount'; import InfoIcon from '@mui/icons-material/Info'; import ForumIcon from '@mui/icons-material/Forum'; import LocalOfferIcon from '@mui/icons-material/LocalOffer'; import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; import ArrowRightIcon from '@mui/icons-material/ArrowRight'; import { SvgIconProps } from '@mui/material/SvgIcon'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItemContent, TreeItemIconContainer, TreeItemRoot, TreeItemGroupTransition, } from '@mui/x-tree-view/TreeItem'; import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; declare module 'react' { interface CSSProperties { '--tree-view-color'?: string; '--tree-view-bg-color'?: string; } } interface StyledTreeItemProps extends Omit, React.HTMLAttributes { bgColor?: string; bgColorForDarkMode?: string; color?: string; colorForDarkMode?: string; labelIcon: React.ElementType; labelInfo?: string; } type CustomTreeItemRootOwnerState = Pick< StyledTreeItemProps, 'color' | 'bgColor' | 'colorForDarkMode' | 'bgColorForDarkMode' >; const CustomTreeItemRoot = styled(TreeItemRoot)<{ ownerState: CustomTreeItemRootOwnerState; }>(({ theme, ownerState }) => ({ '--tree-view-color': ownerState.color, '--tree-view-bg-color': ownerState.bgColor, color: (theme.vars || theme).palette.text.secondary, ...theme.applyStyles('dark', { '--tree-view-color': ownerState.colorForDarkMode, '--tree-view-bg-color': ownerState.bgColorForDarkMode, }), })); const CustomTreeItemContent = styled(TreeItemContent)(({ theme }) => ({ marginBottom: theme.spacing(0.3), color: (theme.vars || theme).palette.text.secondary, borderRadius: theme.spacing(2), paddingRight: theme.spacing(1), paddingLeft: `calc(${theme.spacing(1)} + var(--TreeView-itemChildrenIndentation) * var(--TreeView-itemDepth))`, fontWeight: theme.typography.fontWeightMedium, '&[data-expanded]': { fontWeight: theme.typography.fontWeightRegular, }, '&:hover': { backgroundColor: (theme.vars || theme).palette.action.hover, }, '&[data-focused], &[data-selected], &[data-selected][data-focused]': { backgroundColor: `var(--tree-view-bg-color, ${(theme.vars || theme).palette.action.selected})`, color: 'var(--tree-view-color)', }, })); const CustomTreeItemIconContainer = styled(TreeItemIconContainer)(({ theme }) => ({ marginRight: theme.spacing(1), })); const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: StyledTreeItemProps, ref: React.Ref, ) { const { id, itemId, label, disabled, children, bgColor, color, labelIcon: LabelIcon, labelInfo, colorForDarkMode, bgColorForDarkMode, ...other } = props; const { getContextProviderProps, getRootProps, getContentProps, getIconContainerProps, getLabelProps, getGroupTransitionProps, status, } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const treeItemRootOwnerState = { color, bgColor, colorForDarkMode, bgColorForDarkMode, }; return ( {labelInfo} {children && } ); }); function EndIcon() { return
; } export default function GmailTreeView() { return ( ); } ``` --- # Source: https://mui.com/x/api/data-grid/data-grid-premium.md # DataGridPremium API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { DataGridPremium } from '@mui/x-data-grid-premium/DataGridPremium'; // or import { DataGridPremium } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | columns | `Array` | - | Yes | | | activeChartId | `string` | - | No | | | aggregationFunctions | `object` | `GRID_AGGREGATION_FUNCTIONS when `dataSource` is not provided, `{}` when `dataSource` is provided` | No | | | aggregationModel | `object` | - | No | | | aggregationRowsScope | `'all' \| 'filtered'` | `"filtered"` | No | | | aiAssistant | `bool` | `false` | No | | | aiAssistantActiveConversationIndex | `number` | - | No | | | aiAssistantConversations | `Array<{ id?: string, prompts: Array<{ createdAt: Date, helperText?: string, response?: { aggregation: object, chart?: object, conversationId: string, filterOperator?: 'and' \| 'or', filters: Array, grouping: Array, pivoting: object, select: number, sorting: Array }, value: string, variant?: 'error' \| 'processing' \| 'success' }>, title?: string }>` | - | No | | | aiAssistantSuggestions | `Array<{ value: string }>` | - | No | | | allowAiAssistantDataSampling | `bool` | - | No | | | apiRef | `{ current?: object }` | - | No | | | aria-label | `string` | - | No | | | aria-labelledby | `string` | - | No | | | autoHeight | `bool` | `false` | No | | | autoPageSize | `bool` | `false` | No | | | autosizeOnMount | `bool` | `false` | No | | | autosizeOptions | `{ columns?: Array, disableColumnVirtualization?: bool, expand?: bool, includeHeaderFilters?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }` | - | No | | | cellModesModel | `object` | - | No | | | cellSelection | `bool` | `false` | No | | | cellSelectionModel | `object` | - | No | | | chartsIntegration | `bool` | `false` | No | | | checkboxSelection | `bool` | `false` | No | | | checkboxSelectionVisibleOnly | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | clipboardCopyCellDelimiter | `string` | `'\t'` | No | | | columnBufferPx | `number` | `150` | No | | | columnFilterDebounceMs | `number` | `150` | No | | | columnGroupHeaderHeight | `number` | - | No | | | columnHeaderHeight | `number` | `56` | No | | | columnVisibilityModel | `object` | - | No | | | dataSource | `{ getAggregatedValue?: func, getChildrenCount?: func, getGroupKey?: func, getRows: func, updateRow?: func }` | - | No | | | dataSourceCache | `{ clear: func, get: func, set: func }` | - | No | | | defaultGroupingExpansionDepth | `number` | `0` | No | | | density | `'comfortable' \| 'compact' \| 'standard'` | `"standard"` | No | | | detailPanelExpandedRowIds | `Set` | - | No | | | disableAggregation | `bool` | `false` | No | | | disableAutosize | `bool` | `false` | No | | | disableChildrenFiltering | `bool` | `false` | No | | | disableChildrenSorting | `bool` | `false` | No | | | disableClipboardPaste | `bool` | `false` | No | | | disableColumnFilter | `bool` | `false` | No | | | disableColumnMenu | `bool` | `false` | No | | | disableColumnPinning | `bool` | `false` | No | | | disableColumnReorder | `bool` | `false` | No | | | disableColumnResize | `bool` | `false` | No | | | disableColumnSelector | `bool` | `false` | No | | | disableColumnSorting | `bool` | `false` | No | | | disableDensitySelector | `bool` | `false` | No | | | disableEval | `bool` | `false` | No | | | disableMultipleColumnsFiltering | `bool` | `false` | No | | | disableMultipleColumnsSorting | `bool` | `false` | No | | | disableMultipleRowSelection | `bool` | `false (`!props.checkboxSelection` for MIT Data Grid)` | No | | | disablePivoting | `bool` | `false` | No | | | disableRowGrouping | `bool` | `false` | No | | | disableRowSelectionExcludeModel | `bool` | `false` | No | | | disableRowSelectionOnClick | `bool` | `false` | No | | | disableVirtualization | `bool` | `false` | No | | | editMode | `'cell' \| 'row'` | `"cell"` | No | | | estimatedRowCount | `number` | - | No | | | experimentalFeatures | `{ charts?: bool, warnIfFocusStateIsNotSynced?: bool }` | - | No | | | filterDebounceMs | `number` | `150` | No | | | filterMode | `'client' \| 'server'` | `"client"` | No | | | filterModel | `{ items: Array<{ field: string, id?: number \| string, operator: string, value?: any }>, logicOperator?: 'and' \| 'or', quickFilterExcludeHiddenColumns?: bool, quickFilterLogicOperator?: 'and' \| 'or', quickFilterValues?: array }` | - | No | | | getAggregationPosition | `function(groupNode: GridGroupNode) => GridAggregationPosition \| null` | `(groupNode) => (groupNode.depth === -1 ? 'footer' : 'inline')` | No | | | getCellClassName | `function(params: GridCellParams) => string` | - | No | | | getDetailPanelContent | `function(params: GridRowParams) => React.JSX.Element` | - | No | | | getDetailPanelHeight | `function(params: GridRowParams) => number \| string` | `"() => 500"` | No | | | getEstimatedRowHeight | `function(params: GridRowHeightParams) => number \| null` | - | No | | | getPivotDerivedColumns | `function(column: GridColDef) => void` | - | No | | | getRowClassName | `function(params: GridRowClassNameParams) => string` | - | No | | | getRowHeight | `function(params: GridRowHeightParams) => GridRowHeightReturnValue` | - | No | | | getRowId | `func` | - | No | | | getRowSpacing | `function(params: GridRowSpacingParams) => GridRowSpacing` | - | No | | | getTreeDataPath | `function(row: R) => Array` | - | No | | | groupingColDef | `func \| object` | - | No | | | headerFilterHeight | `number` | - | No | | | headerFilters | `bool` | `false` | No | | | hideFooter | `bool` | `false` | No | | | hideFooterPagination | `bool` | `false` | No | | | hideFooterRowCount | `bool` | `false` | No | | | hideFooterSelectedRowCount | `bool` | `false` | No | | | historyEventHandlers | `object` | `Handlers for `rowEditStop`, `cellEditStop` and `clipboardPasteEnd` events` | No | | | historyStackSize | `number` | `30` | No | | | historyValidationEvents | `Array<'activeChartIdChange' \| 'activeStrategyProcessorChange' \| 'aggregationLookupSet' \| 'aggregationModelChange' \| 'aiAssistantActiveConversationIndexChange' \| 'aiAssistantConversationsChange' \| 'cellClick' \| 'cellDoubleClick' \| 'cellDragEnter' \| 'cellDragOver' \| 'cellEditStart' \| 'cellEditStop' \| 'cellFocusIn' \| 'cellFocusOut' \| 'cellKeyDown' \| 'cellKeyUp' \| 'cellModeChange' \| 'cellModesModelChange' \| 'cellMouseDown' \| 'cellMouseOver' \| 'cellMouseUp' \| 'cellSelectionChange' \| 'chartSynchronizationStateChange' \| 'clipboardCopy' \| 'clipboardPasteEnd' \| 'clipboardPasteStart' \| 'columnGroupHeaderBlur' \| 'columnGroupHeaderFocus' \| 'columnGroupHeaderKeyDown' \| 'columnHeaderBlur' \| 'columnHeaderClick' \| 'columnHeaderContextMenu' \| 'columnHeaderDoubleClick' \| 'columnHeaderDragEnd' \| 'columnHeaderDragEndNative' \| 'columnHeaderDragEnter' \| 'columnHeaderDragOver' \| 'columnHeaderDragStart' \| 'columnHeaderEnter' \| 'columnHeaderFocus' \| 'columnHeaderKeyDown' \| 'columnHeaderLeave' \| 'columnHeaderOut' \| 'columnHeaderOver' \| 'columnIndexChange' \| 'columnOrderChange' \| 'columnResize' \| 'columnResizeStart' \| 'columnResizeStop' \| 'columnsChange' \| 'columnSeparatorDoubleClick' \| 'columnSeparatorMouseDown' \| 'columnVisibilityModelChange' \| 'columnWidthChange' \| 'debouncedResize' \| 'densityChange' \| 'detailPanelsExpandedRowIdsChange' \| 'excelExportStateChange' \| 'fetchRows' \| 'filteredRowsSet' \| 'filterModelChange' \| 'headerFilterBlur' \| 'headerFilterClick' \| 'headerFilterKeyDown' \| 'headerFilterMouseDown' \| 'headerSelectionCheckboxChange' \| 'menuClose' \| 'menuOpen' \| 'paginationMetaChange' \| 'paginationModelChange' \| 'pinnedColumnsChange' \| 'pivotModeChange' \| 'pivotModelChange' \| 'pivotPanelOpenChange' \| 'preferencePanelClose' \| 'preferencePanelOpen' \| 'redo' \| 'renderedRowsIntervalChange' \| 'resize' \| 'rootMount' \| 'rowClick' \| 'rowCountChange' \| 'rowDoubleClick' \| 'rowDragEnd' \| 'rowDragOver' \| 'rowDragStart' \| 'rowEditStart' \| 'rowEditStop' \| 'rowExpansionChange' \| 'rowGroupingModelChange' \| 'rowModesModelChange' \| 'rowMouseEnter' \| 'rowMouseLeave' \| 'rowMouseOut' \| 'rowMouseOver' \| 'rowOrderChange' \| 'rowSelectionChange' \| 'rowSelectionCheckboxChange' \| 'rowsScrollEnd' \| 'rowsScrollEndIntersection' \| 'rowsSet' \| 'scrollPositionChange' \| 'sidebarClose' \| 'sidebarOpen' \| 'sortedRowsSet' \| 'sortModelChange' \| 'stateChange' \| 'strategyAvailabilityChange' \| 'undo' \| 'unmount' \| 'viewportInnerSizeChange' \| 'virtualScrollerContentSizeChange' \| 'virtualScrollerTouchMove' \| 'virtualScrollerWheel'>` | `['columnsChange', 'rowsSet', 'sortedRowsSet', 'filteredRowsSet', 'paginationModelChange']` | No | | | ignoreDiacritics | `bool` | `false` | No | | | ignoreValueFormatterDuringExport | `{ clipboardExport?: bool, csvExport?: bool } \| bool` | `false` | No | | | initialState | `object` | - | No | | | isCellEditable | `function(params: GridCellParams) => boolean` | - | No | | | isGroupExpandedByDefault | `function(node: GridGroupNode) => boolean` | - | No | | | isRowReorderable | `function(params: object, params.row: R, params.rowNode: GridTreeNode) => boolean` | - | No | | | isRowSelectable | `function(params: GridRowParams) => boolean` | - | No | | | isValidRowReorder | `function(context: ReorderValidationContext) => boolean` | - | No | | | keepColumnPositionIfDraggedOutside | `bool` | `false` | No | | | keepNonExistentRowsSelected | `bool` | `false` | No | | | label | `string` | - | No | | | lazyLoading | `bool` | `false` | No | | | lazyLoadingRequestThrottleMs | `number` | `500` | No | | | listView | `bool` | - | No | | | listViewColumn | `{ align?: 'center' \| 'left' \| 'right', cellClassName?: func \| string, display?: 'flex' \| 'text', field: string, renderCell?: func }` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | logger | `{ debug: func, error: func, info: func, warn: func }` | `console` | No | | | logLevel | `'debug' \| 'error' \| 'info' \| 'warn' \| false` | `"error" ("warn" in dev mode)` | No | | | multipleColumnsSortingMode | `'always' \| 'withModifierKey'` | `"withModifierKey"` | No | | | nonce | `string` | - | No | | | onActiveChartIdChange | `function(activeChartId: string) => void` | - | No | | | onAggregationModelChange | `function(model: GridAggregationModel, details: GridCallbackDetails) => void` | - | No | | | onAiAssistantActiveConversationIndexChange | `function(aiAssistantActiveConversationIndex: number) => void` | - | No | | | onAiAssistantConversationsChange | `function(conversations: Array) => void` | - | No | | | onBeforeClipboardPasteStart | `function(params: object) => void` | - | No | | | onCellClick | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellDoubleClick | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellEditStart | `function(params: GridCellParams, event: MuiEvent) => void` | - | No | | | onCellEditStop | `function(params: GridCellParams, event: MuiEvent) => void` | - | No | | | onCellKeyDown | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellModesModelChange | `function(cellModesModel: GridCellModesModel, details: GridCallbackDetails) => void` | - | No | | | onCellSelectionModelChange | `function(cellSelectionModel: GridCellSelectionModel, details: GridCallbackDetails) => void` | - | No | | | onClipboardCopy | `function(data: string) => void` | - | No | | | onClipboardPasteEnd | `func` | - | No | | | onClipboardPasteStart | `func` | - | No | | | onColumnHeaderClick | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderContextMenu | `function(params: GridColumnHeaderParams, event: MuiEvent) => void` | - | No | | | onColumnHeaderDoubleClick | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderEnter | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderLeave | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderOut | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderOver | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnOrderChange | `function(params: GridColumnOrderChangeParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onColumnResize | `function(params: GridColumnResizeParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnVisibilityModelChange | `function(model: GridColumnVisibilityModel, details: GridCallbackDetails) => void` | - | No | | | onColumnWidthChange | `function(params: GridColumnResizeParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onDataSourceError | `function(error: GridGetRowsError \| GridUpdateRowError) => void` | - | No | | | onDensityChange | `function(density: GridDensity) => void` | - | No | | | onDetailPanelExpandedRowIdsChange | `function(ids: Array, details: GridCallbackDetails) => void` | - | No | | | onExcelExportStateChange | `function(inProgress: string) => void` | - | No | | | onFetchRows (deprecated) | `function(params: GridFetchRowsParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | ⚠️ Use the {@link [https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading](https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading) Server-side data-Viewport loading} instead. | | onFilterModelChange | `function(model: GridFilterModel, details: GridCallbackDetails) => void` | - | No | | | onMenuClose | `function(params: GridMenuParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onMenuOpen | `function(params: GridMenuParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onPaginationMetaChange | `function(paginationMeta: GridPaginationMeta) => void` | - | No | | | onPaginationModelChange | `function(model: GridPaginationModel, details: GridCallbackDetails) => void` | - | No | | | onPinnedColumnsChange | `function(pinnedColumns: GridPinnedColumnFields, details: GridCallbackDetails) => void` | - | No | | | onPivotActiveChange | `function(isPivotActive: boolean) => void` | - | No | | | onPivotModelChange | `function(pivotModel: GridPivotModel) => void` | - | No | | | onPivotPanelOpenChange (deprecated) | `function(pivotPanelOpen: boolean) => void` | - | No | ⚠️ Use the `sidebarOpen` and `sidebarClose` events or corresponding event handlers `onSidebarOpen()` and `onSidebarClose()` instead. | | onPreferencePanelClose | `function(params: GridPreferencePanelParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onPreferencePanelOpen | `function(params: GridPreferencePanelParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onProcessRowUpdateError | `function(error: any) => void` | - | No | | | onPrompt | `function(prompt: string, promptContext: string, conversationId: string) => Promise` | - | No | | | onRedo | `func` | - | No | | | onResize | `function(containerSize: ElementSize, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onRowClick | `function(params: GridRowParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onRowCountChange | `function(count: number) => void` | - | No | | | onRowDoubleClick | `function(params: GridRowParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onRowEditStart | `function(params: GridRowParams, event: MuiEvent) => void` | - | No | | | onRowEditStop | `function(params: GridRowParams, event: MuiEvent) => void` | - | No | | | onRowGroupingModelChange | `function(model: GridRowGroupingModel, details: GridCallbackDetails) => void` | - | No | | | onRowModesModelChange | `function(rowModesModel: GridRowModesModel, details: GridCallbackDetails) => void` | - | No | | | onRowOrderChange | `function(params: GridRowOrderChangeParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onRowSelectionModelChange | `function(rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails) => void` | - | No | | | onRowsScrollEnd (deprecated) | `function(params: GridRowScrollEndParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | ⚠️ Use the {@link [https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#infinite-loading](https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#infinite-loading) Server-side data-Infinite loading} instead. | | onSidebarClose | `function(params: GridSidebarParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onSidebarOpen | `function(params: GridSidebarParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onSortModelChange | `function(model: GridSortModel, details: GridCallbackDetails) => void` | - | No | | | onUndo | `func` | - | No | | | pageSizeOptions | `Array` | `[25, 50, 100]` | No | | | pagination | `bool` | `false` | No | | | paginationMeta | `{ hasNextPage?: bool }` | - | No | | | paginationMode | `'client' \| 'server'` | `"client"` | No | | | paginationModel | `{ page: number, pageSize: number }` | - | No | | | pinnedColumns | `object` | - | No | | | pinnedColumnsSectionSeparator | `'border-and-shadow' \| 'border' \| 'shadow'` | `'border-and-shadow'` | No | | | pinnedRows | `{ bottom?: Array, top?: Array }` | - | No | | | pinnedRowsSectionSeparator | `'border-and-shadow' \| 'border'` | `'border-and-shadow'` | No | | | pivotActive | `bool` | `false` | No | | | pivotingColDef | `func \| { align?: 'center' \| 'left' \| 'right', cellClassName?: func \| string, description?: string, display?: 'flex' \| 'text', field?: string, flex?: number, headerAlign?: 'center' \| 'left' \| 'right', headerClassName?: func \| string, headerName?: string, maxWidth?: number, minWidth?: number, resizable?: bool, sortingOrder?: Array<'asc' \| 'desc'>, width?: number }` | `undefined` | No | | | pivotModel | `{ columns: Array, rows: Array<{ field: string, hidden?: bool }>, values: Array<{ aggFunc: string, field: string, hidden?: bool }> }` | - | No | | | pivotPanelOpen (deprecated) | `bool` | `false` | No | ⚠️ Use `initialState.sidebar.open` instead. | | processRowUpdate | `function(newRow: R, oldRow: R, params: { rowId: GridRowId }) => Promise \| R` | - | No | | | resizeThrottleMs | `number` | `60` | No | | | rowBufferPx | `number` | `150` | No | | | rowCount | `number` | - | No | | | rowGroupingColumnMode | `'multiple' \| 'single'` | `'single'` | No | | | rowGroupingModel | `Array` | - | No | | | rowHeight | `number` | `52` | No | | | rowModesModel | `object` | - | No | | | rowReordering | `bool` | `false` | No | | | rows | `Array` | `[]` | No | | | rowSelection | `bool` | `true` | No | | | rowSelectionModel | `{ ids: Set, type: 'exclude' \| 'include' }` | - | No | | | rowSelectionPropagation | `{ descendants?: bool, parents?: bool }` | `{ parents: true, descendants: true }` | No | | | rowsLoadingMode (deprecated) | `'client' \| 'server'` | `"client"` | No | ⚠️ Use the {@link [https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading](https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading) Server-side data-Viewport loading} instead. | | rowSpacingType | `'border' \| 'margin'` | `"margin"` | No | | | rowSpanning | `bool` | `false` | No | | | scrollbarSize | `number` | - | No | | | scrollEndThreshold | `number` | `80` | No | | | setTreeDataPath | `function(path: Array, row: R) => R` | - | No | | | showCellVerticalBorder | `bool` | `false` | No | | | showColumnVerticalBorder | `bool` | `false` | No | | | showToolbar | `bool` | `false` | No | | | slotProps | `object` | - | No | | | slots | `object` | - | No | | | sortingMode | `'client' \| 'server'` | `"client"` | No | | | sortingOrder | `Array<'asc' \| 'desc'>` | `['asc', 'desc', null]` | No | | | sortModel | `Array<{ field: string, sort?: 'asc' \| 'desc' }>` | - | No | | | splitClipboardPastedText | `function(text: string, delimiter: string) => void` | - | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | tabNavigation | `'all' \| 'content' \| 'header' \| 'none'` | `"none"` | No | | | throttleRowsMs | `number` | `0` | No | | | treeData | `bool` | `false` | No | | | virtualizeColumnsWithAutoRowHeight | `bool` | `false` | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | aiAssistantPanel | `null` | `.MuiDataGridPremium-aiAssistantPanel` | Component rendered when AI Assistant panel is open. Only needed when `aiAssistant` prop is passed to the grid. Pass `GridAiAssistantPanel` to render the default AI Assistant panel. | | chartsPanel | `null` | - | Component rendered when charts panel is open. Only needed when `chartsIntegration` prop is passed to the grid. Pass `GridChartsPanel` to render the default charts panel. | | emptyPivotOverlay | `GridEmptyPivotOverlay` | - | Component rendered when pivot mode is enabled but no rows are defined. | | headerFilterCell | `GridHeaderFilterCell` | - | Component responsible for showing menu adornment in Header filter row | | headerFilterMenu | `GridHeaderFilterMenu` | - | Component responsible for showing menu in Header filter row | | bottomContainer | `GridBottomContainer` | - | Component rendered for the bottom container. | | cell | `GridCell` | `.MuiDataGridPremium-cell` | Component rendered for each cell. | | skeletonCell | `GridSkeletonCell` | - | Component rendered for each skeleton cell. | | columnHeaderFilterIconButton | `GridColumnHeaderFilterIconButton` | - | Filter icon component rendered in each column header. | | columnHeaderSortIcon | `GridColumnHeaderSortIcon` | - | Sort icon component rendered in each column header. | | columnMenu | `GridColumnMenu` | - | Column menu component rendered by clicking on the 3 dots "kebab" icon in column headers. | | columnHeaders | `GridColumnHeaders` | `.MuiDataGridPremium-columnHeaders` | Component responsible for rendering the column headers. | | detailPanels | `GridDetailPanels` | - | Component responsible for rendering the detail panels. | | footer | `GridFooter` | - | Footer component rendered at the bottom of the grid viewport. | | footerRowCount | `GridRowCount` | - | Row count component rendered in the footer | | toolbar | `undefined` | `.MuiDataGridPremium-toolbar` | Toolbar component rendered in the grid header. | | loadingOverlay | `GridLoadingOverlay` | - | Loading overlay component rendered when the grid is in a loading state. | | noResultsOverlay | `GridNoResultsOverlay` | - | No results overlay component rendered when the grid has no results after filtering. | | noRowsOverlay | `GridNoRowsOverlay` | - | No rows overlay component rendered when the grid has no rows. | | noColumnsOverlay | `GridNoColumnsOverlay` | - | No columns overlay component rendered when the grid has no columns. | | pagination | `Pagination` | - | Pagination component rendered in the grid footer by default. | | filterPanel | `GridFilterPanel` | - | Filter panel component rendered when clicking the filter button. | | columnsPanel | `GridColumnsPanel` | - | GridColumns panel component rendered when clicking the columns button. | | columnsManagement | `GridColumnsManagement` | `.MuiDataGridPremium-columnsManagement` | Component used inside Grid Columns panel to manage columns. | | panel | `GridPanel` | `.MuiDataGridPremium-panel` | Panel component wrapping the filters and columns panels. | | row | `GridRow` | `.MuiDataGridPremium-row` | Component rendered for each row. | | baseAutocomplete | `Autocomplete` | - | The custom Autocomplete component used in the grid for both header and cells. | | baseBadge | `Badge` | - | The custom Badge component used in the grid for both header and cells. | | baseCheckbox | `Checkbox` | - | The custom Checkbox component used in the grid for both header and cells. | | baseChip | `Chip` | - | The custom Chip component used in the grid. | | baseCircularProgress | `CircularProgress` | - | The custom CircularProgress component used in the grid. | | baseDivider | `Divider` | - | The custom Divider component used in the grid. | | baseLinearProgress | `LinearProgress` | - | The custom LinearProgress component used in the grid. | | baseMenuList | `MenuList` | - | The custom MenuList component used in the grid. | | baseMenuItem | `MenuItem` | - | The custom MenuItem component used in the grid. | | baseTextField | `TextField` | - | The custom TextField component used in the grid. | | baseSelect | `Select` | - | The custom Select component used in the grid. | | baseButton | `Button` | - | The custom Button component used in the grid. | | baseIconButton | `IconButton` | - | The custom IconButton component used in the grid. | | baseInput | `Input` | - | The custom Input component used in the grid. | | baseTextarea | `InputBase with multiline` | - | The custom Textarea component used in the grid for multiline text editing. | | baseToggleButton | `ToggleButton` | - | The custom ToggleButton component used in the grid. | | baseTooltip | `Tooltip` | - | The custom Tooltip component used in the grid. | | basePagination | `Pagination` | - | The custom Pagination component used in the grid. | | basePopper | `Popper` | - | The custom Popper component used in the grid. | | baseSelectOption | `SelectOption` | - | The custom SelectOption component used in the grid. | | baseSkeleton | `Skeleton` | - | The custom Skeleton component used in the grid. | | baseSwitch | `Switch` | - | The custom Switch component used in the grid. | | baseTabs | `Tabs` | - | The custom Tabs component used in the grid. | | booleanCellTrueIcon | `GridCheckIcon` | - | Icon displayed on the boolean cell to represent the true value. | | booleanCellFalseIcon | `GridCloseIcon` | - | Icon displayed on the boolean cell to represent the false value. | | undoIcon | `GridUndoIcon` | - | Icon displayed on the undo button in the toolbar. | | redoIcon | `GridRedoIcon` | - | Icon displayed on the redo button in the toolbar. | | columnMenuIcon | `GridTripleDotsVerticalIcon` | - | Icon displayed on the side of the column header title to display the filter input component. | | openFilterButtonIcon | `GridFilterListIcon` | - | Icon displayed on the open filter button present in the toolbar by default. | | columnFilteredIcon | `GridFilterAltIcon` | - | Icon displayed on the column header menu to show that a filter has been applied to the column. | | columnSelectorIcon | `GridColumnIcon` | - | Icon displayed on the column menu selector tab. | | columnUnsortedIcon | `GridColumnUnsortedIcon` | - | Icon displayed on the side of the column header title when unsorted. | | columnSortedAscendingIcon | `GridArrowUpwardIcon` | - | Icon displayed on the side of the column header title when sorted in ascending order. | | columnSortedDescendingIcon | `GridArrowDownwardIcon` | - | Icon displayed on the side of the column header title when sorted in descending order. | | columnResizeIcon | `GridSeparatorIcon` | - | Icon displayed in between two column headers that allows to resize the column header. | | densityCompactIcon | `GridViewHeadlineIcon` | - | Icon displayed on the compact density option in the toolbar. | | densityStandardIcon | `GridTableRowsIcon` | - | Icon displayed on the standard density option in the toolbar. | | densityComfortableIcon | `GridViewStreamIcon` | - | Icon displayed on the "comfortable" density option in the toolbar. | | exportIcon | `GridDownloadIcon` | - | Icon displayed on the open export button present in the toolbar by default. | | moreActionsIcon | `GridMoreVertIcon` | - | Icon displayed on the `actions` column type to open the menu. | | treeDataExpandIcon | `GridKeyboardArrowRight` | - | Icon displayed on the tree data toggling column when the children are collapsed | | treeDataCollapseIcon | `GridExpandMoreIcon` | - | Icon displayed on the tree data toggling column when the children are expanded | | groupingCriteriaExpandIcon | `GridKeyboardArrowRight` | - | Icon displayed on the grouping column when the children are collapsed | | groupingCriteriaCollapseIcon | `GridExpandMoreIcon` | - | Icon displayed on the grouping column when the children are expanded | | detailPanelExpandIcon | `GridAddIcon` | - | Icon displayed on the detail panel toggle column when collapsed. | | detailPanelCollapseIcon | `GridRemoveIcon` | - | Icon displayed on the detail panel toggle column when expanded. | | filterPanelAddIcon | `GridAddIcon` | - | Icon displayed for deleting the filter from filter panel. | | filterPanelDeleteIcon | `GridDeleteIcon` | - | Icon displayed for deleting the filter from filter panel. | | filterPanelRemoveAllIcon | `GridDeleteForeverIcon` | - | Icon displayed for deleting all the active filters from filter panel. | | rowReorderIcon | `GridDragIcon` | `.MuiDataGridPremium-rowReorderIcon` | Icon displayed on the `reorder` column type to reorder a row. | | quickFilterIcon | `GridSearchIcon` | - | Icon displayed on the quick filter input. | | quickFilterClearIcon | `GridCloseIcon` | - | Icon displayed on the quick filter reset input. | | columnMenuHideIcon | `GridVisibilityOffIcon` | - | Icon displayed in column menu for hiding column | | columnMenuSortAscendingIcon | `GridArrowUpwardIcon` | - | Icon displayed in column menu for ascending sort | | columnMenuSortDescendingIcon | `GridArrowDownwardIcon` | - | Icon displayed in column menu for descending sort | | columnMenuUnsortIcon | `null` | - | Icon displayed in column menu for unsort | | columnMenuFilterIcon | `GridFilterAltIcon` | - | Icon displayed in column menu for filter | | columnMenuManageColumnsIcon | `GridViewColumnIcon` | - | Icon displayed in column menu for showing all columns | | columnMenuClearIcon | `GridClearIcon` | - | Icon displayed in column menu for clearing values | | loadIcon | `GridLoadIcon` | - | Icon displayed on the input while processing. | | columnReorderIcon | `GridDragIcon` | - | Icon displayed on the column reorder button. | | menuItemCheckIcon | `GridCheckIcon` | - | Icon displayed to indicate that a menu item is selected. | | longTextCellExpandIcon | `GridLongTextCellExpandIcon` | - | Icon displayed on the long text cell to expand the content. | | longTextCellCollapseIcon | `GridLongTextCellCollapseIcon` | - | Icon displayed on the long text cell popup to collapse the content. | | columnMenuPinLeftIcon | `GridPushPinLeftIcon` | - | Icon displayed in column menu for left pinning | | columnMenuPinRightIcon | `GridPushPinRightIcon` | - | Icon displayed in column menu for right pinning | | columnMenuUngroupIcon | `GridWorkspacesIcon` | - | Icon displayed in column menu for ungrouping | | columnMenuGroupIcon | `GridGroupWorkIcon` | - | Icon displayed in column menu for grouping | | columnMenuAggregationIcon | `GridFunctionsIcon` | - | Icon displayed in column menu for aggregation | | pivotIcon | `GridPivotIcon` | - | Icon used for the pivot icon | | pivotSearchIcon | `GridSearchIcon` | - | Icon used for the search icon in the sidebar search field | | pivotSearchClearIcon | `GridClearIcon` | - | Icon used for the clear button in the sidebar search field | | pivotMenuAddIcon | `GridAddIcon` | - | Icon displayed in the pivot menu for adding a field to a pivot section. | | pivotMenuMoveUpIcon | `GridExpandLessIcon` | - | Icon displayed in the pivot menu for moving a field up. | | pivotMenuMoveDownIcon | `GridExpandMoreIcon` | - | Icon displayed in the pivot menu for moving a field down. | | pivotMenuMoveToTopIcon | `GridMoveToTopIcon` | - | Icon displayed in the pivot menu for moving a field to the top. | | pivotMenuMoveToBottomIcon | `GridMoveToBottomIcon` | - | Icon displayed in the pivot menu for moving a field to the bottom. | | pivotMenuCheckIcon | `GridCheckIcon` | - | Icon displayed in the pivot menu to signify a pivot section is selected. | | pivotMenuRemoveIcon | `GridDeleteIcon` | - | Icon displayed in the pivot menu for removing a field from the pivot. | | sidebarCloseIcon | `GridCloseIcon` | - | Icon displayed in the sidebar close button. | | collapsibleIcon | `GridExpandMoreIcon` | `.MuiDataGridPremium-collapsibleIcon` | Icon displayed in the collapsible to indicate if it is open or closed. | | aiAssistantIcon | `GridAssistantIcon` | - | Icon used for the AI Assistant button | | aiAssistantPanelCloseIcon | `GridCloseIcon` | - | Icon used for the AI Assistant panel close button | | aiAssistantPanelNewConversationIcon | `GridAddIcon` | - | Icon used for the AI Assistant panel new conversation button | | aiAssistantPanelHistoryIcon | `GridHistoryIcon` | - | Icon used for the AI Assistant panel history icon | | promptIcon | `GridPromptIcon` | `.MuiDataGridPremium-promptIcon` | Icon used for the prompt | | promptSendIcon | `GridSendIcon` | - | Icon used for the button that sends a prompt | | promptSpeechRecognitionIcon | `GridMicIcon` | - | Icon used for the button that starts and stops recording the prompt | | promptSpeechRecognitionOffIcon | `GridMicOffIcon` | - | Icon used for when speech recognition is not supported | | promptRerunIcon | `GridRerunIcon` | - | Icon used for the button that reruns a prompt | | promptSortAscIcon | `GridArrowUpwardIcon` | - | Icon used to display sort ascending changes | | promptSortDescIcon | `GridArrowDownwardIcon` | - | Icon used to display sort descending changes | | promptChartsIcon | `GridChartsIcon` | - | Icon used to mark the request to visalize the data | | promptGroupIcon | `GridGroupWorkIcon` | - | Icon used to display group changes | | promptFilterIcon | `GridFilterAltIcon` | - | Icon used to display filter changes | | promptPivotIcon | `GridPivotIcon` | - | Icon used to display pivot changes | | promptAggregationIcon | `GridFunctionsIcon` | - | Icon used to display aggregation changes | | promptChangesToggleIcon | `GridExpandMoreIcon` | `.MuiDataGridPremium-promptChangesToggleIcon` | Icon used on the toggle button of the changes list | | chartsIcon | `GridChartsIcon` | - | Icon used for the charts configuration button | | chartsSearchIcon | `GridSearchIcon` | - | Icon used for the search icon in the sidebar search field in the charts configuration panel | | chartsSearchClearIcon | `GridClearIcon` | - | Icon used for the clear button in the sidebar search field in the charts configuration panel | | chartsMenuMoveUpIcon | `GridExpandLessIcon` | - | Icon used for the move up button in the charts configuration panel menu | | chartsMenuMoveDownIcon | `GridExpandMoreIcon` | - | Icon used for the move down button in the charts configuration panel menu | | chartsMenuMoveToTopIcon | `GridMoveToTopIcon` | - | Icon used for the move to top button in the charts configuration panel menu | | chartsMenuMoveToBottomIcon | `GridMoveToBottomIcon` | - | Icon used for the move to bottom button in the charts configuration panel menu | | chartsMenuAddIcon | `GridAddIcon` | - | Icon used for the add button in the charts configuration panel menu | | chartsMenuRemoveIcon | `GridDeleteIcon` | - | Icon used for the remove button in the charts configuration panel menu | | chartsSyncIcon | `GridSyncIcon` | - | Icon used for the sync button in the charts configuration panel when sync is enabled | | chartsSyncDisabledIcon | `GridSyncDisabledIcon` | - | Icon used for the sync button in the charts configuration panel when sync is disabled | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | actionsCell | Styles applied to the root element of the cell with type="actions". | | - | aggregationColumnHeader | Styles applied to the root element of the column header when aggregated. | | - | aggregationColumnHeader--alignCenter | Styles applied to the root element of the header when aggregation if `headerAlign="center"`. | | - | aggregationColumnHeader--alignLeft | Styles applied to the root element of the header when aggregation if `headerAlign="left"`. | | - | aggregationColumnHeader--alignRight | Styles applied to the root element of the header when aggregation if `headerAlign="right"`. | | - | aggregationColumnHeaderLabel | Styles applied to the aggregation label in the column header when aggregated. | | - | aggregationRowOverlayWrapper | Styles applied to the aggregation row overlay wrapper. | | - | aiAssistantPanelBody | Styles applied to the AI assistant panel body. | | - | aiAssistantPanelConversation | Styles applied to the AI assistant panel conversation. | | - | aiAssistantPanelConversationList | Styles applied to the AI assistant panel conversation list. | | - | aiAssistantPanelConversationTitle | Styles applied to the AI assistant panel conversation title. | | - | aiAssistantPanelEmptyText | Styles applied to the AI assistant panel empty text. | | - | aiAssistantPanelFooter | Styles applied to the AI assistant panel footer. | | - | aiAssistantPanelHeader | Styles applied to the AI assistant panel header. | | - | aiAssistantPanelSuggestions | Styles applied to the AI assistant panel suggestions. | | - | aiAssistantPanelSuggestionsItem | Styles applied to the AI assistant panel suggestions item. | | - | aiAssistantPanelSuggestionsLabel | Styles applied to the AI assistant panel suggestions label. | | - | aiAssistantPanelSuggestionsList | Styles applied to the AI assistant panel suggestions list. | | - | aiAssistantPanelTitle | Styles applied to the AI assistant panel title. | | - | aiAssistantPanelTitleContainer | Styles applied to the AI assistant panel title container. | | - | autoHeight | Styles applied to the root element if `autoHeight={true}`. | | - | autosizing | Styles applied to the root element while it is being autosized. | | - | booleanCell | Styles applied to the icon of the boolean cell. | | - | cell--editable | Styles applied to the cell element if the cell is editable. | | - | cell--editing | Styles applied to the cell element if the cell is in edit mode. | | - | cell--flex | Styles applied to the cell element in flex display mode. | | - | cell--pinnedLeft | Styles applied to the cell element if it is pinned to the left. | | - | cell--pinnedRight | Styles applied to the cell element if it is pinned to the right. | | - | cell--rangeBottom | Styles applied to the cell element if it is at the bottom edge of a cell selection range. | | - | cell--rangeLeft | Styles applied to the cell element if it is at the left edge of a cell selection range. | | - | cell--rangeRight | Styles applied to the cell element if it is at the right edge of a cell selection range. | | - | cell--rangeTop | Styles applied to the cell element if it is at the top edge of a cell selection range. | | - | cell--selectionMode | Styles applied to the cell element if it is in a cell selection range. | | - | cell--textCenter | Styles applied to the cell element if `align="center"`. | | - | cell--textLeft | Styles applied to the cell element if `align="left"`. | | - | cell--textRight | Styles applied to the cell element if `align="right"`. | | - | cell--withLeftBorder | Styles applied the cell if `showColumnVerticalBorder={true}`. | | - | cell--withRightBorder | Styles applied the cell if `showColumnVerticalBorder={true}`. | | - | cellCheckbox | Styles applied to the cell checkbox element. | | - | cellEmpty | Styles applied to the empty cell element. | | - | cellSkeleton | Styles applied to the skeleton cell element. | | - | checkboxInput | Styles applied to the selection checkbox element. | | - | collapsible | Styles applied to the collapsible element. | | - | collapsiblePanel | Styles applied to the collapsible panel element. | | - | collapsibleTrigger | Styles applied to the collapsible trigger element. | | - | columnHeader | Styles applied to the column header element. | | - | columnHeader--alignCenter | Styles applied to the column header if `headerAlign="center"`. | | - | columnHeader--alignLeft | Styles applied to the column header if `headerAlign="left"`. | | - | columnHeader--alignRight | Styles applied to the column header if `headerAlign="right"`. | | - | columnHeader--dragging | Styles applied to the floating column header element when it is dragged. | | - | columnHeader--emptyGroup | Styles applied to the empty column group header cell. | | - | columnHeader--filledGroup | Styles applied to the column group header cell if not empty. | | - | columnHeader--filter | Styles applied to the header filter cell. | | - | columnHeader--filtered | Styles applied to the column header if the column has a filter applied to it. | | - | columnHeader--last | Styles applied to the last column header element. | | - | columnHeader--moving | Styles applied to the column header if it is being dragged. | | - | columnHeader--numeric | Styles applied to the column header if the type of the column is `number`. | | - | columnHeader--pinnedLeft | | | - | columnHeader--pinnedRight | | | - | columnHeader--sortable | Styles applied to the column header if the column is sortable. | | - | columnHeader--sorted | Styles applied to the column header if the column is sorted. | | - | columnHeader--withLeftBorder | | | - | columnHeader--withRightBorder | Styles applied the column header if `showColumnVerticalBorder={true}`. | | - | columnHeaderCheckbox | Styles applied to the header checkbox cell element. | | - | columnHeaderDraggableContainer | Styles applied to the column header's draggable container element. | | - | columnHeaderFilterInput | Styles applied to the header filter input element. | | - | columnHeaderFilterOperatorLabel | Styles applied to the header filter operator label element. | | - | columnHeaderTitle | Styles applied to the column header's title element; | | - | columnHeaderTitleContainer | Styles applied to the column header's title container element. | | - | columnHeaderTitleContainerContent | Styles applied to the column header's title excepted buttons. | | - | columnSeparator | Styles applied to the column header separator element. | | - | columnSeparator--resizable | Styles applied to the column header separator if the column is resizable. | | - | columnSeparator--resizing | Styles applied to the column header separator if the column is being resized. | | - | columnSeparator--sideLeft | Styles applied to the column header separator if the side is "left". | | - | columnSeparator--sideRight | Styles applied to the column header separator if the side is "right". | | - | columnsManagementEmptyText | Styles applied to the columns management empty text element. | | - | columnsManagementFooter | Styles applied to the columns management footer element. | | - | columnsManagementHeader | Styles applied to the columns management header element. | | - | columnsManagementRow | Styles applied to the columns management row element. | | - | columnsManagementScrollArea | Styles applied to the columns management scroll area element. | | - | columnsManagementSearchInput | Styles applied to the columns management search input element. | | - | container--bottom | Styles applied to the bottom container. | | - | container--top | Styles applied to the top container. | | - | detailPanel | Styles applied to the detail panel element. | | - | detailPanelToggleCell | Styles applied to the detail panel toggle cell element. | | - | detailPanelToggleCell--expanded | Styles applied to the detail panel toggle cell element if expanded. | | - | editBooleanCell | Styles applied to root of the boolean edit component. | | - | editInputCell | Styles applied to the root of the input component. | | - | editLongTextCell | Styles applied to the edit long text cell root element. | | - | editLongTextCellPopperContent | Styles applied to the edit long text cell popper content. | | - | editLongTextCellPopup | Styles applied to the edit long text cell popup. | | - | editLongTextCellTextarea | Styles applied to the edit long text cell textarea. | | - | editLongTextCellValue | Styles applied to the edit long text cell value element. | | - | filterForm | Styles applied to the root of the filter form component. | | - | filterFormColumnInput | Styles applied to the column input of the filter form component. | | - | filterFormDeleteIcon | Styles applied to the delete icon of the filter form component. | | - | filterFormLogicOperatorInput | Styles applied to the link operator input of the filter form component. | | - | filterFormOperatorInput | Styles applied to the operator input of the filter form component. | | - | filterFormValueInput | Styles applied to the value input of the filter form component. | | - | filterIcon | Styles applied to the filter icon element. | | - | footerCell | Styles applied to the root element of the cell inside a footer row. | | - | footerContainer | Styles applied to the footer container element. | | - | groupingCriteriaCell | Styles applied to the root element of the grouping criteria cell | | - | groupingCriteriaCellToggle | Styles applied to the toggle of the grouping criteria cell | | - | headerFilterRow | Styles applied to the column header filter row. | | - | iconButtonContainer | Styles applied to the column header icon's container. | | - | iconSeparator | Styles applied to the column header separator icon element. | | - | longTextCell | Styles applied to the long text cell root element. | | - | longTextCellCollapseButton | Styles applied to the long text cell collapse button. | | - | longTextCellContent | Styles applied to the long text cell content element. | | - | longTextCellExpandButton | Styles applied to the long text cell expand button. | | - | longTextCellPopperContent | Styles applied to the long text cell popper content. | | - | longTextCellPopup | Styles applied to the long text cell popup. | | - | main | Styles applied to the main container element. | | - | main--hasPinnedRight | Styles applied to the main container element when it has right pinned columns. | | - | mainContent | | | - | menu | Styles applied to the menu element. | | - | menuIcon | Styles applied to the menu icon element. | | - | menuIconButton | Styles applied to the menu icon button element. | | - | menuList | Styles applied to the menu list element. | | - | menuOpen | Styles applied to the menu icon element if the menu is open. | | - | overlay | Styles applied to the overlay element. | | - | overlayWrapper | Styles applied to the overlay wrapper element. | | - | overlayWrapperInner | Styles applied to the overlay wrapper inner element. | | - | panelContent | Styles applied to the panel content element. | | - | panelFooter | Styles applied to the panel footer element. | | - | panelHeader | Styles applied to the panel header element. | | - | panelWrapper | Styles applied to the panel wrapper element. | | - | paper | Styles applied to the paper element. | | - | pinnedRows | Styles applied to the pinned rows container. | | - | pinnedRows--bottom | Styles applied to the bottom pinned rows container. | | - | pinnedRows--top | Styles applied to the top pinned rows container. | | - | pivotPanelAvailableFields | Styles applied to the pivot panel available fields. | | - | pivotPanelBody | Styles applied to the pivot panel body. | | - | pivotPanelField | Styles applied to the pivot panel field. | | - | pivotPanelField--sorted | Styles applied to the pivot panel field when sorted. | | - | pivotPanelFieldActionContainer | Styles applied to the pivot panel field action container. | | - | pivotPanelFieldCheckbox | Styles applied to the pivot panel field checkbox. | | - | pivotPanelFieldDragIcon | Styles applied to the pivot panel field drag icon. | | - | pivotPanelFieldList | Styles applied to the pivot panel field list. | | - | pivotPanelFieldName | Styles applied to the pivot panel field name. | | - | pivotPanelHeader | Styles applied to the pivot panel header. | | - | pivotPanelPlaceholder | Styles applied to the pivot panel placeholder. | | - | pivotPanelScrollArea | Styles applied to the pivot panel scroll area. | | - | pivotPanelSearchContainer | Styles applied to the pivot panel search container. | | - | pivotPanelSection | Styles applied to the pivot panel section. | | - | pivotPanelSections | Styles applied to the pivot panel sections. | | - | pivotPanelSectionTitle | Styles applied to the pivot panel section title. | | - | pivotPanelSwitch | Styles applied to the pivot panel switch. | | - | pivotPanelSwitchLabel | Styles applied to the pivot panel switch label. | | - | prompt | Styles applied to the prompt root element. | | - | promptAction | Styles applied to the prompt action element. | | - | promptChangeList | Styles applied to the prompt change list element. | | - | promptChangesToggle | Styles applied to the prompt changes toggle element. | | - | promptContent | Styles applied to the prompt content element. | | - | promptError | Styles applied to the prompt error element. | | - | promptFeedback | Styles applied to the prompt feedback element. | | - | promptIconContainer | Styles applied to the prompt icon element. | | - | promptText | Styles applied to the prompt text element. | | - | resizablePanelHandle | Styles applied to resizable panel handles. | | - | resizablePanelHandle--horizontal | Styles applied to horizontal resizable panel handles. | | - | resizablePanelHandle--vertical | Styles applied to vertical resizable panel handles. | | - | root | Styles applied to the root element. | | - | root--densityComfortable | Styles applied to the root element if density is "comfortable". | | - | root--densityCompact | Styles applied to the root element if density is "compact". | | - | root--densityStandard | Styles applied to the root element if density is "standard" (default). | | - | root--disableUserSelection | Styles applied to the root element when user selection is disabled. | | - | row--beingDragged | Styles applied to the row element when it is being dragged (entire row). | | - | row--detailPanelExpanded | Styles applied to the row if its detail panel is open. | | - | row--dragging | Styles applied to the floating special row reorder cell element when it is dragged. | | - | row--dynamicHeight | Styles applied to the row if it has dynamic row height. | | - | row--editable | Styles applied to the row element if the row is editable. | | - | row--editing | Styles applied to the row element if the row is in edit mode. | | - | row--firstVisible | Styles applied to the first visible row element on every page of the grid. | | - | row--lastVisible | Styles applied to the last visible row element on every page of the grid. | | - | rowCount | Styles applied to the footer row count element to show the total number of rows. Only works when pagination is disabled. | | - | rowReorderCell | Styles applied to the root element of the row reorder cell | | - | rowReorderCell--draggable | Styles applied to the root element of the row reorder cell when dragging is allowed | | - | rowReorderCellContainer | Styles applied to the row reorder cell container element. | | - | rowReorderCellPlaceholder | Styles applied to the row's draggable placeholder element inside the special row reorder cell. | | - | rowSkeleton | Styles applied to the skeleton row element. | | - | scrollArea | Styles applied to both scroll area elements. | | - | scrollArea--down | Styles applied to the bottom scroll area element. | | - | scrollArea--left | Styles applied to the left scroll area element. | | - | scrollArea--right | Styles applied to the right scroll area element. | | - | scrollArea--up | Styles applied to the top scroll area element. | | - | scrollbar | Styles applied to the scrollbars. | | - | scrollbar--horizontal | Styles applied to the horizontal scrollbar. | | - | scrollbar--vertical | Styles applied to the horizontal scrollbar. | | - | scrollShadow | Styles applied to the scroll shadow element. | | - | scrollShadow--horizontal | Styles applied to the horizontal scroll shadow element. | | - | scrollShadow--vertical | Styles applied to the vertical scroll shadow element. | | - | selectedRowCount | Styles applied to the footer selected row count element. | | - | sidebar | Styles applied to the sidebar element. | | - | sidebarHeader | Styles applied to the sidebar header element. | | - | sortButton | Styles applied to the sort button element. | | - | sortIcon | Styles applied to the sort button icon element. | | - | toolbarContainer | Styles applied to the toolbar container element. | | - | toolbarDivider | Styles applied to the toolbar divider element. | | - | toolbarFilterList | Styles applied to the toolbar filter list element. | | - | toolbarLabel | Styles applied to the toolbar label element. | | - | toolbarQuickFilter | Styles applied to the toolbar quick filter root element. | | - | toolbarQuickFilterControl | Styles applied to the toolbar quick filter control element. | | - | toolbarQuickFilterTrigger | Styles applied to the toolbar quick filter trigger element. | | - | treeDataGroupingCell | Styles applied to the root of the grouping column of the tree data. | | - | treeDataGroupingCellToggle | Styles applied to the toggle of the grouping cell of the tree data. | | - | virtualScroller | Styles applied to the virtualization container. | | - | virtualScrollerContent | Styles applied to the virtualization content. | | - | virtualScrollerContent--overflowed | Styles applied to the virtualization content when its height is bigger than the virtualization container. | | - | virtualScrollerRenderZone | Styles applied to the virtualization render zone. | | - | withBorderColor | Styles applied to cells, column header and other elements that have border. Sets border color only. | | - | withSidePanel | | | - | withVerticalBorder | Styles applied the grid if `showColumnVerticalBorder={true}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/DataGridPremium/DataGridPremium.tsx) --- # Source: https://mui.com/x/api/data-grid/data-grid-pro.md # DataGridPro API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { DataGridPro } from '@mui/x-data-grid-pro/DataGridPro'; // or import { DataGridPro } from '@mui/x-data-grid-pro'; // or import { DataGridPro } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | columns | `Array` | - | Yes | | | apiRef | `{ current?: object }` | - | No | | | aria-label | `string` | - | No | | | aria-labelledby | `string` | - | No | | | autoHeight | `bool` | `false` | No | | | autoPageSize | `bool` | `false` | No | | | autosizeOnMount | `bool` | `false` | No | | | autosizeOptions | `{ columns?: Array, disableColumnVirtualization?: bool, expand?: bool, includeHeaderFilters?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }` | - | No | | | cellModesModel | `object` | - | No | | | checkboxSelection | `bool` | `false` | No | | | checkboxSelectionVisibleOnly | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | clipboardCopyCellDelimiter | `string` | `'\t'` | No | | | columnBufferPx | `number` | `150` | No | | | columnFilterDebounceMs | `number` | `150` | No | | | columnGroupHeaderHeight | `number` | - | No | | | columnHeaderHeight | `number` | `56` | No | | | columnVisibilityModel | `object` | - | No | | | dataSource | `{ getChildrenCount?: func, getGroupKey?: func, getRows: func, updateRow?: func }` | - | No | | | dataSourceCache | `{ clear: func, get: func, set: func }` | - | No | | | defaultGroupingExpansionDepth | `number` | `0` | No | | | density | `'comfortable' \| 'compact' \| 'standard'` | `"standard"` | No | | | detailPanelExpandedRowIds | `Set` | - | No | | | disableAutosize | `bool` | `false` | No | | | disableChildrenFiltering | `bool` | `false` | No | | | disableChildrenSorting | `bool` | `false` | No | | | disableColumnFilter | `bool` | `false` | No | | | disableColumnMenu | `bool` | `false` | No | | | disableColumnPinning | `bool` | `false` | No | | | disableColumnReorder | `bool` | `false` | No | | | disableColumnResize | `bool` | `false` | No | | | disableColumnSelector | `bool` | `false` | No | | | disableColumnSorting | `bool` | `false` | No | | | disableDensitySelector | `bool` | `false` | No | | | disableEval | `bool` | `false` | No | | | disableMultipleColumnsFiltering | `bool` | `false` | No | | | disableMultipleColumnsSorting | `bool` | `false` | No | | | disableMultipleRowSelection | `bool` | `false (`!props.checkboxSelection` for MIT Data Grid)` | No | | | disableRowSelectionExcludeModel | `bool` | `false` | No | | | disableRowSelectionOnClick | `bool` | `false` | No | | | disableVirtualization | `bool` | `false` | No | | | editMode | `'cell' \| 'row'` | `"cell"` | No | | | estimatedRowCount | `number` | - | No | | | experimentalFeatures | `{ warnIfFocusStateIsNotSynced?: bool }` | - | No | | | filterDebounceMs | `number` | `150` | No | | | filterMode | `'client' \| 'server'` | `"client"` | No | | | filterModel | `{ items: Array<{ field: string, id?: number \| string, operator: string, value?: any }>, logicOperator?: 'and' \| 'or', quickFilterExcludeHiddenColumns?: bool, quickFilterLogicOperator?: 'and' \| 'or', quickFilterValues?: array }` | - | No | | | getCellClassName | `function(params: GridCellParams) => string` | - | No | | | getDetailPanelContent | `function(params: GridRowParams) => React.JSX.Element` | - | No | | | getDetailPanelHeight | `function(params: GridRowParams) => number \| string` | `"() => 500"` | No | | | getEstimatedRowHeight | `function(params: GridRowHeightParams) => number \| null` | - | No | | | getRowClassName | `function(params: GridRowClassNameParams) => string` | - | No | | | getRowHeight | `function(params: GridRowHeightParams) => GridRowHeightReturnValue` | - | No | | | getRowId | `func` | - | No | | | getRowSpacing | `function(params: GridRowSpacingParams) => GridRowSpacing` | - | No | | | getTreeDataPath | `function(row: R) => Array` | - | No | | | groupingColDef | `func \| object` | - | No | | | headerFilterHeight | `number` | - | No | | | headerFilters | `bool` | `false` | No | | | hideFooter | `bool` | `false` | No | | | hideFooterPagination | `bool` | `false` | No | | | hideFooterRowCount | `bool` | `false` | No | | | hideFooterSelectedRowCount | `bool` | `false` | No | | | ignoreDiacritics | `bool` | `false` | No | | | ignoreValueFormatterDuringExport | `{ clipboardExport?: bool, csvExport?: bool } \| bool` | `false` | No | | | initialState | `object` | - | No | | | isCellEditable | `function(params: GridCellParams) => boolean` | - | No | | | isGroupExpandedByDefault | `function(node: GridGroupNode) => boolean` | - | No | | | isRowReorderable | `function(params: object, params.row: R, params.rowNode: GridTreeNode) => boolean` | - | No | | | isRowSelectable | `function(params: GridRowParams) => boolean` | - | No | | | isValidRowReorder | `function(context: ReorderValidationContext) => boolean` | - | No | | | keepColumnPositionIfDraggedOutside | `bool` | `false` | No | | | keepNonExistentRowsSelected | `bool` | `false` | No | | | label | `string` | - | No | | | lazyLoading | `bool` | `false` | No | | | lazyLoadingRequestThrottleMs | `number` | `500` | No | | | listView | `bool` | - | No | | | listViewColumn | `{ align?: 'center' \| 'left' \| 'right', cellClassName?: func \| string, display?: 'flex' \| 'text', field: string, renderCell?: func }` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | logger | `{ debug: func, error: func, info: func, warn: func }` | `console` | No | | | logLevel | `'debug' \| 'error' \| 'info' \| 'warn' \| false` | `"error" ("warn" in dev mode)` | No | | | multipleColumnsSortingMode | `'always' \| 'withModifierKey'` | `"withModifierKey"` | No | | | nonce | `string` | - | No | | | onCellClick | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellDoubleClick | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellEditStart | `function(params: GridCellParams, event: MuiEvent) => void` | - | No | | | onCellEditStop | `function(params: GridCellParams, event: MuiEvent) => void` | - | No | | | onCellKeyDown | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellModesModelChange | `function(cellModesModel: GridCellModesModel, details: GridCallbackDetails) => void` | - | No | | | onClipboardCopy | `function(data: string) => void` | - | No | | | onColumnHeaderClick | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderContextMenu | `function(params: GridColumnHeaderParams, event: MuiEvent) => void` | - | No | | | onColumnHeaderDoubleClick | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderEnter | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderLeave | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderOut | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderOver | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnOrderChange | `function(params: GridColumnOrderChangeParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onColumnResize | `function(params: GridColumnResizeParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnVisibilityModelChange | `function(model: GridColumnVisibilityModel, details: GridCallbackDetails) => void` | - | No | | | onColumnWidthChange | `function(params: GridColumnResizeParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onDataSourceError | `function(error: GridGetRowsError \| GridUpdateRowError) => void` | - | No | | | onDensityChange | `function(density: GridDensity) => void` | - | No | | | onDetailPanelExpandedRowIdsChange | `function(ids: Array, details: GridCallbackDetails) => void` | - | No | | | onFetchRows (deprecated) | `function(params: GridFetchRowsParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | ⚠️ Use the {@link [https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading](https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading) Server-side data-Viewport loading} instead. | | onFilterModelChange | `function(model: GridFilterModel, details: GridCallbackDetails) => void` | - | No | | | onMenuClose | `function(params: GridMenuParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onMenuOpen | `function(params: GridMenuParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onPaginationMetaChange | `function(paginationMeta: GridPaginationMeta) => void` | - | No | | | onPaginationModelChange | `function(model: GridPaginationModel, details: GridCallbackDetails) => void` | - | No | | | onPinnedColumnsChange | `function(pinnedColumns: GridPinnedColumnFields, details: GridCallbackDetails) => void` | - | No | | | onPreferencePanelClose | `function(params: GridPreferencePanelParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onPreferencePanelOpen | `function(params: GridPreferencePanelParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onProcessRowUpdateError | `function(error: any) => void` | - | No | | | onResize | `function(containerSize: ElementSize, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onRowClick | `function(params: GridRowParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onRowCountChange | `function(count: number) => void` | - | No | | | onRowDoubleClick | `function(params: GridRowParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onRowEditStart | `function(params: GridRowParams, event: MuiEvent) => void` | - | No | | | onRowEditStop | `function(params: GridRowParams, event: MuiEvent) => void` | - | No | | | onRowModesModelChange | `function(rowModesModel: GridRowModesModel, details: GridCallbackDetails) => void` | - | No | | | onRowOrderChange | `function(params: GridRowOrderChangeParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onRowSelectionModelChange | `function(rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails) => void` | - | No | | | onRowsScrollEnd (deprecated) | `function(params: GridRowScrollEndParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | ⚠️ Use the {@link [https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#infinite-loading](https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#infinite-loading) Server-side data-Infinite loading} instead. | | onSortModelChange | `function(model: GridSortModel, details: GridCallbackDetails) => void` | - | No | | | pageSizeOptions | `Array` | `[25, 50, 100]` | No | | | pagination | `bool` | `false` | No | | | paginationMeta | `{ hasNextPage?: bool }` | - | No | | | paginationMode | `'client' \| 'server'` | `"client"` | No | | | paginationModel | `{ page: number, pageSize: number }` | - | No | | | pinnedColumns | `object` | - | No | | | pinnedColumnsSectionSeparator | `'border-and-shadow' \| 'border' \| 'shadow'` | `'border-and-shadow'` | No | | | pinnedRows | `{ bottom?: Array, top?: Array }` | - | No | | | pinnedRowsSectionSeparator | `'border-and-shadow' \| 'border'` | `'border-and-shadow'` | No | | | processRowUpdate | `function(newRow: R, oldRow: R, params: { rowId: GridRowId }) => Promise \| R` | - | No | | | resizeThrottleMs | `number` | `60` | No | | | rowBufferPx | `number` | `150` | No | | | rowCount | `number` | - | No | | | rowHeight | `number` | `52` | No | | | rowModesModel | `object` | - | No | | | rowReordering | `bool` | `false` | No | | | rows | `Array` | `[]` | No | | | rowSelection | `bool` | `true` | No | | | rowSelectionModel | `{ ids: Set, type: 'exclude' \| 'include' }` | - | No | | | rowSelectionPropagation | `{ descendants?: bool, parents?: bool }` | `{ parents: true, descendants: true }` | No | | | rowsLoadingMode (deprecated) | `'client' \| 'server'` | `"client"` | No | ⚠️ Use the {@link [https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading](https://mui.com/x/react-data-grid/server-side-data/lazy-loading/#viewport-loading) Server-side data-Viewport loading} instead. | | rowSpacingType | `'border' \| 'margin'` | `"margin"` | No | | | rowSpanning | `bool` | `false` | No | | | scrollbarSize | `number` | - | No | | | scrollEndThreshold | `number` | `80` | No | | | setTreeDataPath | `function(path: Array, row: R) => R` | - | No | | | showCellVerticalBorder | `bool` | `false` | No | | | showColumnVerticalBorder | `bool` | `false` | No | | | showToolbar | `bool` | `false` | No | | | slotProps | `object` | - | No | | | slots | `object` | - | No | | | sortingMode | `'client' \| 'server'` | `"client"` | No | | | sortingOrder | `Array<'asc' \| 'desc'>` | `['asc', 'desc', null]` | No | | | sortModel | `Array<{ field: string, sort?: 'asc' \| 'desc' }>` | - | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | tabNavigation | `'all' \| 'content' \| 'header' \| 'none'` | `"none"` | No | | | throttleRowsMs | `number` | `0` | No | | | treeData | `bool` | `false` | No | | | virtualizeColumnsWithAutoRowHeight | `bool` | `false` | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | headerFilterCell | `GridHeaderFilterCell` | - | Component responsible for showing menu adornment in Header filter row | | headerFilterMenu | `GridHeaderFilterMenu` | - | Component responsible for showing menu in Header filter row | | bottomContainer | `GridBottomContainer` | - | Component rendered for the bottom container. | | cell | `GridCell` | `.MuiDataGridPro-cell` | Component rendered for each cell. | | skeletonCell | `GridSkeletonCell` | - | Component rendered for each skeleton cell. | | columnHeaderFilterIconButton | `GridColumnHeaderFilterIconButton` | - | Filter icon component rendered in each column header. | | columnHeaderSortIcon | `GridColumnHeaderSortIcon` | - | Sort icon component rendered in each column header. | | columnMenu | `GridColumnMenu` | - | Column menu component rendered by clicking on the 3 dots "kebab" icon in column headers. | | columnHeaders | `GridColumnHeaders` | `.MuiDataGridPro-columnHeaders` | Component responsible for rendering the column headers. | | detailPanels | `GridDetailPanels` | - | Component responsible for rendering the detail panels. | | footer | `GridFooter` | - | Footer component rendered at the bottom of the grid viewport. | | footerRowCount | `GridRowCount` | - | Row count component rendered in the footer | | toolbar | `undefined` | `.MuiDataGridPro-toolbar` | Toolbar component rendered in the grid header. | | loadingOverlay | `GridLoadingOverlay` | - | Loading overlay component rendered when the grid is in a loading state. | | noResultsOverlay | `GridNoResultsOverlay` | - | No results overlay component rendered when the grid has no results after filtering. | | noRowsOverlay | `GridNoRowsOverlay` | - | No rows overlay component rendered when the grid has no rows. | | noColumnsOverlay | `GridNoColumnsOverlay` | - | No columns overlay component rendered when the grid has no columns. | | pagination | `Pagination` | - | Pagination component rendered in the grid footer by default. | | filterPanel | `GridFilterPanel` | - | Filter panel component rendered when clicking the filter button. | | columnsPanel | `GridColumnsPanel` | - | GridColumns panel component rendered when clicking the columns button. | | columnsManagement | `GridColumnsManagement` | `.MuiDataGridPro-columnsManagement` | Component used inside Grid Columns panel to manage columns. | | panel | `GridPanel` | `.MuiDataGridPro-panel` | Panel component wrapping the filters and columns panels. | | row | `GridRow` | `.MuiDataGridPro-row` | Component rendered for each row. | | baseAutocomplete | `Autocomplete` | - | The custom Autocomplete component used in the grid for both header and cells. | | baseBadge | `Badge` | - | The custom Badge component used in the grid for both header and cells. | | baseCheckbox | `Checkbox` | - | The custom Checkbox component used in the grid for both header and cells. | | baseChip | `Chip` | - | The custom Chip component used in the grid. | | baseCircularProgress | `CircularProgress` | - | The custom CircularProgress component used in the grid. | | baseDivider | `Divider` | - | The custom Divider component used in the grid. | | baseLinearProgress | `LinearProgress` | - | The custom LinearProgress component used in the grid. | | baseMenuList | `MenuList` | - | The custom MenuList component used in the grid. | | baseMenuItem | `MenuItem` | - | The custom MenuItem component used in the grid. | | baseTextField | `TextField` | - | The custom TextField component used in the grid. | | baseSelect | `Select` | - | The custom Select component used in the grid. | | baseButton | `Button` | - | The custom Button component used in the grid. | | baseIconButton | `IconButton` | - | The custom IconButton component used in the grid. | | baseInput | `Input` | - | The custom Input component used in the grid. | | baseTextarea | `InputBase with multiline` | - | The custom Textarea component used in the grid for multiline text editing. | | baseToggleButton | `ToggleButton` | - | The custom ToggleButton component used in the grid. | | baseTooltip | `Tooltip` | - | The custom Tooltip component used in the grid. | | basePagination | `Pagination` | - | The custom Pagination component used in the grid. | | basePopper | `Popper` | - | The custom Popper component used in the grid. | | baseSelectOption | `SelectOption` | - | The custom SelectOption component used in the grid. | | baseSkeleton | `Skeleton` | - | The custom Skeleton component used in the grid. | | baseSwitch | `Switch` | - | The custom Switch component used in the grid. | | baseTabs | `Tabs` | - | The custom Tabs component used in the grid. | | booleanCellTrueIcon | `GridCheckIcon` | - | Icon displayed on the boolean cell to represent the true value. | | booleanCellFalseIcon | `GridCloseIcon` | - | Icon displayed on the boolean cell to represent the false value. | | undoIcon | `GridUndoIcon` | - | Icon displayed on the undo button in the toolbar. | | redoIcon | `GridRedoIcon` | - | Icon displayed on the redo button in the toolbar. | | columnMenuIcon | `GridTripleDotsVerticalIcon` | - | Icon displayed on the side of the column header title to display the filter input component. | | openFilterButtonIcon | `GridFilterListIcon` | - | Icon displayed on the open filter button present in the toolbar by default. | | columnFilteredIcon | `GridFilterAltIcon` | - | Icon displayed on the column header menu to show that a filter has been applied to the column. | | columnSelectorIcon | `GridColumnIcon` | - | Icon displayed on the column menu selector tab. | | columnUnsortedIcon | `GridColumnUnsortedIcon` | - | Icon displayed on the side of the column header title when unsorted. | | columnSortedAscendingIcon | `GridArrowUpwardIcon` | - | Icon displayed on the side of the column header title when sorted in ascending order. | | columnSortedDescendingIcon | `GridArrowDownwardIcon` | - | Icon displayed on the side of the column header title when sorted in descending order. | | columnResizeIcon | `GridSeparatorIcon` | - | Icon displayed in between two column headers that allows to resize the column header. | | densityCompactIcon | `GridViewHeadlineIcon` | - | Icon displayed on the compact density option in the toolbar. | | densityStandardIcon | `GridTableRowsIcon` | - | Icon displayed on the standard density option in the toolbar. | | densityComfortableIcon | `GridViewStreamIcon` | - | Icon displayed on the "comfortable" density option in the toolbar. | | exportIcon | `GridDownloadIcon` | - | Icon displayed on the open export button present in the toolbar by default. | | moreActionsIcon | `GridMoreVertIcon` | - | Icon displayed on the `actions` column type to open the menu. | | treeDataExpandIcon | `GridKeyboardArrowRight` | - | Icon displayed on the tree data toggling column when the children are collapsed | | treeDataCollapseIcon | `GridExpandMoreIcon` | - | Icon displayed on the tree data toggling column when the children are expanded | | groupingCriteriaExpandIcon | `GridKeyboardArrowRight` | - | Icon displayed on the grouping column when the children are collapsed | | groupingCriteriaCollapseIcon | `GridExpandMoreIcon` | - | Icon displayed on the grouping column when the children are expanded | | detailPanelExpandIcon | `GridAddIcon` | - | Icon displayed on the detail panel toggle column when collapsed. | | detailPanelCollapseIcon | `GridRemoveIcon` | - | Icon displayed on the detail panel toggle column when expanded. | | filterPanelAddIcon | `GridAddIcon` | - | Icon displayed for deleting the filter from filter panel. | | filterPanelDeleteIcon | `GridDeleteIcon` | - | Icon displayed for deleting the filter from filter panel. | | filterPanelRemoveAllIcon | `GridDeleteForeverIcon` | - | Icon displayed for deleting all the active filters from filter panel. | | rowReorderIcon | `GridDragIcon` | `.MuiDataGridPro-rowReorderIcon` | Icon displayed on the `reorder` column type to reorder a row. | | quickFilterIcon | `GridSearchIcon` | - | Icon displayed on the quick filter input. | | quickFilterClearIcon | `GridCloseIcon` | - | Icon displayed on the quick filter reset input. | | columnMenuHideIcon | `GridVisibilityOffIcon` | - | Icon displayed in column menu for hiding column | | columnMenuSortAscendingIcon | `GridArrowUpwardIcon` | - | Icon displayed in column menu for ascending sort | | columnMenuSortDescendingIcon | `GridArrowDownwardIcon` | - | Icon displayed in column menu for descending sort | | columnMenuUnsortIcon | `null` | - | Icon displayed in column menu for unsort | | columnMenuFilterIcon | `GridFilterAltIcon` | - | Icon displayed in column menu for filter | | columnMenuManageColumnsIcon | `GridViewColumnIcon` | - | Icon displayed in column menu for showing all columns | | columnMenuClearIcon | `GridClearIcon` | - | Icon displayed in column menu for clearing values | | loadIcon | `GridLoadIcon` | - | Icon displayed on the input while processing. | | columnReorderIcon | `GridDragIcon` | - | Icon displayed on the column reorder button. | | menuItemCheckIcon | `GridCheckIcon` | - | Icon displayed to indicate that a menu item is selected. | | longTextCellExpandIcon | `GridLongTextCellExpandIcon` | - | Icon displayed on the long text cell to expand the content. | | longTextCellCollapseIcon | `GridLongTextCellCollapseIcon` | - | Icon displayed on the long text cell popup to collapse the content. | | columnMenuPinLeftIcon | `GridPushPinLeftIcon` | - | Icon displayed in column menu for left pinning | | columnMenuPinRightIcon | `GridPushPinRightIcon` | - | Icon displayed in column menu for right pinning | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | actionsCell | Styles applied to the root element of the cell with type="actions". | | - | aggregationColumnHeader | Styles applied to the root element of the column header when aggregated. | | - | aggregationColumnHeader--alignCenter | Styles applied to the root element of the header when aggregation if `headerAlign="center"`. | | - | aggregationColumnHeader--alignLeft | Styles applied to the root element of the header when aggregation if `headerAlign="left"`. | | - | aggregationColumnHeader--alignRight | Styles applied to the root element of the header when aggregation if `headerAlign="right"`. | | - | aggregationColumnHeaderLabel | Styles applied to the aggregation label in the column header when aggregated. | | - | aggregationRowOverlayWrapper | Styles applied to the aggregation row overlay wrapper. | | - | aiAssistantPanel | Styles applied to the root element of the AI assistant panel. | | - | aiAssistantPanelBody | Styles applied to the AI assistant panel body. | | - | aiAssistantPanelConversation | Styles applied to the AI assistant panel conversation. | | - | aiAssistantPanelConversationList | Styles applied to the AI assistant panel conversation list. | | - | aiAssistantPanelConversationTitle | Styles applied to the AI assistant panel conversation title. | | - | aiAssistantPanelEmptyText | Styles applied to the AI assistant panel empty text. | | - | aiAssistantPanelFooter | Styles applied to the AI assistant panel footer. | | - | aiAssistantPanelHeader | Styles applied to the AI assistant panel header. | | - | aiAssistantPanelSuggestions | Styles applied to the AI assistant panel suggestions. | | - | aiAssistantPanelSuggestionsItem | Styles applied to the AI assistant panel suggestions item. | | - | aiAssistantPanelSuggestionsLabel | Styles applied to the AI assistant panel suggestions label. | | - | aiAssistantPanelSuggestionsList | Styles applied to the AI assistant panel suggestions list. | | - | aiAssistantPanelTitle | Styles applied to the AI assistant panel title. | | - | aiAssistantPanelTitleContainer | Styles applied to the AI assistant panel title container. | | - | autoHeight | Styles applied to the root element if `autoHeight={true}`. | | - | autosizing | Styles applied to the root element while it is being autosized. | | - | booleanCell | Styles applied to the icon of the boolean cell. | | - | cell--editable | Styles applied to the cell element if the cell is editable. | | - | cell--editing | Styles applied to the cell element if the cell is in edit mode. | | - | cell--flex | Styles applied to the cell element in flex display mode. | | - | cell--pinnedLeft | Styles applied to the cell element if it is pinned to the left. | | - | cell--pinnedRight | Styles applied to the cell element if it is pinned to the right. | | - | cell--rangeBottom | Styles applied to the cell element if it is at the bottom edge of a cell selection range. | | - | cell--rangeLeft | Styles applied to the cell element if it is at the left edge of a cell selection range. | | - | cell--rangeRight | Styles applied to the cell element if it is at the right edge of a cell selection range. | | - | cell--rangeTop | Styles applied to the cell element if it is at the top edge of a cell selection range. | | - | cell--selectionMode | Styles applied to the cell element if it is in a cell selection range. | | - | cell--textCenter | Styles applied to the cell element if `align="center"`. | | - | cell--textLeft | Styles applied to the cell element if `align="left"`. | | - | cell--textRight | Styles applied to the cell element if `align="right"`. | | - | cell--withLeftBorder | Styles applied the cell if `showColumnVerticalBorder={true}`. | | - | cell--withRightBorder | Styles applied the cell if `showColumnVerticalBorder={true}`. | | - | cellCheckbox | Styles applied to the cell checkbox element. | | - | cellEmpty | Styles applied to the empty cell element. | | - | cellSkeleton | Styles applied to the skeleton cell element. | | - | checkboxInput | Styles applied to the selection checkbox element. | | - | collapsible | Styles applied to the collapsible element. | | - | collapsibleIcon | Styles applied to the collapsible icon element. | | - | collapsiblePanel | Styles applied to the collapsible panel element. | | - | collapsibleTrigger | Styles applied to the collapsible trigger element. | | - | columnHeader | Styles applied to the column header element. | | - | columnHeader--alignCenter | Styles applied to the column header if `headerAlign="center"`. | | - | columnHeader--alignLeft | Styles applied to the column header if `headerAlign="left"`. | | - | columnHeader--alignRight | Styles applied to the column header if `headerAlign="right"`. | | - | columnHeader--dragging | Styles applied to the floating column header element when it is dragged. | | - | columnHeader--emptyGroup | Styles applied to the empty column group header cell. | | - | columnHeader--filledGroup | Styles applied to the column group header cell if not empty. | | - | columnHeader--filter | Styles applied to the header filter cell. | | - | columnHeader--filtered | Styles applied to the column header if the column has a filter applied to it. | | - | columnHeader--last | Styles applied to the last column header element. | | - | columnHeader--moving | Styles applied to the column header if it is being dragged. | | - | columnHeader--numeric | Styles applied to the column header if the type of the column is `number`. | | - | columnHeader--pinnedLeft | | | - | columnHeader--pinnedRight | | | - | columnHeader--sortable | Styles applied to the column header if the column is sortable. | | - | columnHeader--sorted | Styles applied to the column header if the column is sorted. | | - | columnHeader--withLeftBorder | | | - | columnHeader--withRightBorder | Styles applied the column header if `showColumnVerticalBorder={true}`. | | - | columnHeaderCheckbox | Styles applied to the header checkbox cell element. | | - | columnHeaderDraggableContainer | Styles applied to the column header's draggable container element. | | - | columnHeaderFilterInput | Styles applied to the header filter input element. | | - | columnHeaderFilterOperatorLabel | Styles applied to the header filter operator label element. | | - | columnHeaderTitle | Styles applied to the column header's title element; | | - | columnHeaderTitleContainer | Styles applied to the column header's title container element. | | - | columnHeaderTitleContainerContent | Styles applied to the column header's title excepted buttons. | | - | columnSeparator | Styles applied to the column header separator element. | | - | columnSeparator--resizable | Styles applied to the column header separator if the column is resizable. | | - | columnSeparator--resizing | Styles applied to the column header separator if the column is being resized. | | - | columnSeparator--sideLeft | Styles applied to the column header separator if the side is "left". | | - | columnSeparator--sideRight | Styles applied to the column header separator if the side is "right". | | - | columnsManagementEmptyText | Styles applied to the columns management empty text element. | | - | columnsManagementFooter | Styles applied to the columns management footer element. | | - | columnsManagementHeader | Styles applied to the columns management header element. | | - | columnsManagementRow | Styles applied to the columns management row element. | | - | columnsManagementScrollArea | Styles applied to the columns management scroll area element. | | - | columnsManagementSearchInput | Styles applied to the columns management search input element. | | - | container--bottom | Styles applied to the bottom container. | | - | container--top | Styles applied to the top container. | | - | detailPanel | Styles applied to the detail panel element. | | - | detailPanelToggleCell | Styles applied to the detail panel toggle cell element. | | - | detailPanelToggleCell--expanded | Styles applied to the detail panel toggle cell element if expanded. | | - | editBooleanCell | Styles applied to root of the boolean edit component. | | - | editInputCell | Styles applied to the root of the input component. | | - | editLongTextCell | Styles applied to the edit long text cell root element. | | - | editLongTextCellPopperContent | Styles applied to the edit long text cell popper content. | | - | editLongTextCellPopup | Styles applied to the edit long text cell popup. | | - | editLongTextCellTextarea | Styles applied to the edit long text cell textarea. | | - | editLongTextCellValue | Styles applied to the edit long text cell value element. | | - | filterForm | Styles applied to the root of the filter form component. | | - | filterFormColumnInput | Styles applied to the column input of the filter form component. | | - | filterFormDeleteIcon | Styles applied to the delete icon of the filter form component. | | - | filterFormLogicOperatorInput | Styles applied to the link operator input of the filter form component. | | - | filterFormOperatorInput | Styles applied to the operator input of the filter form component. | | - | filterFormValueInput | Styles applied to the value input of the filter form component. | | - | filterIcon | Styles applied to the filter icon element. | | - | footerCell | Styles applied to the root element of the cell inside a footer row. | | - | footerContainer | Styles applied to the footer container element. | | - | groupingCriteriaCell | Styles applied to the root element of the grouping criteria cell | | - | groupingCriteriaCellToggle | Styles applied to the toggle of the grouping criteria cell | | - | headerFilterRow | Styles applied to the column header filter row. | | - | iconButtonContainer | Styles applied to the column header icon's container. | | - | iconSeparator | Styles applied to the column header separator icon element. | | - | longTextCell | Styles applied to the long text cell root element. | | - | longTextCellCollapseButton | Styles applied to the long text cell collapse button. | | - | longTextCellContent | Styles applied to the long text cell content element. | | - | longTextCellExpandButton | Styles applied to the long text cell expand button. | | - | longTextCellPopperContent | Styles applied to the long text cell popper content. | | - | longTextCellPopup | Styles applied to the long text cell popup. | | - | main | Styles applied to the main container element. | | - | main--hasPinnedRight | Styles applied to the main container element when it has right pinned columns. | | - | mainContent | | | - | menu | Styles applied to the menu element. | | - | menuIcon | Styles applied to the menu icon element. | | - | menuIconButton | Styles applied to the menu icon button element. | | - | menuList | Styles applied to the menu list element. | | - | menuOpen | Styles applied to the menu icon element if the menu is open. | | - | overlay | Styles applied to the overlay element. | | - | overlayWrapper | Styles applied to the overlay wrapper element. | | - | overlayWrapperInner | Styles applied to the overlay wrapper inner element. | | - | panelContent | Styles applied to the panel content element. | | - | panelFooter | Styles applied to the panel footer element. | | - | panelHeader | Styles applied to the panel header element. | | - | panelWrapper | Styles applied to the panel wrapper element. | | - | paper | Styles applied to the paper element. | | - | pinnedRows | Styles applied to the pinned rows container. | | - | pinnedRows--bottom | Styles applied to the bottom pinned rows container. | | - | pinnedRows--top | Styles applied to the top pinned rows container. | | - | pivotPanelAvailableFields | Styles applied to the pivot panel available fields. | | - | pivotPanelBody | Styles applied to the pivot panel body. | | - | pivotPanelField | Styles applied to the pivot panel field. | | - | pivotPanelField--sorted | Styles applied to the pivot panel field when sorted. | | - | pivotPanelFieldActionContainer | Styles applied to the pivot panel field action container. | | - | pivotPanelFieldCheckbox | Styles applied to the pivot panel field checkbox. | | - | pivotPanelFieldDragIcon | Styles applied to the pivot panel field drag icon. | | - | pivotPanelFieldList | Styles applied to the pivot panel field list. | | - | pivotPanelFieldName | Styles applied to the pivot panel field name. | | - | pivotPanelHeader | Styles applied to the pivot panel header. | | - | pivotPanelPlaceholder | Styles applied to the pivot panel placeholder. | | - | pivotPanelScrollArea | Styles applied to the pivot panel scroll area. | | - | pivotPanelSearchContainer | Styles applied to the pivot panel search container. | | - | pivotPanelSection | Styles applied to the pivot panel section. | | - | pivotPanelSections | Styles applied to the pivot panel sections. | | - | pivotPanelSectionTitle | Styles applied to the pivot panel section title. | | - | pivotPanelSwitch | Styles applied to the pivot panel switch. | | - | pivotPanelSwitchLabel | Styles applied to the pivot panel switch label. | | - | prompt | Styles applied to the prompt root element. | | - | promptAction | Styles applied to the prompt action element. | | - | promptChangeList | Styles applied to the prompt change list element. | | - | promptChangesToggle | Styles applied to the prompt changes toggle element. | | - | promptChangesToggleIcon | Styles applied to the prompt changes toggle icon element. | | - | promptContent | Styles applied to the prompt content element. | | - | promptError | Styles applied to the prompt error element. | | - | promptFeedback | Styles applied to the prompt feedback element. | | - | promptIcon | Styles applied to the prompt icon element. | | - | promptIconContainer | Styles applied to the prompt icon element. | | - | promptText | Styles applied to the prompt text element. | | - | resizablePanelHandle | Styles applied to resizable panel handles. | | - | resizablePanelHandle--horizontal | Styles applied to horizontal resizable panel handles. | | - | resizablePanelHandle--vertical | Styles applied to vertical resizable panel handles. | | - | root | Styles applied to the root element. | | - | root--densityComfortable | Styles applied to the root element if density is "comfortable". | | - | root--densityCompact | Styles applied to the root element if density is "compact". | | - | root--densityStandard | Styles applied to the root element if density is "standard" (default). | | - | root--disableUserSelection | Styles applied to the root element when user selection is disabled. | | - | row--beingDragged | Styles applied to the row element when it is being dragged (entire row). | | - | row--detailPanelExpanded | Styles applied to the row if its detail panel is open. | | - | row--dragging | Styles applied to the floating special row reorder cell element when it is dragged. | | - | row--dynamicHeight | Styles applied to the row if it has dynamic row height. | | - | row--editable | Styles applied to the row element if the row is editable. | | - | row--editing | Styles applied to the row element if the row is in edit mode. | | - | row--firstVisible | Styles applied to the first visible row element on every page of the grid. | | - | row--lastVisible | Styles applied to the last visible row element on every page of the grid. | | - | rowCount | Styles applied to the footer row count element to show the total number of rows. Only works when pagination is disabled. | | - | rowReorderCell | Styles applied to the root element of the row reorder cell | | - | rowReorderCell--draggable | Styles applied to the root element of the row reorder cell when dragging is allowed | | - | rowReorderCellContainer | Styles applied to the row reorder cell container element. | | - | rowReorderCellPlaceholder | Styles applied to the row's draggable placeholder element inside the special row reorder cell. | | - | rowSkeleton | Styles applied to the skeleton row element. | | - | scrollArea | Styles applied to both scroll area elements. | | - | scrollArea--down | Styles applied to the bottom scroll area element. | | - | scrollArea--left | Styles applied to the left scroll area element. | | - | scrollArea--right | Styles applied to the right scroll area element. | | - | scrollArea--up | Styles applied to the top scroll area element. | | - | scrollbar | Styles applied to the scrollbars. | | - | scrollbar--horizontal | Styles applied to the horizontal scrollbar. | | - | scrollbar--vertical | Styles applied to the horizontal scrollbar. | | - | scrollShadow | Styles applied to the scroll shadow element. | | - | scrollShadow--horizontal | Styles applied to the horizontal scroll shadow element. | | - | scrollShadow--vertical | Styles applied to the vertical scroll shadow element. | | - | selectedRowCount | Styles applied to the footer selected row count element. | | - | sidebar | Styles applied to the sidebar element. | | - | sidebarHeader | Styles applied to the sidebar header element. | | - | sortButton | Styles applied to the sort button element. | | - | sortIcon | Styles applied to the sort button icon element. | | - | toolbarContainer | Styles applied to the toolbar container element. | | - | toolbarDivider | Styles applied to the toolbar divider element. | | - | toolbarFilterList | Styles applied to the toolbar filter list element. | | - | toolbarLabel | Styles applied to the toolbar label element. | | - | toolbarQuickFilter | Styles applied to the toolbar quick filter root element. | | - | toolbarQuickFilterControl | Styles applied to the toolbar quick filter control element. | | - | toolbarQuickFilterTrigger | Styles applied to the toolbar quick filter trigger element. | | - | treeDataGroupingCell | Styles applied to the root of the grouping column of the tree data. | | - | treeDataGroupingCellToggle | Styles applied to the toggle of the grouping cell of the tree data. | | - | virtualScroller | Styles applied to the virtualization container. | | - | virtualScrollerContent | Styles applied to the virtualization content. | | - | virtualScrollerContent--overflowed | Styles applied to the virtualization content when its height is bigger than the virtualization container. | | - | virtualScrollerRenderZone | Styles applied to the virtualization render zone. | | - | withBorderColor | Styles applied to cells, column header and other elements that have border. Sets border color only. | | - | withSidePanel | | | - | withVerticalBorder | Styles applied the grid if `showColumnVerticalBorder={true}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-pro/src/DataGridPro/DataGridPro.tsx) --- # Source: https://mui.com/x/api/data-grid/data-grid.md # Source: https://mui.com/x/api/data-grid.md # DataGrid API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { DataGrid } from '@mui/x-data-grid/DataGrid'; // or import { DataGrid } from '@mui/x-data-grid'; // or import { DataGrid } from '@mui/x-data-grid-pro'; // or import { DataGrid } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | columns | `Array` | - | Yes | | | apiRef | `{ current?: object }` | - | No | | | aria-label | `string` | - | No | | | aria-labelledby | `string` | - | No | | | autoHeight (deprecated) | `bool` | `false` | No | ⚠️ Use flex parent container instead: [https://mui.com/x/react-data-grid/layout/#flex-parent-container](https://mui.com/x/react-data-grid/layout/#flex-parent-container) | | autoPageSize | `bool` | `false` | No | | | autosizeOnMount | `bool` | `false` | No | | | autosizeOptions | `{ columns?: Array, disableColumnVirtualization?: bool, expand?: bool, includeHeaders?: bool, includeOutliers?: bool, outliersFactor?: number }` | - | No | | | cellModesModel | `object` | - | No | | | checkboxSelection | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | clipboardCopyCellDelimiter | `string` | `'\t'` | No | | | columnBufferPx | `number` | `150` | No | | | columnFilterDebounceMs | `number` | `150` | No | | | columnGroupHeaderHeight | `number` | - | No | | | columnHeaderHeight | `number` | `56` | No | | | columnVisibilityModel | `object` | - | No | | | dataSource | `{ getRows: func, updateRow?: func }` | - | No | | | dataSourceCache | `{ clear: func, get: func, set: func }` | - | No | | | density | `'comfortable' \| 'compact' \| 'standard'` | `"standard"` | No | | | disableAutosize | `bool` | `false` | No | | | disableColumnFilter | `bool` | `false` | No | | | disableColumnMenu | `bool` | `false` | No | | | disableColumnResize | `bool` | `false` | No | | | disableColumnSelector | `bool` | `false` | No | | | disableColumnSorting | `bool` | `false` | No | | | disableDensitySelector | `bool` | `false` | No | | | disableEval | `bool` | `false` | No | | | disableMultipleRowSelection | `bool` | `false (`!props.checkboxSelection` for MIT Data Grid)` | No | | | disableRowSelectionExcludeModel | `bool` | `false` | No | | | disableRowSelectionOnClick | `bool` | `false` | No | | | disableVirtualization | `bool` | `false` | No | | | editMode | `'cell' \| 'row'` | `"cell"` | No | | | estimatedRowCount | `number` | - | No | | | experimentalFeatures | `{ warnIfFocusStateIsNotSynced?: bool }` | - | No | | | filterDebounceMs | `number` | `150` | No | | | filterMode | `'client' \| 'server'` | `"client"` | No | | | filterModel | `{ items: Array<{ field: string, id?: number \| string, operator: string, value?: any }>, logicOperator?: 'and' \| 'or', quickFilterExcludeHiddenColumns?: bool, quickFilterLogicOperator?: 'and' \| 'or', quickFilterValues?: array }` | - | No | | | getCellClassName | `function(params: GridCellParams) => string` | - | No | | | getDetailPanelContent | `function(params: GridRowParams) => React.JSX.Element` | - | No | | | getEstimatedRowHeight | `function(params: GridRowHeightParams) => number \| null` | - | No | | | getRowClassName | `function(params: GridRowClassNameParams) => string` | - | No | | | getRowHeight | `function(params: GridRowHeightParams) => GridRowHeightReturnValue` | - | No | | | getRowId | `func` | - | No | | | getRowSpacing | `function(params: GridRowSpacingParams) => GridRowSpacing` | - | No | | | hideFooter | `bool` | `false` | No | | | hideFooterPagination | `bool` | `false` | No | | | hideFooterSelectedRowCount | `bool` | `false` | No | | | ignoreDiacritics | `bool` | `false` | No | | | ignoreValueFormatterDuringExport | `{ clipboardExport?: bool, csvExport?: bool } \| bool` | `false` | No | | | initialState | `object` | - | No | | | isCellEditable | `function(params: GridCellParams) => boolean` | - | No | | | isRowSelectable | `function(params: GridRowParams) => boolean` | - | No | | | keepNonExistentRowsSelected | `bool` | `false` | No | | | label | `string` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | logger | `{ debug: func, error: func, info: func, warn: func }` | `console` | No | | | logLevel | `'debug' \| 'error' \| 'info' \| 'warn' \| false` | `"error" ("warn" in dev mode)` | No | | | nonce | `string` | - | No | | | onCellClick | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellDoubleClick | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellEditStart | `function(params: GridCellParams, event: MuiEvent) => void` | - | No | | | onCellEditStop | `function(params: GridCellParams, event: MuiEvent) => void` | - | No | | | onCellKeyDown | `function(params: GridCellParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onCellModesModelChange | `function(cellModesModel: GridCellModesModel, details: GridCallbackDetails) => void` | - | No | | | onClipboardCopy | `function(data: string) => void` | - | No | | | onColumnHeaderClick | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderContextMenu | `function(params: GridColumnHeaderParams, event: MuiEvent) => void` | - | No | | | onColumnHeaderDoubleClick | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderEnter | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderLeave | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderOut | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnHeaderOver | `function(params: GridColumnHeaderParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnOrderChange | `function(params: GridColumnOrderChangeParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onColumnResize | `function(params: GridColumnResizeParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onColumnVisibilityModelChange | `function(model: GridColumnVisibilityModel, details: GridCallbackDetails) => void` | - | No | | | onColumnWidthChange | `function(params: GridColumnResizeParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onDataSourceError | `function(error: GridGetRowsError \| GridUpdateRowError) => void` | - | No | | | onDensityChange | `function(density: GridDensity) => void` | - | No | | | onFilterModelChange | `function(model: GridFilterModel, details: GridCallbackDetails) => void` | - | No | | | onMenuClose | `function(params: GridMenuParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onMenuOpen | `function(params: GridMenuParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onPaginationMetaChange | `function(paginationMeta: GridPaginationMeta) => void` | - | No | | | onPaginationModelChange | `function(model: GridPaginationModel, details: GridCallbackDetails) => void` | - | No | | | onPreferencePanelClose | `function(params: GridPreferencePanelParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onPreferencePanelOpen | `function(params: GridPreferencePanelParams, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onProcessRowUpdateError | `function(error: any) => void` | - | No | | | onResize | `function(containerSize: ElementSize, event: MuiEvent<{}>, details: GridCallbackDetails) => void` | - | No | | | onRowClick | `function(params: GridRowParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onRowCountChange | `function(count: number) => void` | - | No | | | onRowDoubleClick | `function(params: GridRowParams, event: MuiEvent, details: GridCallbackDetails) => void` | - | No | | | onRowEditStart | `function(params: GridRowParams, event: MuiEvent) => void` | - | No | | | onRowEditStop | `function(params: GridRowParams, event: MuiEvent) => void` | - | No | | | onRowModesModelChange | `function(rowModesModel: GridRowModesModel, details: GridCallbackDetails) => void` | - | No | | | onRowSelectionModelChange | `function(rowSelectionModel: GridRowSelectionModel, details: GridCallbackDetails) => void` | - | No | | | onSortModelChange | `function(model: GridSortModel, details: GridCallbackDetails) => void` | - | No | | | pageSizeOptions | `Array` | `[25, 50, 100]` | No | | | paginationMeta | `{ hasNextPage?: bool }` | - | No | | | paginationMode | `'client' \| 'server'` | `"client"` | No | | | paginationModel | `{ page: number, pageSize: number }` | - | No | | | processRowUpdate | `function(newRow: R, oldRow: R, params: { rowId: GridRowId }) => Promise \| R` | - | No | | | resizeThrottleMs | `number` | `60` | No | | | rowBufferPx | `number` | `150` | No | | | rowCount | `number` | - | No | | | rowHeight | `number` | `52` | No | | | rowModesModel | `object` | - | No | | | rows | `Array` | `[]` | No | | | rowSelection | `bool` | `true` | No | | | rowSelectionModel | `{ ids: Set, type: 'exclude' \| 'include' }` | - | No | | | rowSpacingType | `'border' \| 'margin'` | `"margin"` | No | | | rowSpanning | `bool` | `false` | No | | | scrollbarSize | `number` | - | No | | | showCellVerticalBorder | `bool` | `false` | No | | | showColumnVerticalBorder | `bool` | `false` | No | | | showToolbar | `bool` | `false` | No | | | slotProps | `object` | - | No | | | slots | `object` | - | No | | | sortingMode | `'client' \| 'server'` | `"client"` | No | | | sortingOrder | `Array<'asc' \| 'desc'>` | `['asc', 'desc', null]` | No | | | sortModel | `Array<{ field: string, sort?: 'asc' \| 'desc' }>` | - | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | virtualizeColumnsWithAutoRowHeight | `bool` | `false` | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | bottomContainer | `GridBottomContainer` | - | Component rendered for the bottom container. | | cell | `GridCell` | `.MuiDataGrid-cell` | Component rendered for each cell. | | skeletonCell | `GridSkeletonCell` | - | Component rendered for each skeleton cell. | | columnHeaderFilterIconButton | `GridColumnHeaderFilterIconButton` | - | Filter icon component rendered in each column header. | | columnHeaderSortIcon | `GridColumnHeaderSortIcon` | - | Sort icon component rendered in each column header. | | columnMenu | `GridColumnMenu` | - | Column menu component rendered by clicking on the 3 dots "kebab" icon in column headers. | | columnHeaders | `GridColumnHeaders` | `.MuiDataGrid-columnHeaders` | Component responsible for rendering the column headers. | | detailPanels | `GridDetailPanels` | - | Component responsible for rendering the detail panels. | | footer | `GridFooter` | - | Footer component rendered at the bottom of the grid viewport. | | footerRowCount | `GridRowCount` | - | Row count component rendered in the footer | | toolbar | `undefined` | `.MuiDataGrid-toolbar` | Toolbar component rendered in the grid header. | | loadingOverlay | `GridLoadingOverlay` | - | Loading overlay component rendered when the grid is in a loading state. | | noResultsOverlay | `GridNoResultsOverlay` | - | No results overlay component rendered when the grid has no results after filtering. | | noRowsOverlay | `GridNoRowsOverlay` | - | No rows overlay component rendered when the grid has no rows. | | noColumnsOverlay | `GridNoColumnsOverlay` | - | No columns overlay component rendered when the grid has no columns. | | pagination | `Pagination` | - | Pagination component rendered in the grid footer by default. | | filterPanel | `GridFilterPanel` | - | Filter panel component rendered when clicking the filter button. | | columnsPanel | `GridColumnsPanel` | - | GridColumns panel component rendered when clicking the columns button. | | columnsManagement | `GridColumnsManagement` | `.MuiDataGrid-columnsManagement` | Component used inside Grid Columns panel to manage columns. | | panel | `GridPanel` | `.MuiDataGrid-panel` | Panel component wrapping the filters and columns panels. | | row | `GridRow` | `.MuiDataGrid-row` | Component rendered for each row. | | baseAutocomplete | `Autocomplete` | - | The custom Autocomplete component used in the grid for both header and cells. | | baseBadge | `Badge` | - | The custom Badge component used in the grid for both header and cells. | | baseCheckbox | `Checkbox` | - | The custom Checkbox component used in the grid for both header and cells. | | baseChip | `Chip` | - | The custom Chip component used in the grid. | | baseCircularProgress | `CircularProgress` | - | The custom CircularProgress component used in the grid. | | baseDivider | `Divider` | - | The custom Divider component used in the grid. | | baseLinearProgress | `LinearProgress` | - | The custom LinearProgress component used in the grid. | | baseMenuList | `MenuList` | - | The custom MenuList component used in the grid. | | baseMenuItem | `MenuItem` | - | The custom MenuItem component used in the grid. | | baseTextField | `TextField` | - | The custom TextField component used in the grid. | | baseSelect | `Select` | - | The custom Select component used in the grid. | | baseButton | `Button` | - | The custom Button component used in the grid. | | baseIconButton | `IconButton` | - | The custom IconButton component used in the grid. | | baseInput | `Input` | - | The custom Input component used in the grid. | | baseTextarea | `InputBase with multiline` | - | The custom Textarea component used in the grid for multiline text editing. | | baseToggleButton | `ToggleButton` | - | The custom ToggleButton component used in the grid. | | baseTooltip | `Tooltip` | - | The custom Tooltip component used in the grid. | | basePagination | `Pagination` | - | The custom Pagination component used in the grid. | | basePopper | `Popper` | - | The custom Popper component used in the grid. | | baseSelectOption | `SelectOption` | - | The custom SelectOption component used in the grid. | | baseSkeleton | `Skeleton` | - | The custom Skeleton component used in the grid. | | baseSwitch | `Switch` | - | The custom Switch component used in the grid. | | baseTabs | `Tabs` | - | The custom Tabs component used in the grid. | | booleanCellTrueIcon | `GridCheckIcon` | - | Icon displayed on the boolean cell to represent the true value. | | booleanCellFalseIcon | `GridCloseIcon` | - | Icon displayed on the boolean cell to represent the false value. | | undoIcon | `GridUndoIcon` | - | Icon displayed on the undo button in the toolbar. | | redoIcon | `GridRedoIcon` | - | Icon displayed on the redo button in the toolbar. | | columnMenuIcon | `GridTripleDotsVerticalIcon` | - | Icon displayed on the side of the column header title to display the filter input component. | | openFilterButtonIcon | `GridFilterListIcon` | - | Icon displayed on the open filter button present in the toolbar by default. | | columnFilteredIcon | `GridFilterAltIcon` | - | Icon displayed on the column header menu to show that a filter has been applied to the column. | | columnSelectorIcon | `GridColumnIcon` | - | Icon displayed on the column menu selector tab. | | columnUnsortedIcon | `GridColumnUnsortedIcon` | - | Icon displayed on the side of the column header title when unsorted. | | columnSortedAscendingIcon | `GridArrowUpwardIcon` | - | Icon displayed on the side of the column header title when sorted in ascending order. | | columnSortedDescendingIcon | `GridArrowDownwardIcon` | - | Icon displayed on the side of the column header title when sorted in descending order. | | columnResizeIcon | `GridSeparatorIcon` | - | Icon displayed in between two column headers that allows to resize the column header. | | densityCompactIcon | `GridViewHeadlineIcon` | - | Icon displayed on the compact density option in the toolbar. | | densityStandardIcon | `GridTableRowsIcon` | - | Icon displayed on the standard density option in the toolbar. | | densityComfortableIcon | `GridViewStreamIcon` | - | Icon displayed on the "comfortable" density option in the toolbar. | | exportIcon | `GridDownloadIcon` | - | Icon displayed on the open export button present in the toolbar by default. | | moreActionsIcon | `GridMoreVertIcon` | - | Icon displayed on the `actions` column type to open the menu. | | treeDataExpandIcon | `GridKeyboardArrowRight` | - | Icon displayed on the tree data toggling column when the children are collapsed | | treeDataCollapseIcon | `GridExpandMoreIcon` | - | Icon displayed on the tree data toggling column when the children are expanded | | groupingCriteriaExpandIcon | `GridKeyboardArrowRight` | - | Icon displayed on the grouping column when the children are collapsed | | groupingCriteriaCollapseIcon | `GridExpandMoreIcon` | - | Icon displayed on the grouping column when the children are expanded | | detailPanelExpandIcon | `GridAddIcon` | - | Icon displayed on the detail panel toggle column when collapsed. | | detailPanelCollapseIcon | `GridRemoveIcon` | - | Icon displayed on the detail panel toggle column when expanded. | | filterPanelAddIcon | `GridAddIcon` | - | Icon displayed for deleting the filter from filter panel. | | filterPanelDeleteIcon | `GridDeleteIcon` | - | Icon displayed for deleting the filter from filter panel. | | filterPanelRemoveAllIcon | `GridDeleteForeverIcon` | - | Icon displayed for deleting all the active filters from filter panel. | | rowReorderIcon | `GridDragIcon` | `.MuiDataGrid-rowReorderIcon` | Icon displayed on the `reorder` column type to reorder a row. | | quickFilterIcon | `GridSearchIcon` | - | Icon displayed on the quick filter input. | | quickFilterClearIcon | `GridCloseIcon` | - | Icon displayed on the quick filter reset input. | | columnMenuHideIcon | `GridVisibilityOffIcon` | - | Icon displayed in column menu for hiding column | | columnMenuSortAscendingIcon | `GridArrowUpwardIcon` | - | Icon displayed in column menu for ascending sort | | columnMenuSortDescendingIcon | `GridArrowDownwardIcon` | - | Icon displayed in column menu for descending sort | | columnMenuUnsortIcon | `null` | - | Icon displayed in column menu for unsort | | columnMenuFilterIcon | `GridFilterAltIcon` | - | Icon displayed in column menu for filter | | columnMenuManageColumnsIcon | `GridViewColumnIcon` | - | Icon displayed in column menu for showing all columns | | columnMenuClearIcon | `GridClearIcon` | - | Icon displayed in column menu for clearing values | | loadIcon | `GridLoadIcon` | - | Icon displayed on the input while processing. | | columnReorderIcon | `GridDragIcon` | - | Icon displayed on the column reorder button. | | menuItemCheckIcon | `GridCheckIcon` | - | Icon displayed to indicate that a menu item is selected. | | longTextCellExpandIcon | `GridLongTextCellExpandIcon` | - | Icon displayed on the long text cell to expand the content. | | longTextCellCollapseIcon | `GridLongTextCellCollapseIcon` | - | Icon displayed on the long text cell popup to collapse the content. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | actionsCell | Styles applied to the root element of the cell with type="actions". | | - | aggregationColumnHeader | Styles applied to the root element of the column header when aggregated. | | - | aggregationColumnHeader--alignCenter | Styles applied to the root element of the header when aggregation if `headerAlign="center"`. | | - | aggregationColumnHeader--alignLeft | Styles applied to the root element of the header when aggregation if `headerAlign="left"`. | | - | aggregationColumnHeader--alignRight | Styles applied to the root element of the header when aggregation if `headerAlign="right"`. | | - | aggregationColumnHeaderLabel | Styles applied to the aggregation label in the column header when aggregated. | | - | aggregationRowOverlayWrapper | Styles applied to the aggregation row overlay wrapper. | | - | aiAssistantPanel | Styles applied to the root element of the AI assistant panel. | | - | aiAssistantPanelBody | Styles applied to the AI assistant panel body. | | - | aiAssistantPanelConversation | Styles applied to the AI assistant panel conversation. | | - | aiAssistantPanelConversationList | Styles applied to the AI assistant panel conversation list. | | - | aiAssistantPanelConversationTitle | Styles applied to the AI assistant panel conversation title. | | - | aiAssistantPanelEmptyText | Styles applied to the AI assistant panel empty text. | | - | aiAssistantPanelFooter | Styles applied to the AI assistant panel footer. | | - | aiAssistantPanelHeader | Styles applied to the AI assistant panel header. | | - | aiAssistantPanelSuggestions | Styles applied to the AI assistant panel suggestions. | | - | aiAssistantPanelSuggestionsItem | Styles applied to the AI assistant panel suggestions item. | | - | aiAssistantPanelSuggestionsLabel | Styles applied to the AI assistant panel suggestions label. | | - | aiAssistantPanelSuggestionsList | Styles applied to the AI assistant panel suggestions list. | | - | aiAssistantPanelTitle | Styles applied to the AI assistant panel title. | | - | aiAssistantPanelTitleContainer | Styles applied to the AI assistant panel title container. | | - | autoHeight | Styles applied to the root element if `autoHeight={true}`. | | - | autosizing | Styles applied to the root element while it is being autosized. | | - | booleanCell | Styles applied to the icon of the boolean cell. | | - | cell--editable | Styles applied to the cell element if the cell is editable. | | - | cell--editing | Styles applied to the cell element if the cell is in edit mode. | | - | cell--flex | Styles applied to the cell element in flex display mode. | | - | cell--pinnedLeft | Styles applied to the cell element if it is pinned to the left. | | - | cell--pinnedRight | Styles applied to the cell element if it is pinned to the right. | | - | cell--rangeBottom | Styles applied to the cell element if it is at the bottom edge of a cell selection range. | | - | cell--rangeLeft | Styles applied to the cell element if it is at the left edge of a cell selection range. | | - | cell--rangeRight | Styles applied to the cell element if it is at the right edge of a cell selection range. | | - | cell--rangeTop | Styles applied to the cell element if it is at the top edge of a cell selection range. | | - | cell--selectionMode | Styles applied to the cell element if it is in a cell selection range. | | - | cell--textCenter | Styles applied to the cell element if `align="center"`. | | - | cell--textLeft | Styles applied to the cell element if `align="left"`. | | - | cell--textRight | Styles applied to the cell element if `align="right"`. | | - | cell--withLeftBorder | Styles applied the cell if `showColumnVerticalBorder={true}`. | | - | cell--withRightBorder | Styles applied the cell if `showColumnVerticalBorder={true}`. | | - | cellCheckbox | Styles applied to the cell checkbox element. | | - | cellEmpty | Styles applied to the empty cell element. | | - | cellSkeleton | Styles applied to the skeleton cell element. | | - | checkboxInput | Styles applied to the selection checkbox element. | | - | collapsible | Styles applied to the collapsible element. | | - | collapsibleIcon | Styles applied to the collapsible icon element. | | - | collapsiblePanel | Styles applied to the collapsible panel element. | | - | collapsibleTrigger | Styles applied to the collapsible trigger element. | | - | columnHeader | Styles applied to the column header element. | | - | columnHeader--alignCenter | Styles applied to the column header if `headerAlign="center"`. | | - | columnHeader--alignLeft | Styles applied to the column header if `headerAlign="left"`. | | - | columnHeader--alignRight | Styles applied to the column header if `headerAlign="right"`. | | - | columnHeader--dragging | Styles applied to the floating column header element when it is dragged. | | - | columnHeader--emptyGroup | Styles applied to the empty column group header cell. | | - | columnHeader--filledGroup | Styles applied to the column group header cell if not empty. | | - | columnHeader--filter | Styles applied to the header filter cell. | | - | columnHeader--filtered | Styles applied to the column header if the column has a filter applied to it. | | - | columnHeader--last | Styles applied to the last column header element. | | - | columnHeader--moving | Styles applied to the column header if it is being dragged. | | - | columnHeader--numeric | Styles applied to the column header if the type of the column is `number`. | | - | columnHeader--pinnedLeft | | | - | columnHeader--pinnedRight | | | - | columnHeader--sortable | Styles applied to the column header if the column is sortable. | | - | columnHeader--sorted | Styles applied to the column header if the column is sorted. | | - | columnHeader--withLeftBorder | | | - | columnHeader--withRightBorder | Styles applied the column header if `showColumnVerticalBorder={true}`. | | - | columnHeaderCheckbox | Styles applied to the header checkbox cell element. | | - | columnHeaderDraggableContainer | Styles applied to the column header's draggable container element. | | - | columnHeaderFilterInput | Styles applied to the header filter input element. | | - | columnHeaderFilterOperatorLabel | Styles applied to the header filter operator label element. | | - | columnHeaderTitle | Styles applied to the column header's title element; | | - | columnHeaderTitleContainer | Styles applied to the column header's title container element. | | - | columnHeaderTitleContainerContent | Styles applied to the column header's title excepted buttons. | | - | columnSeparator | Styles applied to the column header separator element. | | - | columnSeparator--resizable | Styles applied to the column header separator if the column is resizable. | | - | columnSeparator--resizing | Styles applied to the column header separator if the column is being resized. | | - | columnSeparator--sideLeft | Styles applied to the column header separator if the side is "left". | | - | columnSeparator--sideRight | Styles applied to the column header separator if the side is "right". | | - | columnsManagementEmptyText | Styles applied to the columns management empty text element. | | - | columnsManagementFooter | Styles applied to the columns management footer element. | | - | columnsManagementHeader | Styles applied to the columns management header element. | | - | columnsManagementRow | Styles applied to the columns management row element. | | - | columnsManagementScrollArea | Styles applied to the columns management scroll area element. | | - | columnsManagementSearchInput | Styles applied to the columns management search input element. | | - | container--bottom | Styles applied to the bottom container. | | - | container--top | Styles applied to the top container. | | - | detailPanel | Styles applied to the detail panel element. | | - | detailPanelToggleCell | Styles applied to the detail panel toggle cell element. | | - | detailPanelToggleCell--expanded | Styles applied to the detail panel toggle cell element if expanded. | | - | editBooleanCell | Styles applied to root of the boolean edit component. | | - | editInputCell | Styles applied to the root of the input component. | | - | editLongTextCell | Styles applied to the edit long text cell root element. | | - | editLongTextCellPopperContent | Styles applied to the edit long text cell popper content. | | - | editLongTextCellPopup | Styles applied to the edit long text cell popup. | | - | editLongTextCellTextarea | Styles applied to the edit long text cell textarea. | | - | editLongTextCellValue | Styles applied to the edit long text cell value element. | | - | filterForm | Styles applied to the root of the filter form component. | | - | filterFormColumnInput | Styles applied to the column input of the filter form component. | | - | filterFormDeleteIcon | Styles applied to the delete icon of the filter form component. | | - | filterFormLogicOperatorInput | Styles applied to the link operator input of the filter form component. | | - | filterFormOperatorInput | Styles applied to the operator input of the filter form component. | | - | filterFormValueInput | Styles applied to the value input of the filter form component. | | - | filterIcon | Styles applied to the filter icon element. | | - | footerCell | Styles applied to the root element of the cell inside a footer row. | | - | footerContainer | Styles applied to the footer container element. | | - | groupingCriteriaCell | Styles applied to the root element of the grouping criteria cell | | - | groupingCriteriaCellToggle | Styles applied to the toggle of the grouping criteria cell | | - | headerFilterRow | Styles applied to the column header filter row. | | - | iconButtonContainer | Styles applied to the column header icon's container. | | - | iconSeparator | Styles applied to the column header separator icon element. | | - | longTextCell | Styles applied to the long text cell root element. | | - | longTextCellCollapseButton | Styles applied to the long text cell collapse button. | | - | longTextCellContent | Styles applied to the long text cell content element. | | - | longTextCellExpandButton | Styles applied to the long text cell expand button. | | - | longTextCellPopperContent | Styles applied to the long text cell popper content. | | - | longTextCellPopup | Styles applied to the long text cell popup. | | - | main | Styles applied to the main container element. | | - | main--hasPinnedRight | Styles applied to the main container element when it has right pinned columns. | | - | mainContent | | | - | menu | Styles applied to the menu element. | | - | menuIcon | Styles applied to the menu icon element. | | - | menuIconButton | Styles applied to the menu icon button element. | | - | menuList | Styles applied to the menu list element. | | - | menuOpen | Styles applied to the menu icon element if the menu is open. | | - | overlay | Styles applied to the overlay element. | | - | overlayWrapper | Styles applied to the overlay wrapper element. | | - | overlayWrapperInner | Styles applied to the overlay wrapper inner element. | | - | panelContent | Styles applied to the panel content element. | | - | panelFooter | Styles applied to the panel footer element. | | - | panelHeader | Styles applied to the panel header element. | | - | panelWrapper | Styles applied to the panel wrapper element. | | - | paper | Styles applied to the paper element. | | - | pinnedRows | Styles applied to the pinned rows container. | | - | pinnedRows--bottom | Styles applied to the bottom pinned rows container. | | - | pinnedRows--top | Styles applied to the top pinned rows container. | | - | pivotPanelAvailableFields | Styles applied to the pivot panel available fields. | | - | pivotPanelBody | Styles applied to the pivot panel body. | | - | pivotPanelField | Styles applied to the pivot panel field. | | - | pivotPanelField--sorted | Styles applied to the pivot panel field when sorted. | | - | pivotPanelFieldActionContainer | Styles applied to the pivot panel field action container. | | - | pivotPanelFieldCheckbox | Styles applied to the pivot panel field checkbox. | | - | pivotPanelFieldDragIcon | Styles applied to the pivot panel field drag icon. | | - | pivotPanelFieldList | Styles applied to the pivot panel field list. | | - | pivotPanelFieldName | Styles applied to the pivot panel field name. | | - | pivotPanelHeader | Styles applied to the pivot panel header. | | - | pivotPanelPlaceholder | Styles applied to the pivot panel placeholder. | | - | pivotPanelScrollArea | Styles applied to the pivot panel scroll area. | | - | pivotPanelSearchContainer | Styles applied to the pivot panel search container. | | - | pivotPanelSection | Styles applied to the pivot panel section. | | - | pivotPanelSections | Styles applied to the pivot panel sections. | | - | pivotPanelSectionTitle | Styles applied to the pivot panel section title. | | - | pivotPanelSwitch | Styles applied to the pivot panel switch. | | - | pivotPanelSwitchLabel | Styles applied to the pivot panel switch label. | | - | prompt | Styles applied to the prompt root element. | | - | promptAction | Styles applied to the prompt action element. | | - | promptChangeList | Styles applied to the prompt change list element. | | - | promptChangesToggle | Styles applied to the prompt changes toggle element. | | - | promptChangesToggleIcon | Styles applied to the prompt changes toggle icon element. | | - | promptContent | Styles applied to the prompt content element. | | - | promptError | Styles applied to the prompt error element. | | - | promptFeedback | Styles applied to the prompt feedback element. | | - | promptIcon | Styles applied to the prompt icon element. | | - | promptIconContainer | Styles applied to the prompt icon element. | | - | promptText | Styles applied to the prompt text element. | | - | resizablePanelHandle | Styles applied to resizable panel handles. | | - | resizablePanelHandle--horizontal | Styles applied to horizontal resizable panel handles. | | - | resizablePanelHandle--vertical | Styles applied to vertical resizable panel handles. | | - | root | Styles applied to the root element. | | - | root--densityComfortable | Styles applied to the root element if density is "comfortable". | | - | root--densityCompact | Styles applied to the root element if density is "compact". | | - | root--densityStandard | Styles applied to the root element if density is "standard" (default). | | - | root--disableUserSelection | Styles applied to the root element when user selection is disabled. | | - | row--beingDragged | Styles applied to the row element when it is being dragged (entire row). | | - | row--detailPanelExpanded | Styles applied to the row if its detail panel is open. | | - | row--dragging | Styles applied to the floating special row reorder cell element when it is dragged. | | - | row--dynamicHeight | Styles applied to the row if it has dynamic row height. | | - | row--editable | Styles applied to the row element if the row is editable. | | - | row--editing | Styles applied to the row element if the row is in edit mode. | | - | row--firstVisible | Styles applied to the first visible row element on every page of the grid. | | - | row--lastVisible | Styles applied to the last visible row element on every page of the grid. | | - | rowCount | Styles applied to the footer row count element to show the total number of rows. Only works when pagination is disabled. | | - | rowReorderCell | Styles applied to the root element of the row reorder cell | | - | rowReorderCell--draggable | Styles applied to the root element of the row reorder cell when dragging is allowed | | - | rowReorderCellContainer | Styles applied to the row reorder cell container element. | | - | rowReorderCellPlaceholder | Styles applied to the row's draggable placeholder element inside the special row reorder cell. | | - | rowSkeleton | Styles applied to the skeleton row element. | | - | scrollArea | Styles applied to both scroll area elements. | | - | scrollArea--down | Styles applied to the bottom scroll area element. | | - | scrollArea--left | Styles applied to the left scroll area element. | | - | scrollArea--right | Styles applied to the right scroll area element. | | - | scrollArea--up | Styles applied to the top scroll area element. | | - | scrollbar | Styles applied to the scrollbars. | | - | scrollbar--horizontal | Styles applied to the horizontal scrollbar. | | - | scrollbar--vertical | Styles applied to the horizontal scrollbar. | | - | scrollShadow | Styles applied to the scroll shadow element. | | - | scrollShadow--horizontal | Styles applied to the horizontal scroll shadow element. | | - | scrollShadow--vertical | Styles applied to the vertical scroll shadow element. | | - | selectedRowCount | Styles applied to the footer selected row count element. | | - | sidebar | Styles applied to the sidebar element. | | - | sidebarHeader | Styles applied to the sidebar header element. | | - | sortButton | Styles applied to the sort button element. | | - | sortIcon | Styles applied to the sort button icon element. | | - | toolbarContainer | Styles applied to the toolbar container element. | | - | toolbarDivider | Styles applied to the toolbar divider element. | | - | toolbarFilterList | Styles applied to the toolbar filter list element. | | - | toolbarLabel | Styles applied to the toolbar label element. | | - | toolbarQuickFilter | Styles applied to the toolbar quick filter root element. | | - | toolbarQuickFilterControl | Styles applied to the toolbar quick filter control element. | | - | toolbarQuickFilterTrigger | Styles applied to the toolbar quick filter trigger element. | | - | treeDataGroupingCell | Styles applied to the root of the grouping column of the tree data. | | - | treeDataGroupingCellToggle | Styles applied to the toggle of the grouping cell of the tree data. | | - | virtualScroller | Styles applied to the virtualization container. | | - | virtualScrollerContent | Styles applied to the virtualization content. | | - | virtualScrollerContent--overflowed | Styles applied to the virtualization content when its height is bigger than the virtualization container. | | - | virtualScrollerRenderZone | Styles applied to the virtualization render zone. | | - | withBorderColor | Styles applied to cells, column header and other elements that have border. Sets border color only. | | - | withSidePanel | | | - | withVerticalBorder | Styles applied the grid if `showColumnVerticalBorder={true}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/DataGrid/DataGrid.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/DataGrid/DataGrid.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-calendar.md # Source: https://mui.com/x/react-date-pickers/date-calendar.md --- productId: x-date-pickers title: React Date Calendar component components: DateCalendar, MonthCalendar, YearCalendar, PickersDay, DayCalendarSkeleton githubLabel: 'component: DatePicker' packageName: '@mui/x-date-pickers' --- # Date Calendar The Date Calendar component lets users select a date without any input or popper / modal. ## Basic usage ```tsx import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function BasicDateCalendar() { return ( ); } ``` ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function DateCalendarValue() { const [value, setValue] = React.useState(dayjs('2022-04-17')); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Form props The component can be disabled or read-only. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function DateCalendarFormProps() { return ( ); } ``` ## Views The component can contain three views: `day`, `month`, and `year`. By default, only the `day` and `year` views are enabled. You can customize the enabled views using the `views` prop. Views will appear in the order they're included in the `views` array. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function DateCalendarViews() { return ( ); } ``` ## Choose the initial year / month If `value` or `defaultValue` contains a valid date, this date will be used to choose which month to render in the `day` view and which year to render in the `month` view. If both `value` and `defaultValue` contain no valid date, the component will try to find a month and year that satisfies the validation rules. You can override this date using the `referenceDate`, in the example below the calendar renders April 2022 even though no date is visually selected: ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function DateCalendarReferenceDate() { return ( ); } ``` :::success Learn more about the `referenceDate` in the [dedicated doc section](/x/react-date-pickers/base-concepts/#reference-date-when-no-value-is-defined). ::: ## Month and Year Calendar If you only need the `year` view or the `month` view, you can use the `YearCalendar` / `MonthCalendar` components: ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { YearCalendar } from '@mui/x-date-pickers/YearCalendar'; import { MonthCalendar } from '@mui/x-date-pickers/MonthCalendar'; export default function YearMonthCalendar() { return ( ); } ``` ### Order of years By default, years are displayed in ascending order, chronologically from the minimum year to the maximum. Set the `yearsOrder` prop to `desc` to show the years in descending order. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { YearCalendar } from '@mui/x-date-pickers/YearCalendar'; const currentYear = dayjs(); export default function YearsOrderDescendingCalendar() { return ( ); } ``` ## Day view customization ### Show additional days To show all days of displayed weeks, including those outside of the current month, use `showDaysOutsideCurrentMonth`. By default, only weeks of the current month are displayed, but you can provide a total number of weeks to display with `fixedWeekNumber` prop. This value is usually set to `6` for Gregorian calendars, because month display can vary between 4 and 6 weeks. ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function CustomMonthLayout() { return ( ); } ``` ### Display week number To display week numbers, use the `displayWeekNumber` prop. You can customize the calendar week header by using the localization key `localeText.calendarWeekNumberHeaderText`. You can also customize what's rendered as a calendar week number, using a callback for the localization key `localeText.calendarWeekNumberText`. ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; export default function AddWeekNumber() { return ( `${weekNumber}.`, }} > ); } ``` ### Week picker You can select the whole week using the `day` component slot: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import isBetweenPlugin from 'dayjs/plugin/isBetween'; import { styled } from '@mui/material/styles'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay'; dayjs.extend(isBetweenPlugin); interface CustomPickerDayProps extends PickersDayProps { isSelected: boolean; isHovered: boolean; } const CustomPickersDay = styled(PickersDay, { shouldForwardProp: (prop) => prop !== 'isSelected' && prop !== 'isHovered', })(({ theme, isSelected, isHovered, day }) => ({ borderRadius: 0, ...(isSelected && { backgroundColor: theme.palette.primary.main, color: theme.palette.primary.contrastText, '&:hover, &:focus': { backgroundColor: theme.palette.primary.main, }, }), ...(isHovered && { backgroundColor: theme.palette.primary.light, '&:hover, &:focus': { backgroundColor: theme.palette.primary.light, }, ...theme.applyStyles('dark', { backgroundColor: theme.palette.primary.dark, '&:hover, &:focus': { backgroundColor: theme.palette.primary.dark, }, }), }), ...(day.day() === 0 && { borderTopLeftRadius: '50%', borderBottomLeftRadius: '50%', }), ...(day.day() === 6 && { borderTopRightRadius: '50%', borderBottomRightRadius: '50%', }), })) as React.ComponentType; const isInSameWeek = (dayA: Dayjs, dayB: Dayjs | null | undefined) => { if (dayB == null) { return false; } return dayA.isSame(dayB, 'week'); }; function Day( props: PickersDayProps & { selectedDay?: Dayjs | null; hoveredDay?: Dayjs | null; }, ) { const { day, selectedDay, hoveredDay, ...other } = props; return ( ); } export default function WeekPicker() { const [hoveredDay, setHoveredDay] = React.useState(null); const [value, setValue] = React.useState(dayjs('2022-04-17')); return ( setValue(newValue)} showDaysOutsideCurrentMonth displayWeekNumber slots={{ day: Day }} slotProps={{ day: (ownerState) => ({ selectedDay: value, hoveredDay, onPointerEnter: () => setHoveredDay(ownerState.day), onPointerLeave: () => setHoveredDay(null), }) as any, }} /> ); } ``` ## Dynamic data Sometimes it may be necessary to display additional info right in the calendar. The following demo shows how to add a badge on some day based on server-side data: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import Badge from '@mui/material/Badge'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { PickersDay, PickersDayProps } from '@mui/x-date-pickers/PickersDay'; import { DateCalendar } from '@mui/x-date-pickers/DateCalendar'; import { DayCalendarSkeleton } from '@mui/x-date-pickers/DayCalendarSkeleton'; function getRandomNumber(min: number, max: number) { return Math.round(Math.random() * (max - min) + min); } /** * Mimic fetch with abort controller https://developer.mozilla.org/en-US/docs/Web/API/AbortController/abort * ⚠️ No IE11 support */ function fakeFetch(date: Dayjs, { signal }: { signal: AbortSignal }) { return new Promise<{ daysToHighlight: number[] }>((resolve, reject) => { const timeout = setTimeout(() => { const daysInMonth = date.daysInMonth(); const daysToHighlight = [1, 2, 3].map(() => getRandomNumber(1, daysInMonth)); resolve({ daysToHighlight }); }, 500); signal.onabort = () => { clearTimeout(timeout); reject(new DOMException('aborted', 'AbortError')); }; }); } const initialValue = dayjs('2022-04-17'); function ServerDay(props: PickersDayProps & { highlightedDays?: number[] }) { const { highlightedDays = [], day, outsideCurrentMonth, ...other } = props; const isSelected = !props.outsideCurrentMonth && highlightedDays.indexOf(props.day.date()) >= 0; return ( ); } export default function DateCalendarServerRequest() { const requestAbortController = React.useRef(null); const [isLoading, setIsLoading] = React.useState(false); const [highlightedDays, setHighlightedDays] = React.useState([1, 2, 15]); const fetchHighlightedDays = (date: Dayjs) => { const controller = new AbortController(); fakeFetch(date, { signal: controller.signal, }) .then(({ daysToHighlight }) => { setHighlightedDays(daysToHighlight); setIsLoading(false); }) .catch((error) => { // ignore the error if it's caused by `controller.abort` if (error.name !== 'AbortError') { throw error; } }); requestAbortController.current = controller; }; React.useEffect(() => { fetchHighlightedDays(initialValue); // abort request on unmount return () => requestAbortController.current?.abort(); }, []); const handleMonthChange = (date: Dayjs) => { if (requestAbortController.current) { // make sure that you are aborting useless requests // because it is possible to switch between months pretty quickly requestAbortController.current.abort(); } setIsLoading(true); setHighlightedDays([]); fetchHighlightedDays(date); }; return ( } slots={{ day: ServerDay, }} slotProps={{ day: { highlightedDays, } as any, }} /> ); } ``` ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/api/date-pickers/date-field.md # Source: https://mui.com/x/react-date-pickers/date-field.md --- productId: x-date-pickers title: React Date Field component components: DateField githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Date Field The Date Field component lets users select a date with the keyboard. ## Basic usage ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; export default function BasicDateField() { return ( ); } ``` ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; export default function DateFieldValue() { const [value, setValue] = React.useState(dayjs('2022-04-17')); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ### Customize the date format ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import dayjs from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; export default function CustomDateFormat() { return ( ); } ``` :::info See [Date format and localization—Custom formats](/x/react-date-pickers/adapters-locale/#custom-formats) for more details. ::: ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/api/date-pickers/date-picker-toolbar.md # DatePickerToolbar API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) ## Import ```jsx import { DatePickerToolbar } from '@mui/x-date-pickers/DatePicker'; // or import { DatePickerToolbar } from '@mui/x-date-pickers'; // or import { DatePickerToolbar } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | hidden | `bool` | ``true` for Desktop, `false` for Mobile.` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | toolbarFormat | `string` | - | No | | | toolbarPlaceholder | `node` | `"––"` | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | | - | title | Styles applied to the title element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/DatePicker/DatePickerToolbar.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-picker.md # Source: https://mui.com/x/react-date-pickers/date-picker.md --- productId: x-date-pickers title: React Date Picker component components: DatePicker, DesktopDatePicker, MobileDatePicker, StaticDatePicker, DateCalendar githubLabel: 'component: DatePicker' packageName: '@mui/x-date-pickers' materialDesign: https://m2.material.io/components/date-pickers --- # Date Picker The Date Picker component lets users select a date. ## Basic usage ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function BasicDatePicker() { return ( ); } ``` ## Component composition The component is built using the `DateField` for the keyboard editing and the `DateCalendar` for the view editing. Check out their documentation page for more information: - [Date Field](/x/react-date-pickers/date-field/) - [Date Calendar](/x/react-date-pickers/date-calendar/) You can check the available props of the combined component on the dedicated [API page](/x/api/date-pickers/date-picker/#props). Some [DateField props](/x/api/date-pickers/date-field/#props) are not available on the Picker component, you can use `slotProps.field` to pass them to the field. ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function DatePickerValue() { const [value, setValue] = React.useState(dayjs('2022-04-17')); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Available components The component is available in four variants: - The `DesktopDatePicker` component which works best for mouse devices and large screens. It renders the views inside a popover and a field for keyboard editing. - The `MobileDatePicker` component which works best for touch devices and small screens. It renders the view inside a modal and a field for keyboard editing. - The `DatePicker` component which renders `DesktopDatePicker` or `MobileDatePicker` depending on the device it runs on. - The `StaticDatePicker` component which renders without the popover/modal and field. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker'; import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; export default function ResponsiveDatePickers() { return ( ); } ``` By default, the `DatePicker` component renders the desktop version if the media query [`@media (pointer: fine)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer) matches. This can be customized with the `desktopModeMediaQuery` prop. :::warning Responsive components can suffer some inconsistencies between testing environments if media query is not supported. Please refer to [this section](/x/react-date-pickers/base-concepts/#testing-caveats) for solutions. ::: ### Keyboard Date Picker (legacy) The current implementation of the Date Picker component replaces the experimental Keyboard Date Picker from Material UI. See the [migration documentation](/material-ui/migration/pickers-migration/#imports) for more information. For accessibility, all Picker components accept keyboard inputs. If your use case only calls for keyboard editing, you can use Field components: the Date Picker component can be edited via input or a calendar, whereas the Date Field can only be edited via input. See the [Fields documentation](/x/react-date-pickers/fields/) for more details. ## Form props The component supports the `disabled`, `readOnly` and `name` form props: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function FormPropsDatePickers() { return ( ); } ``` ## Views The component supports three views: `day`, `month`, and `year`. By default, the `day` and `year` views are enabled. Use the `views` prop to change this behavior: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function DatePickerViews() { return ( ); } ``` By default, the component renders the `day` view on mount. Use the `openTo` prop to change this behavior: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function DatePickerOpenTo() { return ( ); } ``` :::success The views will appear in the order defined by the `views` array. If the view defined in `openTo` is not the first view, then the views before will not be included in the default flow (for example, viewing the default behaviors, the `year` is only accessible when clicking on the toolbar). ::: ## Order of years By default, years are displayed in ascending order, chronologically from the minimum year to the maximum. Set the `yearsOrder` prop to `desc` to show the years in descending order. ```tsx import dayjs from 'dayjs'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; const currentYear = dayjs(); export default function DatePickerYearsOrder() { return ( ); } ``` ## Landscape orientation By default, the Date Picker component automatically sets the orientation based on the `window.orientation` value. You can force a specific orientation using the `orientation` prop: ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { StaticDatePicker } from '@mui/x-date-pickers/StaticDatePicker'; export default function StaticDatePickerLandscape() { return ( ); } ``` :::info You can find more information about the layout customization in the [custom layout page](/x/react-date-pickers/custom-layout/). ::: ## Helper text You can show a helper text with the date format accepted: ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function HelperText() { return ( ); } ``` ## Clearing the value You can enable the clearable behavior: ```tsx import * as React from 'react'; import { DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; import Box from '@mui/material/Box'; import Alert from '@mui/material/Alert'; export default function ClearableProp() { const [cleared, setCleared] = React.useState(false); React.useEffect(() => { if (cleared) { const timeout = setTimeout(() => { setCleared(false); }, 1500); return () => clearTimeout(timeout); } return () => {}; }, [cleared]); return ( setCleared(true) }, }} /> {cleared && ( Field cleared! )} ); } ``` :::info See [Field components—Clearable behavior](/x/react-date-pickers/fields/#clearable-behavior) for more details. ::: ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. ## Customization You can check out multiple examples of how to customize the date pickers and their subcomponents. ```jsx import * as React from 'react'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import Stack from '@mui/material/Stack'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { BrandingProvider } from '@mui/docs/branding'; import CustomizationPlayground from 'docsx/src/modules/components/CustomizationPlayground'; import CircularProgress from '@mui/material/CircularProgress'; import { pickerExamples } from './examplesConfig.styling'; export default function CustomizationExamplesNoSnap() { const [selectedPicker, setSelectedPicker] = React.useState(0); const handleSelectedPickerChange = (_e, newValue) => { if (newValue !== null) { setSelectedPicker(newValue); } }; if (!pickerExamples[selectedPicker]?.examples) { return ( ); } return ( {pickerExamples.map(({ name }, index) => ( {name} ))} {pickerExamples.map( (example, index) => String(index) === String(selectedPicker) && ( ), )} ); } ``` --- # Source: https://mui.com/x/api/date-pickers.md # Date and Time Pickers - API Reference This page contains an index to the most important APIs of the Date and Time Pickers. ## 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 [](/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 [](/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 [](/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 [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/multi-input-date-range-field/) - [SingleInputDateRangeField [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/single-input-date-range-field/) - [MultiInputTimeRangeField [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/multi-input-time-range-field/) - [SingleInputTimeRangeField [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/single-input-time-range-field/) - [MultiInputDateTimeRangeField [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/multi-input-date-time-range-field/) - [SingleInputDateTimeRangeField [](/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 [](/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 [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/date-range-picker-toolbar/) - [TimeRangePickerToolbar [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/time-range-picker-toolbar/) - [DateTimeRangePickerToolbar [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/date-time-range-picker-toolbar/) ### Others - [DateRangePickerDay [](/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 [](/x/introduction/licensing/#pro-plan 'Pro plan')](/x/api/date-pickers/time-range-picker-tabs/) - [DateTimeRangePickerTabs [](/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/) - [PickersDay](/x/api/date-pickers/pickers-day/) --- # Source: https://mui.com/x/api/date-pickers/date-range-calendar.md # Source: https://mui.com/x/react-date-pickers/date-range-calendar.md --- productId: x-date-pickers title: React Date Range Calendar component components: DateRangeCalendar githubLabel: 'component: DateRangePicker' packageName: '@mui/x-date-pickers-pro' --- # Date Range Calendar [](/x/introduction/licensing/#pro-plan 'Pro plan') The Date Range Calendar lets the user select a range of dates without any input or popper / modal. ## Basic usage ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; export default function BasicDateRangeCalendar() { return ( ); } ``` ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; import { DateRange } from '@mui/x-date-pickers-pro/models'; export default function DateRangeCalendarValue() { const [value, setValue] = React.useState>([ dayjs('2022-04-17'), dayjs('2022-04-21'), ]); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Form props The component can be disabled or read-only. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; export default function DateRangeCalendarFormProps() { return ( ); } ``` ## Customization ### Choose the months to render You can render up to 3 months at the same time using the `calendars` prop: ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; export default function DateRangeCalendarCalendarsProp() { return ( ); } ``` You can choose the position where the current month is rendered using the `currentMonthCalendarPosition` prop. This can be useful when using `disableFuture` to render the current month and the month before instead of the current month and the month after. ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; export default function DateRangeCalendarCurrentMonthCalendarPositionProp() { return ( ); } ``` ### Custom day rendering The displayed days are customizable with the `Day` component slot. You can take advantage of the [DateRangePickerDay](/x/api/date-pickers/date-range-picker-day/) component. ```tsx import * as React from 'react'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import dayjs from 'dayjs'; import { styled } from '@mui/material/styles'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateRangeCalendar } from '@mui/x-date-pickers-pro/DateRangeCalendar'; import { DateRangePickerDay as MuiDateRangePickerDay, DateRangePickerDayProps, } from '@mui/x-date-pickers-pro/DateRangePickerDay'; const DateRangePickerDay = styled(MuiDateRangePickerDay)(({ theme }) => ({ variants: [ { props: ({ isHighlighting, outsideCurrentMonth }) => !outsideCurrentMonth && isHighlighting, style: { borderRadius: 0, backgroundColor: theme.palette.primary.main, color: theme.palette.common.white, '&:hover, &:focus': { backgroundColor: theme.palette.primary.dark, }, }, }, { props: ({ isStartOfHighlighting }) => isStartOfHighlighting, style: { borderTopLeftRadius: '50%', borderBottomLeftRadius: '50%', }, }, { props: ({ isEndOfHighlighting }) => isEndOfHighlighting, style: { borderTopRightRadius: '50%', borderBottomRightRadius: '50%', }, }, ], })) as React.ComponentType; export default function CustomDateRangePickerDay() { return ( ); } ``` ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/react-date-pickers/date-range-field.md --- productId: x-date-pickers title: React Date Range Field components components: MultiInputDateRangeField, SingleInputDateRangeField githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers-pro' --- # Date Range Field [](/x/introduction/licensing/#pro-plan 'Pro plan') The Date Range Field lets the user select a date range with the keyboard. ## Basic usage You can render your Date Range Field with either one input using `SingleInputDateRangeField` or two inputs using `MultiInputDateRangeField` as shown below. :::info All the topics covered below are applicable to both `SingleInputDateRangeField` and `MultiInputDateRangeField` unless explicitly mentioned. ::: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; export default function BasicDateRangeField() { return ( ({ label: position === 'start' ? 'Departure' : 'Return', }), }} /> ); } ``` ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { DateRange } from '@mui/x-date-pickers-pro/models'; export default function DateRangeFieldValue() { const [value, setValue] = React.useState>(() => [ dayjs('2022-04-17'), dayjs('2022-04-21'), ]); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/api/date-pickers/date-range-picker-day-2.md # DateRangePickerDay2 API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) - [Customization playground](/x/react-date-pickers/playground/) ## Import ```jsx import { DateRangePickerDay2 } from '@mui/x-date-pickers-pro/DateRangePickerDay2'; // or import { DateRangePickerDay2 } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | day | `object` | - | Yes | | | isEndOfHighlighting | `bool` | - | Yes | | | isEndOfPreviewing | `bool` | - | Yes | | | isFirstVisibleCell | `bool` | - | Yes | | | isHighlighting | `bool` | - | Yes | | | isLastVisibleCell | `bool` | - | Yes | | | isPreviewing | `bool` | - | Yes | | | isStartOfHighlighting | `bool` | - | Yes | | | isStartOfPreviewing | `bool` | - | Yes | | | outsideCurrentMonth | `bool` | - | Yes | | | action | `func \| { current?: { focusVisible: func } }` | - | No | | | centerRipple | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | disabled | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableMargin | `bool` | `false` | No | | | disableRipple | `bool` | `false` | No | | | disableTouchRipple | `bool` | `false` | No | | | draggable | `bool` | `false` | No | | | focusRipple | `bool` | `false` | No | | | focusVisibleClassName | `string` | - | No | | | isVisuallySelected | `bool` | - | No | | | onFocusVisible | `func` | - | No | | | selected | `bool` | `false` | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | today | `bool` | `false` | No | | | TouchRippleProps | `object` | - | No | | | touchRippleRef | `func \| { current?: { pulsate: func, start: func, stop: func } }` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLButtonElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiDateRangePickerDay2` to change the default props of this component with the theme. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | dayOutsideMonth | Styles applied to the root element if `outsideCurrentMonth=true` and `showDaysOutsideCurrentMonth=true`. | | `.Mui-disabled` | - | State class applied to the root element if `disabled=true`. | | - | draggable | | | - | endOfMonth | | | - | endOfWeek | | | - | fillerCell | Styles applied to the root element if `outsideCurrentMonth=true` and `showDaysOutsideCurrentMonth=false`. | | - | insidePreviewing | | | - | insideSelection | | | - | previewed | | | - | previewEnd | | | - | previewStart | | | - | root | Styles applied to the root element. | | `.Mui-selected` | - | State class applied to the root element if `selected=true`. | | - | selectionEnd | | | - | selectionStart | | | - | startOfMonth | | | - | startOfWeek | | | - | today | Styles applied to the root element if `disableHighlightToday=false` and `today=true`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DateRangePickerDay2/DateRangePickerDay2.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DateRangePickerDay2/DateRangePickerDay2.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-range-picker-day.md # DateRangePickerDay API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Range Picker - Date Time Range Picker ## Import ```jsx import { DateRangePickerDay } from '@mui/x-date-pickers-pro/DateRangePickerDay'; // or import { DateRangePickerDay } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | day | `object` | - | Yes | | | isEndOfHighlighting | `bool` | - | Yes | | | isEndOfPreviewing | `bool` | - | Yes | | | isFirstVisibleCell | `bool` | - | Yes | | | isHighlighting | `bool` | - | Yes | | | isLastVisibleCell | `bool` | - | Yes | | | isPreviewing | `bool` | - | Yes | | | isStartOfHighlighting | `bool` | - | Yes | | | isStartOfPreviewing | `bool` | - | Yes | | | outsideCurrentMonth | `bool` | - | Yes | | | action | `func \| { current?: { focusVisible: func } }` | - | No | | | centerRipple | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | disabled | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableMargin | `bool` | `false` | No | | | disableRipple | `bool` | `false` | No | | | disableTouchRipple | `bool` | `false` | No | | | draggable | `bool` | `false` | No | | | focusRipple | `bool` | `false` | No | | | focusVisibleClassName | `string` | - | No | | | isVisuallySelected | `bool` | - | No | | | onFocusVisible | `func` | - | No | | | selected | `bool` | `false` | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | today | `bool` | `false` | No | | | TouchRippleProps | `object` | - | No | | | touchRippleRef | `func \| { current?: { pulsate: func, start: func, stop: func } }` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLButtonElement). > Any other props supplied will be provided to the root element (native element). ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | day | Styles applied to the day element. | | - | dayInsideRangeInterval | Styles applied to the day element if `selected=false` and `isHighlighting=true`. | | - | dayOutsideRangeInterval | Styles applied to the day element if `isHighlighting=false`. | | - | endOfMonth | Styles applied to the root element if `day` is the end of the month. | | - | firstVisibleCell | Styles applied to the root element if `day` is the first visible cell of the month. | | - | hiddenDayFiller | Styles applied to the root element if it is an empty cell used to fill the week. | | - | lastVisibleCell | Styles applied to the root element if `day` is the last visible cell of the month. | | - | notSelectedDate | Styles applied to the day element if `selected=false`. | | - | outsideCurrentMonth | Styles applied to the root element if `outsideCurrentMonth=true` | | - | rangeIntervalDayHighlight | Styles applied to the root element if `isHighlighting=true`. | | - | rangeIntervalDayHighlightEnd | Styles applied to the root element if `isEndOfHighlighting=true`. | | - | rangeIntervalDayHighlightStart | Styles applied to the root element if `isStartOfHighlighting=true`. | | - | rangeIntervalDayPreview | Styles applied to the root element if `isPreviewing=true`. | | - | rangeIntervalDayPreviewEnd | Styles applied to the root element if `isEndOfPreviewing=true`. | | - | rangeIntervalDayPreviewStart | Styles applied to the root element if `isStartOfPreviewing=true`. | | - | rangeIntervalPreview | Styles applied to the preview element. | | - | root | Styles applied to the root element. | | - | startOfMonth | Styles applied to the root element if `day` is the start of the month. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DateRangePickerDay/DateRangePickerDay.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-range-picker-toolbar.md # DateRangePickerToolbar API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) ## Import ```jsx import { DateRangePickerToolbar } from '@mui/x-date-pickers-pro/DateRangePicker'; // or import { DateRangePickerToolbar } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | hidden | `bool` | ``true` for Desktop, `false` for Mobile.` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | toolbarFormat | `string` | - | No | | | toolbarPlaceholder | `node` | `"––"` | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | container | Styles applied to the container element. | | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePickerToolbar.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-range-picker.md # Source: https://mui.com/x/react-date-pickers/date-range-picker.md --- productId: x-date-pickers title: React Date Range Picker component components: DateRangePicker, DesktopDateRangePicker, MobileDateRangePicker, StaticDateRangePicker, DateRangeCalendar, DateRangePickerDay githubLabel: 'component: DateRangePicker' packageName: '@mui/x-date-pickers-pro' materialDesign: https://m2.material.io/components/date-pickers --- # Date Range Picker [](/x/introduction/licensing/#pro-plan 'Pro plan') The Date Range Picker lets the user select a range of dates. ## Basic usage ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; export default function BasicDateRangePicker() { return ( ); } ``` ## Component composition The component is built using the `SingleInputDateRangeField` for the keyboard editing and the `DateRangeCalendar` for the view editing. Check out their documentation page for more information: - [Date Range Field](/x/react-date-pickers/date-range-field/) - [Date Range Calendar](/x/react-date-pickers/date-range-calendar/) You can check the available props of the combined component on the dedicated [API page](/x/api/date-pickers/date-range-picker/#props). Some [SingleInputDateRangeField props](/x/api/date-pickers/single-input-date-range-field/#props) are not available on the Picker component, you can use `slotProps.field` to pass them to the field. ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRange } from '@mui/x-date-pickers-pro/models'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; export default function DateRangePickerValue() { const [value, setValue] = React.useState>([ dayjs('2022-04-17'), dayjs('2022-04-21'), ]); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Available components The component is available in four variants: - The `DesktopDateRangePicker` component which works best for mouse devices and large screens. It renders the views inside a popover and a field for keyboard editing. - The `MobileDateRangePicker` component which works best for touch devices and small screens. It renders the view inside a modal and does not let users edit values with the keyboard in the field. - The `DateRangePicker` component which renders `DesktopDateRangePicker` or `MobileDateRangePicker` depending on the device it runs on. - The `StaticDateRangePicker` component which renders without the popover/modal and field. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { MobileDateRangePicker } from '@mui/x-date-pickers-pro/MobileDateRangePicker'; import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; import { pickersLayoutClasses } from '@mui/x-date-pickers/PickersLayout'; export default function ResponsiveDateRangePickers() { return ( ); } ``` By default, the `DateRangePicker` component renders the desktop version if the media query [`@media (pointer: fine)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer) matches. This can be customized with the `desktopModeMediaQuery` prop. :::warning Responsive components can suffer some inconsistencies between testing environments if media query is not supported. Please refer to [this section](/x/react-date-pickers/base-concepts/#testing-caveats) for solutions. ::: ## Form props The component supports the `disabled`, `readOnly` and `name` form props: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; export default function FormPropsDateRangePickers() { return ( ); } ``` :::success The `name` prop is not available when using the Date Range Picker with the Multi Input Date Range Field. ::: ## Customization ### Render 1 to 3 months You can render up to 3 months at the same time using the `calendars` prop. :::info This prop will be ignored on the mobile picker. ::: ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; export default function DateRangePickerCalendarProp() { return ( ); } ``` ### Use a multi input field You can pass the `MultiInputDateRangeField` component to the Date Range Picker to use it for keyboard editing. ```tsx import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; export default function MultiInputDateRangePicker() { return ( ); } ``` :::info You can find more information in a [dedicated documentation page section](/x/react-date-pickers/custom-field/#usage-inside-a-range-picker). ::: ### Add shortcuts To simplify range selection, you can add [shortcuts](/x/react-date-pickers/shortcuts/#range-shortcuts). ```tsx import dayjs, { Dayjs } from 'dayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { StaticDateRangePicker } from '@mui/x-date-pickers-pro/StaticDateRangePicker'; import { PickersShortcutsItem } from '@mui/x-date-pickers/PickersShortcuts'; import { DateRange } from '@mui/x-date-pickers-pro/models'; const shortcutsItems: PickersShortcutsItem>[] = [ { label: 'This Week', getValue: () => { const today = dayjs(); return [today.startOf('week'), today.endOf('week')]; }, }, { label: 'Last Week', getValue: () => { const today = dayjs(); const prevWeek = today.subtract(7, 'day'); return [prevWeek.startOf('week'), prevWeek.endOf('week')]; }, }, { label: 'Last 7 Days', getValue: () => { const today = dayjs(); return [today.subtract(7, 'day'), today]; }, }, { label: 'Current Month', getValue: () => { const today = dayjs(); return [today.startOf('month'), today.endOf('month')]; }, }, { label: 'Next Month', getValue: () => { const today = dayjs(); const startOfNextMonth = today.endOf('month').add(1, 'day'); return [startOfNextMonth, startOfNextMonth.endOf('month')]; }, }, { label: 'Reset', getValue: () => [null, null] }, ]; export default function BasicRangeShortcuts() { return ( ); } ``` ### Customize the field You can find the documentation in the [Custom field page](/x/react-date-pickers/custom-field/). ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. ## Month Range Picker 🚧 :::warning This component isn't available yet, but it is planned—you can 👍 upvote [this GitHub issue](https://github.com/mui/mui-x/issues/4995) to help us prioritize it. Please don't hesitate to leave a comment there to describe your needs, especially if you have a use case we should address or you're facing specific pain points with your current solution. ::: The Month Range Picker would let users select a range of months. --- # Source: https://mui.com/x/api/date-pickers/date-time-field.md # Source: https://mui.com/x/react-date-pickers/date-time-field.md --- productId: x-date-pickers title: React Date Field component components: DateTimeField githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Date Time Field The Date Time Field component lets users select a date and a time with the keyboard. ## Basic usage ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateTimeField } from '@mui/x-date-pickers/DateTimeField'; export default function BasicDateTimeField() { return ( ); } ``` ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateTimeField } from '@mui/x-date-pickers/DateTimeField'; export default function DateTimeFieldValue() { const [value, setValue] = React.useState(dayjs('2022-04-17T15:30')); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ### Customize the date time format ```tsx import dayjs from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateTimeField } from '@mui/x-date-pickers/DateTimeField'; export default function CustomDateTimeFormat() { return ( ); } ``` :::info See [Date format and localization—Custom formats](/x/react-date-pickers/adapters-locale/#custom-formats) for more details. ::: ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/api/date-pickers/date-time-picker-tabs.md # DateTimePickerTabs API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) ## Import ```jsx import { DateTimePickerTabs } from '@mui/x-date-pickers/DateTimePicker'; // or import { DateTimePickerTabs } from '@mui/x-date-pickers'; // or import { DateTimePickerTabs } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | dateIcon | `node` | `DateRange` | No | | | hidden | `bool` | ``window.innerHeight < 667` for `DesktopDateTimePicker` and `MobileDateTimePicker`, `displayStaticWrapperAs === 'desktop'` for `StaticDateTimePicker`` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timeIcon | `node` | `Time` | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/DateTimePicker/DateTimePickerTabs.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/DateTimePicker/DateTimePickerTabs.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-time-picker-toolbar.md # DateTimePickerToolbar API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) ## Import ```jsx import { DateTimePickerToolbar } from '@mui/x-date-pickers/DateTimePicker'; // or import { DateTimePickerToolbar } from '@mui/x-date-pickers'; // or import { DateTimePickerToolbar } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | hidden | `bool` | ``true` for Desktop, `false` for Mobile.` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | toolbarFormat | `string` | - | No | | | toolbarPlaceholder | `node` | `"––"` | No | | | toolbarTitle | `node` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | ampmLabel | Styles applied to am/pm labels. | | - | ampmLandscape | Styles applied to am/pm section in landscape mode. | | - | ampmSelection | Styles applied to the am/pm section. | | - | dateContainer | Styles applied to the date container element. | | - | root | Styles applied to the root element. | | - | separator | Styles applied to the separator element. | | - | timeContainer | Styles applied to the time container element. | | - | timeDigitsContainer | Styles applied to the time (except am/pm) container element. | | - | timeLabelReverse | Styles applied to the time container if rtl. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/DateTimePicker/DateTimePickerToolbar.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-time-picker.md # Source: https://mui.com/x/react-date-pickers/date-time-picker.md --- productId: x-date-pickers title: React Date Time Picker component components: DateTimePicker, DesktopDateTimePicker, MobileDateTimePicker, StaticDateTimePicker, DigitalClock, MultiSectionDigitalClock, TimeClock githubLabel: 'component: DateTimePicker' packageName: '@mui/x-date-pickers' materialDesign: https://m2.material.io/components/date-pickers --- # Date Time Picker The Date Time Picker component lets users select a date and time. ## Basic usage ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; export default function BasicDateTimePicker() { return ( ); } ``` ## Component composition The component is built using the `DateTimeField` for the keyboard editing, the `DateCalendar` for the date view editing and `DigitalClock` for the time view editing. Check out their documentation page for more information: - [Date Field](/x/react-date-pickers/date-field/) - [Date Calendar](/x/react-date-pickers/date-calendar/) - [Digital Clock](/x/react-date-pickers/digital-clock/) You can check the available props of the combined component on the dedicated [API page](/x/api/date-pickers/date-time-picker/#props). Some [DateTimeField props](/x/api/date-pickers/date-time-field/#props) are not available on the Picker component, you can use `slotProps.field` to pass them to the field. ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; export default function DateTimePickerValue() { const [value, setValue] = React.useState(dayjs('2022-04-17T15:30')); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Available components The component is available in four variants: - The `DesktopDateTimePicker` component which works best for mouse devices and large screens. It renders the views inside a popover and a field for keyboard editing. - The `MobileDateTimePicker` component which works best for touch devices and small screens. It renders the view inside a modal and a field for keyboard editing. - The `DateTimePicker` component which renders `DesktopDateTimePicker` or `MobileDateTimePicker` depending on the device it runs on. - The `StaticDateTimePicker` component which renders without the popover/modal and field. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { MobileDateTimePicker } from '@mui/x-date-pickers/MobileDateTimePicker'; import { DesktopDateTimePicker } from '@mui/x-date-pickers/DesktopDateTimePicker'; import { StaticDateTimePicker } from '@mui/x-date-pickers/StaticDateTimePicker'; export default function ResponsiveDateTimePickers() { return ( ); } ``` By default, the `DateTimePicker` component renders the desktop version if the media query [`@media (pointer: fine)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer) matches. This can be customized with the `desktopModeMediaQuery` prop. :::warning Responsive components can suffer some inconsistencies between testing environments if media query is not supported. Please refer to [this section](/x/react-date-pickers/base-concepts/#testing-caveats) for solutions. ::: ## Form props The component supports the `disabled`, `readOnly` and `name` form props: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; export default function FormPropsDateTimePickers() { return ( ); } ``` ## Views The component supports six views: `day`, `month`, `year`, `hours`, `minutes` and `seconds`. By default, the `year`, `day`, `hours`, and `minutes` views are enabled. Use the `views` prop to change this behavior: ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; export default function DateTimePickerViews() { return ( ); } ``` By default, the component renders the `day` view on mount. Use the `openTo` prop to change this behavior: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { MobileTimePicker } from '@mui/x-date-pickers/MobileTimePicker'; export default function DateTimePickerOpenTo() { return ( ); } ``` :::success The views will appear in the order defined by the `views` array. If the view defined in `openTo` is not the first view, then the views before will not be included in the default flow (for example view the default behaviors, the `year` is only accessible when clicking on the toolbar). ::: ## Landscape orientation By default, the Date Time Picker component automatically sets the orientation based on the `window.orientation` value. You can force a specific orientation using the `orientation` prop. ```tsx import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { StaticDateTimePicker } from '@mui/x-date-pickers/StaticDateTimePicker'; export default function StaticDateTimePickerLandscape() { return ( ); } ``` :::info You can find more information about the layout customization in the [custom layout page](/x/react-date-pickers/custom-layout/). ::: ## Choose time view renderer You can use the `viewRenderers` prop to change the view that is used for rendering a view. You might be interested in using the [Time Clock](/x/react-date-pickers/time-clock/) instead of the [Digital Clock](/x/react-date-pickers/digital-clock/) or removing the time view rendering altogether in favor of only using the field to input the time. ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker'; import { renderTimeViewClock } from '@mui/x-date-pickers/timeViewRenderers'; export default function DateTimePickerViewRenderers() { return ( ); } ``` ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/react-date-pickers/date-time-range-field.md --- productId: x-date-pickers title: React Date Time Range Field components components: MultiInputDateTimeRangeField, SingleInputDateTimeRangeField githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers-pro' --- # Date Time Range Field [](/x/introduction/licensing/#pro-plan 'Pro plan') The Date Time Range Field lets the user select a range of dates with an explicit starting and ending time with the keyboard. ## Basic usage :::info All the topics covered below are applicable to both `SingleInputDateTimeRangeField` and `MultiInputDateTimeRangeField` unless explicitly mentioned. ::: You can render your Date Time Range Field with either one input using `SingleInputDateTimeRangeField` or two inputs using `MultiInputDateTimeRangeField` as shown below. ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField'; import { SingleInputDateTimeRangeField } from '@mui/x-date-pickers-pro/SingleInputDateTimeRangeField'; export default function BasicDateTimeRangeField() { return ( ({ label: position === 'start' ? 'Check-in' : 'Check-out', }), }} /> ); } ``` ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRange } from '@mui/x-date-pickers-pro/models'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { SingleInputDateTimeRangeField } from '@mui/x-date-pickers-pro/SingleInputDateTimeRangeField'; export default function DateTimeRangeFieldValue() { const [value, setValue] = React.useState>(() => [ dayjs('2022-04-17T15:30'), dayjs('2022-04-21T18:30'), ]); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/api/date-pickers/date-time-range-picker-tabs.md # DateTimeRangePickerTabs API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Time Range Picker ## Import ```jsx import { DateTimeRangePickerTabs } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; // or import { DateTimeRangePickerTabs } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | dateIcon | `element` | `DateRangeIcon` | No | | | hidden | `bool` | ``window.innerHeight < 667` for `DesktopDateTimeRangePicker` and `MobileDateTimeRangePicker`` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timeIcon | `element` | `TimeIcon` | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | filler | Styles applied to the filler element, shown instead of a navigation arrow. | | - | navigationButton | Styles applied to the tab navigation button elements. | | - | root | Styles applied to the root element. | | - | tabButton | Styles applied to the tab button element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerTabs.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-time-range-picker-toolbar.md # DateTimeRangePickerToolbar API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Time Range Picker ## Import ```jsx import { DateTimeRangePickerToolbar } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; // or import { DateTimeRangePickerToolbar } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | hidden | `bool` | ``true` for Desktop, `false` for Mobile.` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | toolbarFormat | `string` | - | No | | | toolbarPlaceholder | `node` | `"––"` | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | endToolbar | Styles applied to the end toolbar element. | | - | root | Styles applied to the root element. | | - | startToolbar | Styles applied to the start toolbar element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePickerToolbar.tsx) --- # Source: https://mui.com/x/api/date-pickers/date-time-range-picker.md # Source: https://mui.com/x/react-date-pickers/date-time-range-picker.md --- productId: x-date-pickers title: React Date Time Range Picker component components: DateTimeRangePicker, DesktopDateTimeRangePicker, MobileDateTimeRangePicker, DateRangeCalendar, DateRangePickerDay, DigitalClock, MultiSectionDigitalClock, DateTimeRangePickerTabs, DateTimeRangePickerToolbar githubLabel: 'component: DateTimeRangePicker' packageName: '@mui/x-date-pickers-pro' materialDesign: https://m2.material.io/components/date-pickers --- # Date Time Range Picker [](/x/introduction/licensing/#pro-plan 'Pro plan') The Date Time Range Picker lets the user select a range of dates with an explicit starting and ending time. ## Basic usage ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; export default function BasicDateTimeRangePicker() { return ( ); } ``` ## Component composition The component is built using the `SingleInputDateTimeRangeField` for the keyboard editing, the `DateRangeCalendar` for the date view editing and `DigitalClock` for the time view editing. Check out their documentation page for more information: - [Date Time Range Field](/x/react-date-pickers/date-time-range-field/) - [Date Range Calendar](/x/react-date-pickers/date-range-calendar/) - [Digital Clock](/x/react-date-pickers/digital-clock/) You can check the available props of the combined component on the dedicated [API page](/x/api/date-pickers/date-time-range-picker/#props). Some [SingleInputDateTimeRangeField props](/x/api/date-pickers/single-input-date-time-range-field/#props) are not available on the Picker component, you can use `slotProps.field` to pass them to the field. ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateRange } from '@mui/x-date-pickers-pro/models'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; export default function DateTimeRangePickerValue() { const [value, setValue] = React.useState>([ dayjs('2022-04-17T15:30'), dayjs('2022-04-21T18:30'), ]); return ( setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Available components The component is available in three variants: - The `DesktopDateTimeRangePicker` component which works best for mouse devices and large screens. It renders the views inside a popover and a field for keyboard editing. - The `MobileDateTimeRangePicker` component which works best for touch devices and small screens. It renders the view inside a modal and does not let users edit values with the keyboard in the field. - The `DateTimeRangePicker` component which renders `DesktopDateTimeRangePicker` or `MobileDateTimeRangePicker` depending on the device it runs on. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; import { MobileDateTimeRangePicker } from '@mui/x-date-pickers-pro/MobileDateTimeRangePicker'; import { DesktopDateTimeRangePicker } from '@mui/x-date-pickers-pro/DesktopDateTimeRangePicker'; export default function ResponsiveDateTimeRangePickers() { return ( ); } ``` By default, the `DateTimeRangePicker` component renders the desktop version if the media query [`@media (pointer: fine)`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@media/pointer) matches. This can be customized with the `desktopModeMediaQuery` prop. :::warning Responsive components can suffer some inconsistencies between testing environments if media query is not supported. Please refer to [this section](/x/react-date-pickers/base-concepts/#testing-caveats) for solutions. ::: ## Form props The component supports the `disabled`, `readOnly` and `name` form props: ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; export default function FormPropsDateTimeRangePickers() { return ( ); } ``` ## Customization ### Render 1 to 3 months You can render up to 3 months at the same time using the `calendars` prop. :::info This prop will be ignored on the mobile picker. ::: ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers-pro/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers-pro/AdapterDayjs'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; export default function DateTimeRangePickerCalendarProp() { return ( ); } ``` ### Use a multi input field You can pass the `MultiInputDateTimeRangeField` component to the Date Time Range Picker to use it for keyboard editing: ```tsx import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; export default function MultiInputDateTimeRangePicker() { return ( ); } ``` :::info You can find more information in a [dedicated documentation page section](/x/react-date-pickers/custom-field/#usage-inside-a-range-picker). ::: ### Customize the field You can find the documentation in the [Custom field page](/x/react-date-pickers/custom-field/). ### Change view renderer You can pass a different view renderer to the Date Time Range Picker to customize the views. ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker'; import { renderDigitalClockTimeView, renderTimeViewClock, } from '@mui/x-date-pickers/timeViewRenderers'; export default function DateTimeRangePickerViewRenderer() { return ( ); } ``` ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/api/date-pickers/day-calendar-skeleton.md # DayCalendarSkeleton API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date Calendar](/x/react-date-pickers/date-calendar/) ## Import ```jsx import { DayCalendarSkeleton } from '@mui/x-date-pickers/DayCalendarSkeleton'; // or import { DayCalendarSkeleton } from '@mui/x-date-pickers'; // or import { DayCalendarSkeleton } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiDayCalendarSkeleton` to change the default props of this component with the theme. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | daySkeleton | Styles applied to the day element. | | - | root | Styles applied to the root element. | | - | week | Styles applied to the week element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/DayCalendarSkeleton/DayCalendarSkeleton.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/DayCalendarSkeleton/DayCalendarSkeleton.tsx) --- # Source: https://mui.com/x/api/date-pickers/desktop-date-picker.md # DesktopDatePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date Picker](/x/react-date-pickers/date-picker/) - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { DesktopDatePicker } from '@mui/x-date-pickers/DesktopDatePicker'; // or import { DesktopDatePicker } from '@mui/x-date-pickers'; // or import { DesktopDatePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `true` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | minDate | `object` | `1900-01-01` | No | | | monthsPerRow | `3 \| 4` | `3` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | onYearChange | `function(year: PickerValidDate) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'day' \| 'month' \| 'year'` | - | No | | | orientation | `'landscape' \| 'portrait'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => ...` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate) => boolean` | - | No | | | shouldDisableMonth | `function(month: PickerValidDate) => boolean` | - | No | | | shouldDisableYear | `function(year: PickerValidDate) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | | view | `'day' \| 'month' \| 'year'` | - | No | | | viewRenderers | `{ day?: func, month?: func, year?: func }` | - | No | | | views | `Array<'day' \| 'month' \| 'year'>` | - | No | | | yearsOrder | `'asc' \| 'desc'` | `'asc'` | No | | | yearsPerRow | `3 \| 4` | `4` | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `PickersDay` | - | Custom component for day. Check the [PickersDay](https://mui.com/x/api/date-pickers/pickers-day/) component. | | desktopPaper | `PickerPopperPaper` | - | Custom component for the paper rendered inside the desktop picker's Popper. | | desktopTransition | `Grow or Fade from '@mui/material' when `reduceAnimations` is `true`.` | - | Custom component for the desktop popper [Transition](https://mui.com/material-ui/transitions/). | | desktopTrapFocus | `TrapFocus from '@mui/material'.` | - | Custom component for trapping the focus inside the views on desktop. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | monthButton | `MonthCalendarButton` | - | Button displayed to render a single month in the `month` view. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | popper | `Popper from '@mui/material'.` | - | Custom component for the popper inside which the views are rendered on desktop. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DatePickerToolbar` | - | Custom component for the toolbar rendered above the views. | | yearButton | `YearCalendarButton` | - | Button displayed to render a single year in the `year` view. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/desktop-date-range-picker.md # DesktopDateRangePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Range Picker - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro/DesktopDateRangePicker'; // or import { DesktopDateRangePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | autoFocus | `bool` | - | No | | | calendars | `1 \| 2 \| 3` | `2` | No | | | closeOnSelect | `bool` | `true` | No | | | currentMonthCalendarPosition | `1 \| 2 \| 3` | `1` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultRangePosition | `'end' \| 'start'` | `'start'` | No | | | defaultValue | `Array` | - | No | | | disableAutoMonthSwitching | `bool` | `false` | No | | | disabled | `bool` | `false` | No | | | disableDragEditing | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | minDate | `object` | `1900-01-01` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onRangePositionChange | `function(rangePosition: RangePosition) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | open | `bool` | `false` | No | | | rangePosition | `'end' \| 'start'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `Array \| object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => "..."` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate, position: string) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `Array` | - | No | | | viewRenderers | `{ day?: func }` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `DateRangePickersDay` | - | Custom component for day in range pickers. Check the [DateRangePickersDay](https://mui.com/x/api/date-pickers/date-range-picker-day/) component. | | desktopPaper | `PickerPopperPaper` | - | Custom component for the paper rendered inside the desktop picker's Popper. | | desktopTransition | `Grow or Fade from '@mui/material' when `reduceAnimations` is `true`.` | - | Custom component for the desktop popper [Transition](https://mui.com/material-ui/transitions/). | | desktopTrapFocus | `TrapFocus from '@mui/material'.` | - | Custom component for trapping the focus inside the views on desktop. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | popper | `Popper from '@mui/material'.` | - | Custom component for the popper inside which the views are rendered on desktop. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DateTimePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/desktop-date-time-picker.md # DesktopDateTimePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date Time Picker](/x/react-date-pickers/date-time-picker/) - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { DesktopDateTimePicker } from '@mui/x-date-pickers/DesktopDateTimePicker'; // or import { DesktopDateTimePicker } from '@mui/x-date-pickers'; // or import { DesktopDateTimePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | ampmInClock | `bool` | `true on desktop, false on mobile` | No | | | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | maxDateTime | `object` | - | No | | | maxTime | `object` | - | No | | | minDate | `object` | `1900-01-01` | No | | | minDateTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | monthsPerRow | `3 \| 4` | `3` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | onYearChange | `function(year: PickerValidDate) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'day' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'year'` | - | No | | | orientation | `'landscape' \| 'portrait'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => ...` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate) => boolean` | - | No | | | shouldDisableMonth | `function(month: PickerValidDate) => boolean` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | shouldDisableYear | `function(year: PickerValidDate) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | skipDisabled | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | thresholdToRenderTimeInASingleColumn | `number` | `24` | No | | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | | view | `'day' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'year'` | - | No | | | viewRenderers | `{ day?: func, hours?: func, meridiem?: func, minutes?: func, month?: func, seconds?: func, year?: func }` | - | No | | | views | `Array<'day' \| 'hours' \| 'minutes' \| 'month' \| 'seconds' \| 'year'>` | - | No | | | yearsOrder | `'asc' \| 'desc'` | `'asc'` | No | | | yearsPerRow | `3 \| 4` | `4` | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `PickersDay` | - | Custom component for day. Check the [PickersDay](https://mui.com/x/api/date-pickers/pickers-day/) component. | | desktopPaper | `PickerPopperPaper` | - | Custom component for the paper rendered inside the desktop picker's Popper. | | desktopTransition | `Grow or Fade from '@mui/material' when `reduceAnimations` is `true`.` | - | Custom component for the desktop popper [Transition](https://mui.com/material-ui/transitions/). | | desktopTrapFocus | `TrapFocus from '@mui/material'.` | - | Custom component for trapping the focus inside the views on desktop. | | digitalClockItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single digital clock item. | | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | monthButton | `MonthCalendarButton` | - | Button displayed to render a single month in the `month` view. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | popper | `Popper from '@mui/material'.` | - | Custom component for the popper inside which the views are rendered on desktop. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | tabs | `DateTimePickerTabs` | - | Tabs enabling toggling between date and time pickers. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DateTimePickerToolbar` | - | Custom component for the toolbar rendered above the views. | | yearButton | `YearCalendarButton` | - | Button displayed to render a single year in the `year` view. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/desktop-date-time-range-picker.md # DesktopDateTimeRangePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Time Range Picker - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { DesktopDateTimeRangePicker } from '@mui/x-date-pickers-pro/DesktopDateTimeRangePicker'; // or import { DesktopDateTimeRangePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | autoFocus | `bool` | - | No | | | calendars | `1 \| 2 \| 3` | `1` | No | | | closeOnSelect | `bool` | `false` | No | | | currentMonthCalendarPosition | `1 \| 2 \| 3` | `1` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultRangePosition | `'end' \| 'start'` | `'start'` | No | | | defaultValue | `Array` | - | No | | | disableAutoMonthSwitching | `bool` | `false` | No | | | disabled | `bool` | `false` | No | | | disableDragEditing | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | maxDateTime | `object` | - | No | | | maxTime | `object` | - | No | | | minDate | `object` | `1900-01-01` | No | | | minDateTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onRangePositionChange | `function(rangePosition: RangePosition) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'day' \| 'hours' \| 'minutes' \| 'seconds'` | - | No | | | rangePosition | `'end' \| 'start'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `Array \| object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => "..."` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate, position: string) => boolean` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | skipDisabled | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | thresholdToRenderTimeInASingleColumn | `number` | `24` | No | | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `Array` | - | No | | | view | `'day' \| 'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | viewRenderers | `{ day?: func, hours?: func, meridiem?: func, minutes?: func, seconds?: func }` | - | No | | | views | `Array<'day' \| 'hours' \| 'minutes' \| 'seconds'>` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `DateRangePickersDay` | - | Custom component for day in range pickers. Check the [DateRangePickersDay](https://mui.com/x/api/date-pickers/date-range-picker-day/) component. | | desktopPaper | `PickerPopperPaper` | - | Custom component for the paper rendered inside the desktop picker's Popper. | | desktopTransition | `Grow or Fade from '@mui/material' when `reduceAnimations` is `true`.` | - | Custom component for the desktop popper [Transition](https://mui.com/material-ui/transitions/). | | desktopTrapFocus | `TrapFocus from '@mui/material'.` | - | Custom component for trapping the focus inside the views on desktop. | | digitalClockItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single digital clock item. | | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | popper | `Popper from '@mui/material'.` | - | Custom component for the popper inside which the views are rendered on desktop. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | tabs | `DateTimeRangePickerTabs` | - | Tabs enabling toggling between date and time pickers. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DateTimeRangePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/desktop-time-picker.md # DesktopTimePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Time Picker](/x/react-date-pickers/time-picker/) - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { DesktopTimePicker } from '@mui/x-date-pickers/DesktopTimePicker'; // or import { DesktopTimePicker } from '@mui/x-date-pickers'; // or import { DesktopTimePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | ampmInClock | `bool` | `true on desktop, false on mobile` | No | | | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | localeText | `object` | - | No | | | maxTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onOpen | `func` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | orientation | `'landscape' \| 'portrait'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | skipDisabled | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | thresholdToRenderTimeInASingleColumn | `number` | `24` | No | | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | | view | `'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | viewRenderers | `{ hours?: func, meridiem?: func, minutes?: func, seconds?: func }` | - | No | | | views | `Array<'hours' \| 'minutes' \| 'seconds'>` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | desktopPaper | `PickerPopperPaper` | - | Custom component for the paper rendered inside the desktop picker's Popper. | | desktopTransition | `Grow or Fade from '@mui/material' when `reduceAnimations` is `true`.` | - | Custom component for the desktop popper [Transition](https://mui.com/material-ui/transitions/). | | desktopTrapFocus | `TrapFocus from '@mui/material'.` | - | Custom component for trapping the focus inside the views on desktop. | | digitalClockItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single digital clock item. | | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | popper | `Popper from '@mui/material'.` | - | Custom component for the popper inside which the views are rendered on desktop. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `TimePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/desktop-time-range-picker.md # DesktopTimeRangePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Time Range Picker - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { DesktopTimeRangePicker } from '@mui/x-date-pickers-pro/DesktopTimeRangePicker'; // or import { DesktopTimeRangePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | defaultRangePosition | `'end' \| 'start'` | `'start'` | No | | | defaultValue | `Array` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `func \| { current?: object }` | - | No | | | label | `node` | - | No | | | localeText | `object` | - | No | | | maxTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onOpen | `func` | - | No | | | onRangePositionChange | `function(rangePosition: RangePosition) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'hours' \| 'minutes' \| 'seconds'` | - | No | | | rangePosition | `'end' \| 'start'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `Array \| object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | skipDisabled | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | thresholdToRenderTimeInASingleColumn | `number` | `24` | No | | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `Array` | - | No | | | view | `'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | viewRenderers | `{ hours?: func, meridiem?: func, minutes?: func, seconds?: func }` | - | No | | | views | `Array<'hours' \| 'minutes' \| 'seconds'>` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | desktopPaper | `PickerPopperPaper` | - | Custom component for the paper rendered inside the desktop picker's Popper. | | desktopTransition | `Grow or Fade from '@mui/material' when `reduceAnimations` is `true`.` | - | Custom component for the desktop popper [Transition](https://mui.com/material-ui/transitions/). | | desktopTrapFocus | `TrapFocus from '@mui/material'.` | - | Custom component for trapping the focus inside the views on desktop. | | digitalClockItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single digital clock item. | | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | popper | `Popper from '@mui/material'.` | - | Custom component for the popper inside which the views are rendered on desktop. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | tabs | `TimeRangePickerTabs` | - | Tabs enabling toggling between start and end time. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | Toolbar | `TimeRangePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/DesktopTimeRangePicker/DesktopTimeRangePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/DesktopTimeRangePicker/DesktopTimeRangePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/digital-clock.md # Source: https://mui.com/x/react-date-pickers/digital-clock.md --- productId: x-date-pickers title: React Digital Clock component components: DigitalClock, MultiSectionDigitalClock githubLabel: 'component: TimePicker' packageName: '@mui/x-date-pickers' --- # Digital Clock The Digital Clock lets the user select a time without any input or popper / modal. ## Description There are two component versions for different cases. The `DigitalClock` handles selection of a single time instance in one step, just like a `select` component. The `MultiSectionDigitalClock` lets users select time using separate sections for separate views. The `DigitalClock` is more appropriate when there is a limited number of time options needed, while the `MultiSectionDigitalClock` is suited for cases when a more granular time selection is needed. ## Basic usage ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; export default function DigitalClockBasic() { return ( ); } ``` ## Uncontrolled vs. controlled value The value of the component can be uncontrolled or controlled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; export default function DigitalClockValue() { const [value, setValue] = React.useState(dayjs('2022-04-17T15:30')); return ( setValue(newValue)} /> setValue(newValue)} /> ); } ``` :::info - The value is **controlled** when its parent manages it by providing a `value` prop. - The value is **uncontrolled** when it is managed by the component's own internal state. This state can be initialized using the `defaultValue` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Form props The components can be disabled or read-only. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; export default function DigitalClockFormProps() { return ( ); } ``` ## Views The `MultiSectionDigitalClock` component can contain three views: `hours`, `minutes`, and `seconds`. By default, only the `hours` and `minutes` views are enabled. You can customize the enabled views using the `views` prop. Views will appear in the order they're included in the `views` array. ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; export default function DigitalClockViews() { return ( ); } ``` ## 12h/24h format The components use the hour format of the locale's time setting, that is the 12-hour or 24-hour format. You can force a specific format using the `ampm` prop. You can find more information about 12h/24h format in the [Date localization page](/x/react-date-pickers/adapters-locale/#meridiem-12h-24h-format). ```tsx import dayjs from 'dayjs'; import Typography from '@mui/material/Typography'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; export default function DigitalClockAmPm() { return ( Locale default behavior (enabled for enUS) AM PM enabled AM PM disabled ); } ``` ## Time steps By default, the components list the time options in the following way: - `DigitalClock` in `30` minutes intervals; - `MultiSectionDigitalClock` component in `5` unit (`minutes` or `seconds`) intervals; You can set the desired interval using the `timeStep` and `timeSteps` props. The prop accepts: - The `DigitalClock` component accepts a `number` value `timeStep` prop; - The `MultiSectionDigitalClock` component accepts a `timeSteps` prop with `number` values for `hours`, `minutes`, or `seconds` units; ```tsx import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; export default function DigitalClockTimeStep() { return ( ); } ``` ## Skip rendering disabled options With the `skipDisabled` prop, the components don't render options that are not available to the user (for example through `minTime`, `maxTime`, `shouldDisableTime` etc.). The following example combines these properties to customize which options are rendered. - The first component does not show options before `9:00` (the value of `minTime`). - The second one shows options between `09:00` and `13:20` thanks to `shouldDisableTime`. ```tsx import dayjs, { Dayjs } from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DigitalClock } from '@mui/x-date-pickers/DigitalClock'; import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; import { TimeView } from '@mui/x-date-pickers/models'; const shouldDisableTime = (date: Dayjs, view: TimeView) => { const hour = date.hour(); if (view === 'hours') { return hour < 9 || hour > 13; } if (view === 'minutes') { const minute = date.minute(); return minute > 20 && hour === 13; } return false; }; export default function DigitalClockSkipDisabled() { return ( ); } ``` ## Localization See the [Date format and localization](/x/react-date-pickers/adapters-locale/) and [Translated components](/x/react-date-pickers/localization/) documentation pages for more details. ## Validation See the [Validation](/x/react-date-pickers/validation/) documentation page for more details. --- # Source: https://mui.com/x/react-data-grid/editing/editing-events.md # Data Grid - Editing events Using editing events. The interactions that [start](/x/react-data-grid/editing/#start-editing) and [stop](/x/react-data-grid/editing/#stop-editing) trigger `'cellEditStart'` and `'cellEditStop'` [events](/x/react-data-grid/events/), respectively. For [row editing](/x/react-data-grid/editing/#row-editing), the events are `'rowEditStart'` and `'rowEditStop'`. You can control how these events are handled to customize editing behavior. For convenience, you can also listen to these events using their respective props: - `onCellEditStart()` - `onCellEditStop()` - `onRowEditStart()` - `onRowEditStop()` These events and props are called with an object containing the row ID and column field of the cell that is being edited. The object also contains a `reason` param that specifies which type of interaction caused the event to be fired—for instance, `'cellDoubleClick'` when a double-click initiates edit mode. The following demo shows how to prevent the user from exiting edit mode when clicking outside of a cell. To do this, the `onCellEditStop()` prop is used to check if the `reason` is `'cellFocusOut'`. If that condition is true, it [disables](/x/react-data-grid/events/#disabling-the-default-behavior) the default event behavior. In this context, the user can only stop editing a cell by pressing Enter, Escape or Tab. ```tsx import { GridColDef, GridRowsProp, DataGrid, GridCellEditStopParams, GridCellEditStopReasons, MuiEvent, } from '@mui/x-data-grid'; import { randomCreatedDate, randomTraderName, randomUpdatedDate, } from '@mui/x-data-grid-generator'; export default function DisableStopEditModeOnFocusOut() { return (
{ if (params.reason === GridCellEditStopReasons.cellFocusOut) { event.defaultMuiPrevented = true; } }} />
); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 180, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true, align: 'left', headerAlign: 'left', }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/editing.md # Source: https://mui.com/x/react-tree-view/rich-tree-view/editing.md --- productId: x-tree-view components: RichTreeView, TreeItem githubLabel: 'scope: tree view' packageName: '@mui/x-tree-view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ packageName: '@mui/x-tree-view' --- # Rich Tree View - Label editing Learn how to edit Tree View item labels. ## Enable label editing Use the `isItemEditable` prop to enable editing. If set to `true`, this prop enables label editing on all items as shown in the demo below: ```tsx import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { MUI_X_PRODUCTS } from './products'; export default function LabelEditingAllItems() { return ( ); } ``` :::success If an item is editable, the editing state can be toggled by double clicking on it, or by pressing Enter on the keyboard when the item is in focus. Once an item is in the editing state, the value of the label can be edited. Pressing Enter again or blurring the item will save the new value. Pressing Esc will cancel the action and restore the item to its original state. ::: ## Limit editing to some items If you pass a method to `isItemEditable`, then only the items for which the method returns `true` will be editable: ```tsx import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { MUI_X_PRODUCTS } from './editableProducts'; export default function LabelEditingSomeItems() { return ( Boolean(item?.editable)} defaultExpandedItems={['grid', 'pickers']} /> ); } ``` ### Limit editing to leaves You can limit editing to just the leaves of the tree, as shown below: ```tsx import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { useRichTreeViewApiRef } from '@mui/x-tree-view/hooks'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; type ExtendedTreeItemProps = { editable?: boolean; id: string; label: string; }; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ { id: 'grid', label: 'Data Grid', children: [ { id: 'grid-community', label: '@mui/x-data-grid' }, { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, ], }, { id: 'pickers', label: 'Date and Time pickers', children: [ { id: 'pickers-community', label: '@mui/x-date-pickers', }, { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, ], }, { id: 'charts', label: 'Charts', children: [{ id: 'charts-community', label: '@mui/x-charts' }], }, { id: 'tree-view', label: 'Tree View', children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], }, ]; export default function EditLeaves() { const apiRef = useRichTreeViewApiRef(); return ( apiRef.current!.getItemOrderedChildrenIds(item.id).length === 0 } defaultExpandedItems={['grid', 'pickers']} /> ); } ``` ## Track item label change Use the `onItemLabelChange` prop to trigger an action when an item label changes: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { MUI_X_PRODUCTS } from './products'; export default function EditingCallback() { const [lastEditedItem, setLastEditedItem] = React.useState<{ itemId: string; label: string; } | null>(null); return ( {lastEditedItem ? ( The label of item with id {lastEditedItem!.itemId} has been edited to {lastEditedItem!.label} ) : ( No item has been edited yet )} setLastEditedItem({ itemId, label })} /> ); } ``` ## Change the default behavior By default, blurring a `TreeItem` saves the new value if there is one. To modify this behavior, use the `slotProps` on the `TreeItem` as shown below: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; import { TreeItem, TreeItemProps } from '@mui/x-tree-view/TreeItem'; import { UseTreeItemLabelInputSlotOwnProps } from '@mui/x-tree-view/useTreeItem'; import { MUI_X_PRODUCTS } from './products'; const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: TreeItemProps, ref: React.Ref, ) { const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { interactions.handleCancelItemLabelEditing(event); }; return ( ); }); export default function CustomBehavior() { return ( ); } ``` ## Validation You can override the event handlers of the `labelInput` and implement a custom validation logic using the interaction methods from `useTreeItemUtils()`: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Tooltip from '@mui/material/Tooltip'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import ErrorOutlineIcon from '@mui/icons-material/ErrorOutline'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; import { TreeItem, TreeItemProps } from '@mui/x-tree-view/TreeItem'; import { UseTreeItemLabelInputSlotOwnProps } from '@mui/x-tree-view/useTreeItem'; import { TreeItemLabelInput } from '@mui/x-tree-view/TreeItemLabelInput'; import { MUI_X_PRODUCTS } from './products'; const ERRORS = { REQUIRED: 'The label cannot be empty', INVALID: 'The label cannot contain digits', }; interface CustomLabelInputProps extends UseTreeItemLabelInputSlotOwnProps { error: null | keyof typeof ERRORS; } function CustomLabelInput(props: Omit) { const { error, ...other } = props; return ( {error ? ( ) : ( )} ); } const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: TreeItemProps, ref: React.Ref, ) { const [error, setError] = React.useState(null); const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); const validateLabel = (label: string) => { if (!label) { setError('REQUIRED'); } else if (/\d/.test(label)) { setError('INVALID'); } else { setError(null); } }; const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { if (error) { event.defaultMuiPrevented = true; } }; const handleInputKeyDown: UseTreeItemLabelInputSlotOwnProps['onKeyDown'] = ( event, ) => { event.defaultMuiPrevented = true; const target = event.target as HTMLInputElement; if (event.key === 'Enter' && target.value) { if (error) { return; } setError(null); interactions.handleSaveItemLabel(event, target.value); } else if (event.key === 'Escape') { setError(null); interactions.handleCancelItemLabelEditing(event); } }; const handleInputChange = (event: React.ChangeEvent) => { validateLabel(event.target.value); }; return ( ); }); export default function Validation() { return ( ); } ``` ## Enable editing using only icons The demo below shows how to completely override the editing behavior and implement it using icons: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import IconButton from '@mui/material/IconButton'; import EditOutlinedIcon from '@mui/icons-material/EditOutlined'; import CloseRoundedIcon from '@mui/icons-material/CloseRounded'; import CheckIcon from '@mui/icons-material/Check'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { useTreeItemUtils } from '@mui/x-tree-view/hooks'; import { TreeItem, TreeItemLabel, TreeItemProps } from '@mui/x-tree-view/TreeItem'; import { TreeItemLabelInput } from '@mui/x-tree-view/TreeItemLabelInput'; import { UseTreeItemLabelInputSlotOwnProps, UseTreeItemLabelSlotOwnProps, } from '@mui/x-tree-view/useTreeItem'; import { MUI_X_PRODUCTS } from './products'; interface CustomLabelProps extends UseTreeItemLabelSlotOwnProps { editable: boolean; editing: boolean; toggleItemEditing: () => void; } function CustomLabel({ editing, editable, children, toggleItemEditing, ...other }: CustomLabelProps) { return ( {children} {editable && ( )} ); } interface CustomLabelInputProps extends UseTreeItemLabelInputSlotOwnProps { handleCancelItemLabelEditing: (event: React.SyntheticEvent) => void; handleSaveItemLabel: (event: React.SyntheticEvent, label: string) => void; value: string; } function CustomLabelInput(props: Omit) { const { handleCancelItemLabelEditing, handleSaveItemLabel, value, ...other } = props; return ( { handleSaveItemLabel(event, value); }} > ); } const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: TreeItemProps, ref: React.Ref, ) { const { interactions, status } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); const handleContentDoubleClick: UseTreeItemLabelSlotOwnProps['onDoubleClick'] = ( event, ) => { event.defaultMuiPrevented = true; }; const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { event.defaultMuiPrevented = true; }; const handleInputKeyDown: UseTreeItemLabelInputSlotOwnProps['onKeyDown'] = ( event, ) => { event.defaultMuiPrevented = true; }; return ( ); }); export default function EditWithIcons() { return ( ); } ``` ## Create a custom labelInput The demo below shows how to use a different component in the `labelInput` slot: ```tsx import * as React from 'react'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import CheckIcon from '@mui/icons-material/Check'; import IconButton from '@mui/material/IconButton'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import CloseRoundedIcon from '@mui/icons-material/CloseRounded'; import { TreeItem, TreeItemLabel, TreeItemProps } from '@mui/x-tree-view/TreeItem'; import { UseTreeItemLabelInputSlotOwnProps, UseTreeItemLabelSlotOwnProps, } from '@mui/x-tree-view/useTreeItem'; import { useTreeItemUtils, useTreeItemModel } from '@mui/x-tree-view/hooks'; import { TreeViewBaseItem, TreeViewItemId } from '@mui/x-tree-view/models'; const StyledLabelInput = styled('input')(({ theme }) => ({ ...theme.typography.body1, backgroundColor: (theme.vars || theme).palette.background.paper, borderRadius: theme.shape.borderRadius, border: 'none', padding: '0 2px', boxSizing: 'border-box', width: 100, '&:focus': { outline: `1px solid ${(theme.vars || theme).palette.primary.main}`, }, })); type ExtendedTreeItemProps = { editable?: boolean; id: string; firstName: string; lastName: string; }; export const ITEMS: TreeViewBaseItem[] = [ { id: '1', firstName: 'Jane', lastName: 'Doe', editable: true, children: [ { id: '1.1', firstName: 'Elena', lastName: 'Kim', editable: true }, { id: '1.2', firstName: 'Noah', lastName: 'Rodriguez', editable: true }, { id: '1.3', firstName: 'Maya', lastName: 'Patel', editable: true }, ], }, { id: '2', firstName: 'Liam', lastName: 'Clarke', editable: true, children: [ { id: '2.1', firstName: 'Ethan', lastName: 'Lee', editable: true, }, { id: '2.2', firstName: 'Ava', lastName: 'Jones', editable: true }, ], }, ]; function Label({ children, ...other }: UseTreeItemLabelSlotOwnProps) { return ( {children} ); } interface CustomLabelInputProps extends UseTreeItemLabelInputSlotOwnProps { handleCancelItemLabelEditing: (event: React.SyntheticEvent) => void; handleSaveItemLabel: (event: React.SyntheticEvent, label: string) => void; itemId: TreeViewItemId; } const LabelInput = React.forwardRef(function LabelInput( { itemId, handleCancelItemLabelEditing, handleSaveItemLabel, ...props }: Omit, ref: React.Ref, ) { const item = useTreeItemModel(itemId)!; const [initialNameValue, setInitialNameValue] = React.useState({ firstName: item.firstName, lastName: item.lastName, }); const [nameValue, setNameValue] = React.useState({ firstName: item.firstName, lastName: item.lastName, }); const handleFirstNameChange = (event: React.ChangeEvent) => { setNameValue((prev) => ({ ...prev, firstName: event.target.value })); }; const handleLastNameChange = (event: React.ChangeEvent) => { setNameValue((prev) => ({ ...prev, lastName: event.target.value })); }; const reset = () => { setNameValue(initialNameValue); }; const save = () => { setInitialNameValue(nameValue); }; return ( { handleSaveItemLabel(event, `${nameValue.firstName} ${nameValue.lastName}`); save(); }} > { handleCancelItemLabelEditing(event); reset(); }} > ); }); const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: TreeItemProps, ref: React.Ref, ) { const { interactions } = useTreeItemUtils({ itemId: props.itemId, children: props.children, }); const handleInputBlur: UseTreeItemLabelInputSlotOwnProps['onBlur'] = (event) => { event.defaultMuiPrevented = true; }; const handleInputKeyDown: UseTreeItemLabelInputSlotOwnProps['onKeyDown'] = ( event, ) => { event.defaultMuiPrevented = true; }; return ( ); }); export default function CustomLabelInput() { return ( `${item.firstName} ${item.lastName}`} /> ); } ``` ## Imperative API To use the `apiRef` object, you need to initialize it using the `useRichTreeViewApiRef()` or `useRichTreeViewProApiRef()` hook as follows: ```tsx // Community package const apiRef = useRichTreeViewApiRef(); return ; // Pro package const apiRef = useRichTreeViewProApiRef(); return ; ``` When your component first renders, `apiRef.current` is `undefined`. After the initial render, `apiRef` holds methods to interact imperatively with `RichTreeView`. ### Change the label of an item Use the `updateItemLabel()` API method to imperatively update the label of an item. ```ts apiRef.current.updateItemLabel( // The id of the item to update itemId, // The new label of the item newLabel, ); ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { useRichTreeViewApiRef } from '@mui/x-tree-view/hooks'; import { MUI_X_PRODUCTS } from './products'; export default function ApiMethodUpdateItemLabel() { const [isLabelUpdated, setIsLabelUpdated] = React.useState(false); const apiRef = useRichTreeViewApiRef(); const handleUpdateLabel = () => { if (isLabelUpdated) { apiRef.current!.updateItemLabel('grid', 'Data Grid'); setIsLabelUpdated(false); } else { apiRef.current!.updateItemLabel('grid', 'New Label'); setIsLabelUpdated(true); } }; return ( ); } ``` ### Change edition mode of an item Use the `setEditedItem()` API method to set which item is being edited. ```ts apiRef.current.setEditedItem( // The id of the item to edit, or `null` to exit editing mode itemId, ); ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { RichTreeView } from '@mui/x-tree-view/RichTreeView'; import { useRichTreeViewApiRef } from '@mui/x-tree-view/hooks'; export default function ApiMethodSetEditedItem() { const [items, setItems] = React.useState([ { id: '1', label: 'Jane Doe', editable: true }, ]); const apiRef = useRichTreeViewApiRef(); const handleAddFolder = () => { const newId = String(items.length + 1); const newItem = { id: newId, label: '', editable: true }; setItems((prev) => [...prev, newItem]); requestAnimationFrame(() => { apiRef.current!.setEditedItem(newId); }); }; const handleItemLabelChange = (itemId: string, newLabel: string) => { setItems((prevItems) => prevItems.map((item) => item.id === itemId ? { ...item, label: newLabel } : item, ), ); }; return ( item.editable} onItemLabelChange={handleItemLabelChange} /> ); } ``` ## Editing lazy loaded children To store the updated item labels on your server, use the `onItemLabelChange()` callback function. Changes to the label are not automatically updated in the `dataSourceCache` and must be updated manually. ```tsx const handleItemLabelChange = (itemId: TreeViewItemId, newLabel: string) => { // update your cache here }; item?.childrenCount as number, getTreeItems: fetchData, }} {...otherProps} />; ``` See [lazy loading](/x/react-tree-view/rich-tree-view/lazy-loading/#lazy-loading-and-label-editing) for more details. --- # Source: https://mui.com/x/react-charts/examples.md --- title: React Charts productId: x-charts githubLabel: 'scope: charts' packageName: '@mui/x-charts' --- # MUI X Charts Browse through our collection of MUI X Chart demos. ## Bar Charts Vertical and horizontal bars, stacked and grouped variations. ## Line Charts Connected data points showing trends over time. ## Area Charts Filled areas below lines for cumulative data. ## Scatter Charts Plot points to show relationships between variables. ## Pie Charts Circular slices showing proportional data. ## Other Charts Gauge, sparkline, and specialized chart types. ## More demos Browse individual chart categories for more detailed examples: - **[Bar Charts](/x/react-charts/bar-demo/)** - **[Line Charts](/x/react-charts/line-demo/)** - **[Area Charts](/x/react-charts/areas-demo/)** - **[Scatter Charts](/x/react-charts/scatter-demo/)** - **[Pie Charts](/x/react-charts/pie-demo/)** - **[Other Charts](/x/react-charts/gauge/)** --- # Source: https://mui.com/x/react-tree-view/rich-tree-view/expansion.md # Source: https://mui.com/x/react-tree-view/simple-tree-view/expansion.md --- productId: x-tree-view title: Simple Tree View - Expansion components: SimpleTreeView, TreeItem packageName: '@mui/x-tree-view' githubLabel: 'scope: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ --- # Simple Tree View - Expansion Learn how to handle expanding and collapsing Tree View items. ## Controlled expansion Use the `expandedItems` prop to control expanded items. You can also use the `onExpandedItemsChange` prop to listen to changes in the expanded items and update the prop accordingly. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; export default function ControlledExpansion() { const [expandedItems, setExpandedItems] = React.useState([]); const handleExpandedItemsChange = ( event: React.SyntheticEvent | null, itemIds: string[], ) => { setExpandedItems(itemIds); }; const handleExpandClick = () => { setExpandedItems((oldExpanded) => oldExpanded.length === 0 ? [ 'grid', 'grid-community', 'grid-pro', 'grid-premium', 'pickers', 'pickers-community', 'pickers-pro', 'charts', 'charts-community', 'tree-view', 'tree-view-community', ] : [], ); }; return (
); } ``` :::info - The expansion is **controlled** when its parent manages it by providing a `expandedItems` prop. - The expansion is **uncontrolled** when it's managed by the component's own internal state. This state can be initialized using the `defaultExpandedItems` prop. Learn more about the _Controlled and uncontrolled_ pattern in the [React documentation](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components). ::: ## Track item expansion change Use the `onItemExpansionToggle` prop to trigger an action upon an item being expanded. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; import Typography from '@mui/material/Typography'; export default function TrackItemExpansionToggle() { const [action, setAction] = React.useState<{ itemId: string; isExpanded: boolean; } | null>(null); const handleItemExpansionToggle = ( event: React.SyntheticEvent | null, itemId: string, isExpanded: boolean, ) => { setAction({ itemId, isExpanded }); }; return ( {action == null ? ( No action recorded ) : ( Last action: {action.isExpanded ? 'expand' : 'collapse'} {action.itemId} )} ); } ``` ## Limit expansion to icon container You can use the `expansionTrigger` prop to decide if the expansion interaction should be triggered by clicking on the icon container instead of the whole `TreeItem` content. ```tsx import Box from '@mui/material/Box'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; export default function IconExpansionTreeView() { return ( ); } ``` ## Imperative API :::success To use the `apiRef` object, you need to initialize it using the `useSimpleTreeViewApiRef()` hook as follows: ```tsx const apiRef = useSimpleTreeViewApiRef(); return ; ``` When your component first renders, `apiRef.current` is `undefined`. After the initial render, `apiRef` holds methods to interact imperatively with `SimpleTreeView`. ::: ### Change an item expansion Use the `setItemExpansion()` API method to change the expansion of an item. ```ts apiRef.current.setItemExpansion({ // The DOM event that triggered the change event, // The id of the item to expand or collapse itemId, // If `true` the item is expanded // If `false` the item is collapsed // If not defined, the item's expansion status is toggled. shouldBeExpanded, }); ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { useSimpleTreeViewApiRef } from '@mui/x-tree-view/hooks'; export default function ApiMethodSetItemExpansion() { const apiRef = useSimpleTreeViewApiRef(); const handleExpandClick = (event: React.MouseEvent) => { apiRef.current!.setItemExpansion({ event, itemId: 'grid', shouldBeExpanded: true, }); }; const handleCollapseClick = (event: React.MouseEvent) => { apiRef.current!.setItemExpansion({ event, itemId: 'grid', shouldBeExpanded: false, }); }; return ( ); } ``` ### Check if an item is expanded Use the `isItemExpanded()` API method to check the expansion of an item. ```ts apiRef.current.isItemExpanded( // The id of the item to check itemId, ); ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import Snackbar from '@mui/material/Snackbar'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { useSimpleTreeViewApiRef } from '@mui/x-tree-view/hooks'; export default function ApiMethodIsItemExpanded() { const apiRef = useSimpleTreeViewApiRef(); const [isGridExpanded, setIsGridExpanded] = React.useState(false); const [isSnackbarOpen, setIsSnackbarOpen] = React.useState(false); const checkExpansion = () => { setIsGridExpanded(apiRef.current!.isItemExpanded('grid')); setIsSnackbarOpen(true); }; return ( setIsSnackbarOpen(false)} message={`Data Grid is ${isGridExpanded ? 'expanded' : 'collapsed'}`} anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} sx={{ position: 'absolute' }} /> ); } ``` --- # Source: https://mui.com/x/api/data-grid/export-csv.md # ExportCsv API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Data Grid - Export component](/x/react-data-grid/components/export) ## Import ```jsx import { ExportCsv } from '@mui/x-data-grid/components'; // or import { ExportCsv } from '@mui/x-data-grid'; // or import { ExportCsv } from '@mui/x-data-grid-pro'; // or import { ExportCsv } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | options | `{ allColumns?: bool, delimiter?: string, escapeFormulas?: bool, fields?: Array, fileName?: string, getRowsToExport?: func, includeColumnGroupsHeaders?: bool, includeHeaders?: bool, shouldAppendQuotes?: bool, utf8WithBom?: bool }` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/export/ExportCsv.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/export/ExportCsv.tsx) --- # Source: https://mui.com/x/api/data-grid/export-excel.md # ExportExcel API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Data Grid - Export component](/x/react-data-grid/components/export) ## Import ```jsx import { ExportExcel } from '@mui/x-data-grid-premium/components'; // or import { ExportExcel } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | options | `{ allColumns?: bool, columnsStyles?: object, escapeFormulas?: bool, exceljsPostProcess?: func, exceljsPreProcess?: func, fields?: Array, fileName?: string, getRowsToExport?: func, includeColumnGroupsHeaders?: bool, includeHeaders?: bool, valueOptionsSheetName?: string, worker?: func }` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/export/ExportExcel.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/export/ExportExcel.tsx) --- # Source: https://mui.com/x/api/data-grid/export-print.md # ExportPrint API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Data Grid - Export component](/x/react-data-grid/components/export) ## Import ```jsx import { ExportPrint } from '@mui/x-data-grid/components'; // or import { ExportPrint } from '@mui/x-data-grid'; // or import { ExportPrint } from '@mui/x-data-grid-pro'; // or import { ExportPrint } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | options | `{ allColumns?: bool, bodyClassName?: string, copyStyles?: bool, fields?: Array, fileName?: string, getRowsToExport?: func, hideFooter?: bool, hideToolbar?: bool, includeCheckboxes?: bool, pageStyle?: func \| string }` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/export/ExportPrint.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/export/ExportPrint.tsx) --- # Source: https://mui.com/x/react-data-grid/components/export.md # Source: https://mui.com/x/react-data-grid/export.md # Source: https://mui.com/x/react-charts/export.md --- title: Charts - Export productId: x-charts components: ScatterChartPro, BarChartPro, LineChartPro, Heatmap, FunnelChart, RadarChartPro, SankeyChart --- # Charts - Export [](/x/introduction/licensing/#pro-plan 'Pro plan') Let users export a chart as an image or in PDF format. Charts can be exported as images, or as PDFs using the browser's native print dialog. The exporting feature is available for the following charts: - `LineChartPro` - `BarChartPro` - `ScatterChartPro` - `PieChartPro` - `Heatmap` - `FunnelChart` - `RadarChartPro` - `SankeyChart` ## Implementing exporting ### Default toolbar To enable exporting from the chart's toolbar, pass the `showToolbar` prop to the chart component. The toolbar then renders a button that opens a menu with the export options. :::info By default, the toolbar is not displayed on exported media. You can override the `onBeforeExport` callback to change this behavior. ::: ```tsx import { LineChartPro } from '@mui/x-charts-pro/LineChartPro'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import { inflationData } from '../dataset/inflationRates'; const yAxisFormatter = new Intl.NumberFormat('en-US', { style: 'percent', minimumFractionDigits: 0, maximumFractionDigits: 0, maximumSignificantDigits: 1, }); const percentageFormatter = new Intl.NumberFormat('en-US', { style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 2, }); const seriesValueFormatter = (value: number | null) => percentageFormatter.format(value! / 100); const xAxis = [ { data: inflationData.map((p) => p.year), valueFormatter: (value: number) => `${value}`, zoom: true, }, ]; const yAxis = [ { valueFormatter: (value: number) => yAxisFormatter.format(value / 100) }, ]; const series = [ { label: 'Germany', data: inflationData.map((p) => p.rateDE), valueFormatter: seriesValueFormatter, showMark: false, }, { label: 'United Kingdom', data: inflationData.map((p) => p.rateUK), valueFormatter: seriesValueFormatter, showMark: false, }, { label: 'France', data: inflationData.map((p) => p.rateFR), valueFormatter: seriesValueFormatter, showMark: false, }, ]; const settings = { height: 300, xAxis, yAxis, series, grid: { horizontal: true }, }; export default function ExportChartToolbar() { return ( Inflation rate in France, Germany and the UK, 1960-2024 Source: World Bank ); } ``` ### Custom toolbar See [Toolbar—Composition](/x/react-charts/toolbar/#composition) for more information on how to create a custom toolbar. ## Image exporting You must install `rasterizehtml` to enable image exporting: ```bash npm npm install rasterizehtml ``` ```bash pnpm pnpm add rasterizehtml ``` ```bash yarn yarn add rasterizehtml ``` ## Export options Export behavior can be modified with [print](/x/api/charts/chart-print-export-options/) and [image export](/x/api/charts/chart-image-export-options/) options. These options can be passed to the built-in toolbar using `slotProps.toolbar`, and are then automatically displayed. You can customize their respective behaviors by passing an options object to `slotProps.toolbar`, or to the export trigger itself if you're using a custom toolbar: ```tsx // Default toolbar: // Custom trigger: ``` ### Export formats To disable the print export, set the `disableToolbarButton` property to `true`. You can customize image export formats by providing an array of objects to the `imageExportOptions` property. These objects must contain the `type` property which specifies the image format. :::info If the browser does not support a requested image format, the export defaults to PNG. ::: In the example below, you can toggle which export formats are available to the user. The name of the exported file has been customized to resemble the chart's title. ```tsx import * as React from 'react'; import { ChartProApi } from '@mui/x-charts-pro/context'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { ScatterChartPro } from '@mui/x-charts-pro/ScatterChartPro'; import { ScatterValueType } from '@mui/x-charts/models'; import { continents, countryData } from '../dataset/countryData'; import { populationGdpPerCapitaData } from './populationGdpPerCapitaData'; import ExportOptionSelector from './ExportOptionSelector'; const populationFormatter = new Intl.NumberFormat('en-US', { notation: 'compact', }); const gdpPerCapitaFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', notation: 'compact', }); const series = continents.map( (continent) => ({ label: continent, data: populationGdpPerCapitaData[continent].map((p) => ({ x: p.population, y: p.gdpPerCapita, id: countryData[p.code].country, })), valueFormatter: (value: ScatterValueType | null) => `${value!.id}: ${populationFormatter.format(value!.x)} people, ${gdpPerCapitaFormatter.format(value!.y)} GDP per capita`, highlightScope: { highlight: 'item', fade: 'global', }, }) as const, ); const fileName = 'Population_vs_GDP_Per_Capita_USD_2019'; export default function ExportChartToolbarCustomization() { const apiRef = React.useRef(undefined); const [formats, setFormats] = React.useState({ print: true, 'image/png': true, 'image/jpeg': false, 'image/webp': false, }); const imageExportOptions = Object.entries(formats) .filter(([key, value]) => key.startsWith('image/') && value) .map(([key]) => ({ type: key, fileName })); const handleChange = (event: React.ChangeEvent) => { setFormats((prev) => ({ ...prev, [event.target.name]: event.target.checked, })); }; return ( Population vs GDP Per Capita (USD), 2019 { if (context.location === 'tick' && context.defaultTickLabel === '') { return ''; } return populationFormatter.format(value); }, zoom: true, label: 'Population', }, ]} series={series} yAxis={[ { scaleType: 'log', valueFormatter: (value: number) => gdpPerCapitaFormatter.format(value), label: 'GDP per Capita', }, ]} showToolbar grid={{ horizontal: true }} slotProps={{ toolbar: { printOptions: { disableToolbarButton: !formats.print, fileName }, imageExportOptions, }, }} /> Source: World Bank `{ ${Object.entries(option) .map(([key, value]) => { if (key === 'fileName') { return 'filename'; } return `${key}: ${JSON.stringify(value)}`; }) .join(' , ')} }`, ) .join(',\n ')} ]` } }, }} />`} language="jsx" copyButtonHidden /> ); } ``` ### Add custom styles before exporting To add custom styles or modify the chart's appearance before exporting, use the `onBeforeExport` callback. When exporting, the chart is first rendered into an iframe and then exported as an image or PDF. The `onBeforeExport` callback gives you access to the iframe before the export process starts. For example, you can add the title and caption to the exported chart as shown below: ```tsx import * as React from 'react'; import { LineChartPro } from '@mui/x-charts-pro/LineChartPro'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import { defaultOnBeforeExport } from '@mui/x-charts-pro/models'; import { inflationData } from '../dataset/inflationRates'; const yAxisFormatter = new Intl.NumberFormat('en-US', { style: 'percent', minimumFractionDigits: 0, maximumFractionDigits: 0, maximumSignificantDigits: 1, }); const percentageFormatter = new Intl.NumberFormat('en-US', { style: 'percent', minimumFractionDigits: 2, maximumFractionDigits: 2, }); const seriesValueFormatter = (value: number | null) => percentageFormatter.format(value! / 100); const xAxis = [ { data: inflationData.map((p) => p.year), valueFormatter: (value: number) => `${value}`, zoom: true, }, ]; const yAxis = [ { valueFormatter: (value: number) => yAxisFormatter.format(value / 100) }, ]; const series = [ { label: 'Germany', data: inflationData.map((p) => p.rateDE), valueFormatter: seriesValueFormatter, showMark: false, }, { label: 'United Kingdom', data: inflationData.map((p) => p.rateUK), valueFormatter: seriesValueFormatter, showMark: false, }, { label: 'France', data: inflationData.map((p) => p.rateFR), valueFormatter: seriesValueFormatter, showMark: false, }, ]; const settings = { height: 300, xAxis, yAxis, series, grid: { horizontal: true }, }; function createOnBeforeExport( titleRef: React.RefObject, captionRef: React.RefObject, ) { return function onBeforeExport(iframe: HTMLIFrameElement) { // Apply default modification (removing the toolbar) defaultOnBeforeExport(iframe); const document = iframe.contentDocument!; const chart = document.body.firstElementChild!; // Create a vertical stack to hold the title, chart and caption const stack = document.createElement('div'); stack.style.display = 'flex'; stack.style.flexDirection = 'column'; stack.style.width = 'fit-content'; stack.style.margin = 'auto'; document.body.appendChild(stack); // Add title to stack const title = titleRef.current; if (title) { const titleClone = title.cloneNode(true) as HTMLSpanElement; stack.appendChild(titleClone); } // Move chart to stack (after title) document.body.removeChild(chart); stack.appendChild(chart); // Add caption to stack const caption = captionRef.current; if (caption) { const captionClone = caption.cloneNode(true) as HTMLSpanElement; captionClone.style.alignSelf = 'start'; stack.appendChild(captionClone); } }; } export default function ExportChartOnBeforeExport() { const titleRef = React.useRef(null); const captionRef = React.useRef(null); const onBeforeExport = React.useMemo( () => createOnBeforeExport(titleRef, captionRef), [], ); return ( Inflation rate in France, Germany and the UK, 1960-2024 Source: World Bank ); } ``` :::info If you don't want to manually add elements to the chart export, you can create a chart through composition and include the elements you want to export as part of the chart. See [Exporting composed charts](#exporting-composed-charts) below for more information. ::: ## Copy styles The styles of the page the chart belongs to are copied to the export iframe by default. You can disable this behavior by setting the `copyStyles` property to `false` in the export options. ```tsx ``` ## Exporting composed charts MUI X Charts may be [self-contained](/x/react-charts/quickstart/#self-contained-charts) or [composed of various subcomponents](/x/react-charts/quickstart/#composable-charts). See [Composition](/x/react-charts/composition/) for more details on implementing the latter type. `ChartsWrapper` is considered the root element of a chart for exporting purposes, and all descendants are included in the export. To use a custom wrapper instead, you must set the reference to the root element with the `useChartRootRef()` hook as shown below: ```tsx import * as React from 'react'; import { BarPlot } from '@mui/x-charts/BarChart'; import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { useChartRootRef } from '@mui/x-charts/hooks'; import Button from '@mui/material/Button'; import { Stack } from '@mui/system'; import { ChartDataProviderPro } from '@mui/x-charts-pro/ChartDataProviderPro'; import { ChartsSurface } from '@mui/x-charts/ChartsSurface'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsLegend } from '@mui/x-charts/ChartsLegend'; import { useChartProApiRef } from '@mui/x-charts-pro/hooks'; import Typography from '@mui/material/Typography'; function CustomChartWrapper({ children }: React.PropsWithChildren) { const chartRootRef = useChartRootRef(); return (
{children}
); } export default function ExportCompositionNoSnap() { const apiRef = useChartProApiRef<'composition'>(); return ( Composite Chart ); } ``` ## Content Security Policy (CSP) If your application uses a Content Security Policy (CSP), you might need to adjust it for exporting to work correctly. See [the dedicated document on CSP](/x/react-charts/content-security-policy/) for more details. ## apiRef ### Print or export as PDF The `apiRef` prop exposes the `exportAsPrint()` method that can be used to open the browser's print dialog. The print dialog lets you print the chart or save it as a PDF, as well as configure other settings. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import InputLabel from '@mui/material/InputLabel'; import FormControl from '@mui/material/FormControl'; import MenuItem from '@mui/material/MenuItem'; import { ScatterChartPro } from '@mui/x-charts-pro/ScatterChartPro'; import { ChartProApi } from '@mui/x-charts-pro/context'; import { BarChartPro } from '@mui/x-charts-pro/BarChartPro'; import { LineChartPro } from '@mui/x-charts-pro/LineChartPro'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; import { useChartProApiRef } from '@mui/x-charts-pro/hooks'; import { RadarChartPro } from '@mui/x-charts-pro/RadarChartPro'; import { PieChartPro } from '@mui/x-charts-pro/PieChartPro'; import { Unstable_SankeyChart } from '@mui/x-charts-pro/SankeyChart'; import { data } from './randomData'; import { heatmapData } from './heatmapData'; const scatterSeries = [ { label: 'Series A', data: data.map((v) => ({ x: v.x1, y: v.y1, id: v.id })), }, { label: 'Series B', data: data.map((v) => ({ x: v.x1, y: v.y2, id: v.id })), }, ]; const sankeySeries = { data: { links: [ { source: 'A', target: 'B', value: 10 }, { source: 'A', target: 'C', value: 5 }, { source: 'B', target: 'D', value: 8 }, { source: 'C', target: 'D', value: 3 }, ], }, }; const series = [ { label: 'Series A', data: data.map((p) => p.y1) }, { label: 'Series B', data: data.map((p) => p.y2) }, ]; type ChartType = | 'scatter' | 'line' | 'bar' | 'pie' | 'heatmap' | 'funnel' | 'radar' | 'sankey'; export default function PrintChart() { const [chartType, setChartType] = React.useState('scatter'); const apiRef = useChartProApiRef(); const handleChange = (event: SelectChangeEvent) => setChartType(event.target.value as ChartType); return ( Chart Type ); } function Chart({ apiRef, type, }: { apiRef: React.RefObject | undefined>; type: T; }) { switch (type) { case 'scatter': return ( | undefined>} height={300} series={scatterSeries} /> ); case 'line': return ( | undefined>} height={300} xAxis={[{ data: data.map((p) => p.x1).toSorted((a, b) => a - b) }]} series={series} /> ); case 'bar': return ( | undefined>} height={300} xAxis={[ { data: data.map((p) => Math.round(p.x1)).toSorted((a, b) => a - b) }, ]} series={series} /> ); case 'pie': return ( | undefined>} series={[ { arcLabel: 'value', data: [ { id: 0, value: 10, label: 'series A' }, { id: 1, value: 15, label: 'series B' }, { id: 2, value: 20, label: 'series C' }, ], }, ]} height={300} hideLegend={false} /> ); case 'heatmap': return ( | undefined>} xAxis={[{ data: [1, 2, 3, 4] }]} yAxis={[{ data: ['A', 'B', 'C', 'D', 'E'] }]} series={[{ data: heatmapData }]} height={300} hideLegend={false} /> ); case 'funnel': return ( | undefined>} width={400} height={300} series={[ { data: [ { label: 'Visitors', value: 200 }, { label: 'Product Page Views', value: 180 }, { label: 'Added to Cart', value: 90 }, { label: 'Purchased', value: 50 }, ], }, ]} /> ); case 'radar': return ( | undefined>} height={300} series={[{ label: 'Lisa', data: [120, 98, 86, 99, 85, 65] }]} radar={{ max: 120, metrics: [ 'Math', 'Chinese', 'English', 'Geography', 'Physics', 'History', ], }} /> ); case 'sankey': return ( | undefined>} height={300} series={sankeySeries} /> ); default: throw new Error(`Unknown chart type: ${type}`); } } ``` ### Export as image The `apiRef` prop also exposes the `exportAsImage()` method to export the chart as an image. The function accepts an options object with the `type` property which specifies the image format. The available formats are: - `image/png` and `image/jpeg` which can both be used across all [supported platforms](/material-ui/getting-started/supported-platforms/) - `image/webp` which is only supported in some browsers If the format is not supported by the browser, `exportAsImage()` falls back to `image/png`. For lossy formats such as `image/jpeg` and `image/webp`, the options object accepts the `quality` property which sets a numerical value between 0 and 1. The default is 0.9. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import FormControl from '@mui/material/FormControl'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormLabel from '@mui/material/FormLabel'; import Radio from '@mui/material/Radio'; import RadioGroup from '@mui/material/RadioGroup'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import { LineChartPro } from '@mui/x-charts-pro/LineChartPro'; import { useChartProApiRef } from '@mui/x-charts-pro/hooks'; import { ChartProApi } from '@mui/x-charts-pro/context'; function ExportParamsSelector({ apiRef, }: { apiRef: React.RefObject; }) { const [type, setType] = React.useState('image/png'); const [rawQuality, setRawQuality] = React.useState('0.9'); const quality = Math.max(0, Math.min(1, Number.parseFloat(rawQuality))); return ( Image Format setType(event.target.value as 'image/png' | 'image/jpeg' | 'image/webp') } > } label="image/png" /> } label="image/jpeg" /> } label="image/webp" /> setRawQuality(event.target.value)} disabled={type === 'image/png'} helperText="Only applicable to lossy formats." />
); } export default function ExportChartAsImage() { const apiRef = useChartProApiRef<'line'>(); return ( ); } ``` --- # Source: https://mui.com/x/react-data-grid/features.md # Data Grid feature showcase Explore all of the available features in each of the Data Grid packages. The demo below uses the Data Grid to list all available features in the Community, Pro, and Premium packages. Check it out to help determine which package is best for you, and see features like filtering, sorting, and grouping in action. ```tsx import * as React from 'react'; import { DataGridPremium, DataGridPremiumProps, gridClasses, GridColDef, GridEventListener, GridRenderCellParams, GridRowParams, Toolbar, useGridApiRef, QuickFilter, QuickFilterControl, QuickFilterClear, } from '@mui/x-data-grid-premium'; import Link from '@mui/material/Link'; import Chip from '@mui/material/Chip'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import ArrowUp from '@mui/icons-material/KeyboardArrowUp'; import ArrowDown from '@mui/icons-material/KeyboardArrowDown'; import KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded'; import { useTheme, alpha, styled } from '@mui/material/styles'; import { yellow, blue, green } from '@mui/material/colors'; import TextField from '@mui/material/TextField'; import InputAdornment from '@mui/material/InputAdornment'; import SearchIcon from '@mui/icons-material/Search'; import CancelIcon from '@mui/icons-material/Cancel'; import AggregationRowGrouping from '../aggregation/AggregationRowGrouping'; import BasicColumnPinning from '../column-pinning/BasicColumnPinning'; import ColumnSelectorGrid from '../column-visibility/ColumnSelectorGrid'; import ExcelExport from '../export/ExcelExport'; import QuickFilteringGrid from '../filtering/QuickFilteringGrid'; import BasicDetailPanels from '../master-detail/BasicDetailPanels'; import RowGroupingInitialState from '../row-grouping/RowGroupingInitialState'; import RowOrderingGrid from '../row-ordering/RowOrderingGrid'; import RowPinningWithPagination from '../row-pinning/RowPinningWithPagination'; import RestoreStateInitialState from '../state/RestoreStateInitialState'; import TreeDataFullExample from '../tree-data/TreeDataFullExample'; import ColumnVirtualizationGrid from '../virtualization/ColumnVirtualizationGrid'; import FullFeaturedDemo from './FullFeaturedDemo'; import LazyLoadingGrid from '../row-updates/LazyLoadingGrid'; import BasicGroupingDemo from '../column-groups/BasicGroupingDemo'; import EditingWithDatePickers from '../custom-columns/EditingWithDatePickers'; import CellSelectionGrid from '../cell-selection/CellSelectionRangeStyling'; import HeaderFilteringDataGridPro from '../filtering/HeaderFilteringDataGridPro'; import ClipboardPaste from '../clipboard/ClipboardPaste'; import GridPivotingInitialState from '../pivoting/GridPivotingInitialState'; import GridChartsIntegrationPivoting from '../charts-integration/GridChartsIntegrationPivoting'; import AssistantWithExamples from '../ai-assistant/AssistantWithExamples'; type Row = { id: number; name: string; description: string; plan: string; detailPage: string; demo: React.JSX.Element; newBadge?: boolean; linkToCode?: string; }; export const featuresSet: Row[] = [ { id: 1, name: 'Master-detail row panels', description: 'Display parent rows with collapsible child panels (as seen in this demo).', plan: 'Pro', detailPage: '/master-detail/', demo: , linkToCode: '/master-detail/#system-BasicDetailPanels.tsx', }, { id: 2, name: 'Inline editing', description: 'Edit data inside cells by double-clicking or pressing Enter.', plan: 'Community', detailPage: '/editing/', demo: , linkToCode: '/recipes-editing/#system-EditingWithDatePickers.tsx', }, { id: 3, name: 'Column grouping', description: 'Group columns in a multi-level hierarchy.', plan: 'Community', detailPage: '/column-groups/', demo: , linkToCode: '/column-groups/#system-BasicGroupingDemo.tsx', }, { id: 4, name: 'Lazy loading', description: 'Paginate rows and only fetch what you need.', plan: 'Pro', detailPage: '/row-updates/#lazy-loading', demo: , linkToCode: '/row-updates/#system-LazyLoadingGrid.tsx', }, { id: 5, name: 'Save and restore state', description: 'Save and restore internal state and configurations like active filters and sorting.', plan: 'Community', detailPage: '/state/#save-and-restore-the-state', demo: , linkToCode: '/state/#system-RestoreStateInitialState.tsx', }, { id: 6, name: 'Row grouping', description: 'Group rows with repeating column values.', plan: 'Premium', detailPage: '/row-grouping/', demo: , linkToCode: '/row-grouping/#system-RowGroupingInitialState.tsx', }, { id: 7, name: 'Excel export', description: 'Export rows in various file formats such as CSV, PDF or Excel.', plan: 'Premium', detailPage: '/export/#excel-export', demo: , linkToCode: '/export/#system-ExcelExport.tsx', }, { id: 8, name: 'Quick filter', description: 'Use a single text input to filter multiple fields.', plan: 'Community', detailPage: '/filtering/quick-filter/', demo: , linkToCode: '/filtering/quick-filter/#system-QuickFilteringGrid.tsx', }, { id: 9, name: 'Row reordering', description: 'Drag and drop to reorder data.', plan: 'Pro', detailPage: '/row-ordering/', demo: , linkToCode: '/row-ordering/#system-RowOrderingGrid.tsx', }, { id: 10, name: 'Column Pinning', description: 'Pin columns to the left or right.', plan: 'Pro', detailPage: '/column-pinning/', demo: , linkToCode: '/column-pinning/#system-BasicColumnPinning.tsx', }, { id: 11, name: 'Row pinning', description: 'Pin rows to the top or bottom of the Grid.', plan: 'Pro', detailPage: '/row-pinning/', demo: , linkToCode: '/row-pinning/#system-RowPinningWithPagination.tsx', }, { id: 12, name: 'Aggregation and Summary rows', description: 'Set summary footer rows or inline summaries with row grouping.', plan: 'Premium', detailPage: '/aggregation/', demo: , linkToCode: '/aggregation/#system-AggregationRowGrouping.tsx', }, { id: 13, name: 'Column visibility', description: 'Display different columns for different use cases.', plan: 'Community', detailPage: '/column-visibility/', demo: , linkToCode: '/column-visibility/#system-ColumnSelectorGrid.tsx', }, { id: 14, name: 'Column virtualization', description: 'High-performance support for thousands of columns.', plan: 'Community', detailPage: '/virtualization/#column-virtualization', demo: , linkToCode: '/virtualization/#system-ColumnVirtualizationGrid.tsx', }, { id: 15, name: 'Row virtualization', description: 'High-performance support for large volumes of data.', plan: 'Pro', detailPage: '/virtualization/#row-virtualization', demo: , }, { id: 16, name: 'Tree data', description: 'Support rows with a parent/child relationship.', plan: 'Pro', detailPage: '/tree-data/', demo: , linkToCode: '/tree-data/#system-TreeDataFullExample.tsx', }, { id: 17, name: 'Cell selection', description: 'Select one or more cells by dragging the mouse or using the Shift key.', plan: 'Premium', detailPage: '/cell-selection/', demo: , linkToCode: '/cell-selection/#system-CellSelectionGrid.tsx', }, { id: 18, name: 'Clipboard paste', description: 'Copy and paste selected cells and rows using standard keyboard shortcuts.', plan: 'Premium', detailPage: '/clipboard/#clipboard-paste', demo: , linkToCode: '/clipboard/#system-ClipboardPaste.tsx', }, { id: 19, name: 'Header filters', description: 'Quickly accessible and customizable header filters to filter the data.', plan: 'Pro', detailPage: '/filtering/#header-filters', demo: , linkToCode: '/filtering/header-filters/#system-HeaderFilteringDataGridPro.tsx', }, { id: 20, name: 'Pivoting', description: 'Rearrange rows and columns to view data from multiple perspectives.', plan: 'Premium', detailPage: '/pivoting/', demo: , linkToCode: '/pivoting/#system-GridPivotingInitialState.tsx', }, { id: 21, name: 'Charts integration', description: 'Visualize data with charts.', plan: 'Premium', detailPage: '/charts-integration/', demo: , linkToCode: '/charts-integration/#system-GridChartsIntegrationPivoting.tsx', }, { id: 22, name: 'AI Assistant', description: 'Translate natural language into a set of grid state updates.', plan: 'Premium', detailPage: '/ai-assistant/', demo: , linkToCode: '/ai-assistant/#system-AssistantWithExamples.tsx', }, ]; function getChipProperties(plan: string) { switch (plan) { case 'Premium': return { avatarLink: '/static/x/premium.svg' }; case 'Pro': return { avatarLink: '/static/x/pro.svg' }; default: return { avatarLink: '/static/x/community.svg' }; } } const chipColor = { light: { Premium: { background: yellow[50], border: alpha(yellow[900], 0.4) }, Pro: { background: blue[50], border: alpha(blue[900], 0.2) }, Community: { background: green[50], border: alpha(green[900], 0.2) }, }, dark: { Premium: { background: alpha(yellow[900], 0.4), border: alpha(yellow[300], 0.4), }, Pro: { background: alpha(blue[600], 0.4), border: alpha(blue[300], 0.4) }, Community: { background: alpha(green[600], 0.4), border: alpha(green[300], 0.4), }, }, } as const; function PlanTag(props: { plan: 'Premium' | 'Pro' | 'Community' }) { const theme = useTheme(); const chipProperties = getChipProperties(props.plan); const avatar = !chipProperties.avatarLink ? undefined : ( ); return ( ); } const StyledToolbar = styled(Toolbar)(({ theme }) => ({ padding: theme.spacing(1.5), minHeight: 'auto', })); const StyledQuickFilter = styled(QuickFilter)({ margin: 0, width: '100%', }); function CustomToolbar() { return ( ( ), endAdornment: other.value ? ( ) : null, }, }} /> )} /> ); } function RowDemo(props: { row: Row }) { const { row } = props; const theme = useTheme(); return (
{row.demo}
{row.linkToCode ? ( svg': { transition: '0.2s' }, '&:hover > svg': { transform: 'translateX(2px)' }, }} > View the demo source ) : null}
); } function CustomSizeAggregationFooter(props: { value: string | undefined }) { return ( Total: {props.value} ); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Feature name', maxWidth: 172, flex: 0.2, minWidth: 100, groupable: false, display: 'flex', renderCell: (params) => { if (params.aggregation) { return ; } if (!params.value) { return ''; } return ( {params.value} {params.row.newBadge && ( ({ ml: 1, p: 0.2, height: 'auto', fontSize: theme.typography.pxToRem(10), fontWeight: 'bold', textTransform: 'uppercase', letterSpacing: '.04rem', '& .MuiChip-label': { px: '4px', }, })} /> )} ); }, }, { field: 'description', headerName: 'Description', groupable: false, flex: 0.5, minWidth: 120, }, { field: 'plan', headerName: 'Plan', maxWidth: 130, flex: 0.3, type: 'singleSelect', valueOptions: ['Premium', 'Pro', 'Community'], display: 'flex', renderCell: (params: GridRenderCellParams) => { if (params.aggregation) { return ; } if (!params.value) { return ''; } return ; }, sortComparator: (p1, p2) => { function getSortingValue(plan: string) { switch (plan) { case 'Pro': return 1; case 'Premium': return 2; default: return 0; } } const p1Value = getSortingValue(p1); const p2Value = getSortingValue(p2); return p1Value - p2Value; }, }, ]; const mainDataGridCellClassName = 'main-data-grid-cell'; const getCellClassName = () => mainDataGridCellClassName; export default function PopularFeaturesDemo() { const apiRef = useGridApiRef(); const getDetailPanelContent = React.useCallback< NonNullable >((params: GridRowParams) => { return ; }, []); const getRowHeight = React.useCallback< NonNullable >(() => 'auto', []); const getDetailPanelHeight = React.useCallback< NonNullable >(() => 'auto', []); const onRowClick = React.useCallback>( (params) => { const rowNode = apiRef.current?.getRowNode(params.id); if (rowNode && rowNode.type === 'group') { apiRef.current?.setRowChildrenExpansion( params.id, !rowNode.childrenExpanded, ); } else { apiRef.current?.toggleDetailPanel(params.id); } }, [apiRef], ); const memoizedGroupingDef = React.useMemo(() => { return { headerName: 'Grouped by Plan', width: 200, }; }, []); return ( ); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-date-pickers/fields.md --- productId: x-date-pickers title: React Date Fields components components: DateField, TimeField, DateTimeField, MultiInputDateRangeField, SingleInputDateRangeField, MultiInputTimeRangeField, SingleInputTimeRangeField, MultiInputDateTimeRangeField, SingleInputDateTimeRangeField githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Fields component The field components let the user input date and time values with a keyboard and refined keyboard navigation. ## Introduction The fields are React components that let you enter a date or time with the keyboard, without using any popover or modal UI. They provide refined navigation through arrow keys and support advanced behaviors like localization and validation. ### Fields to edit a single element ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; import { TimeField } from '@mui/x-date-pickers/TimeField'; import { DateTimeField } from '@mui/x-date-pickers/DateTimeField'; const defaultValue = dayjs('2022-04-17T15:30'); export default function SingleDateFieldExamples() { return ( ); } ``` ### Fields to edit a range [](/x/introduction/licensing/#pro-plan 'Pro plan') All fields to edit a range are available in a single input version and in a multi-input version. ```tsx import dayjs from 'dayjs'; import { DemoContainer, DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; import { SingleInputTimeRangeField } from '@mui/x-date-pickers-pro/SingleInputTimeRangeField'; import { MultiInputTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField'; import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField'; import { SingleInputDateTimeRangeField } from '@mui/x-date-pickers-pro/SingleInputDateTimeRangeField'; const date1 = dayjs('2022-04-17T15:30'); const date2 = dayjs('2022-04-21T18:30'); export default function DateRangeFieldExamples() { return ( ); } ``` ## Advanced ### What is a section? In the field components, the date is divided into several sections, each one responsible for editing a date token. For example, if the format passed to the field is `MM/DD/YYYY`, the field will create 3 sections: - A `month` section for the token `MM` - A `day` section for the token `DD` - A `year` section for the token `YYYY` Those sections are independent, pressing ArrowUp while focusing the `day` section will add one day to the date, but it will never change the month or the year. ### Control the selected sections Use the `selectedSections` and `onSelectedSectionsChange` props to control which sections are currently being selected. This prop accepts the following formats: 1. If a number is provided, the section at this index will be selected. 2. If `"all"` is provided, all the sections will be selected. 3. If an object with `startIndex` and `endIndex` fields is provided, the sections between those two indexes will be selected. 4. If a string of type `FieldSectionType` is provided, the first section with that name will be selected. 5. If `null` is provided, no section will be selected. :::warning You need to make sure the input is focused before imperatively updating the selected sections. ::: ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { FieldSectionType, FieldSelectedSections } from '@mui/x-date-pickers/models'; import { DateField } from '@mui/x-date-pickers/DateField'; export default function ControlledSelectedSections() { const [selectedSections, setSelectedSections] = React.useState(null); const inputRef = React.useRef(null); const setSelectedSectionType = (selectedSectionType: FieldSectionType) => { inputRef.current?.focus(); setSelectedSections(selectedSectionType); }; return ( ); } ``` #### Usage with single input range fields [](/x/introduction/licensing/#pro-plan 'Pro plan') For single input range fields, you won't be able to use the section name to select a single section because each section is present both in the start and in the end date. Instead, you can pass the index of the section using the `unstableFieldRef` prop to access the full list of sections: :::warning The `unstableFieldRef` is not stable yet. More specifically, the shape of the `section` object might be modified in the near future. Please only use it if needed. ::: ```tsx import * as React from 'react'; import { Dayjs } from 'dayjs'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { FieldSectionType, FieldSelectedSections, FieldRef, } from '@mui/x-date-pickers/models'; import { DateRange, RangePosition } from '@mui/x-date-pickers-pro/models'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; export default function ControlledSelectedSectionsSingleInputRangeField() { const [selectedSections, setSelectedSections] = React.useState(null); const inputRef = React.useRef(null); const fieldRef = React.useRef>>(null); const setSelectedSectionType = ( selectedSectionType: FieldSectionType, position: RangePosition, ) => { if (!fieldRef.current) { return; } inputRef.current?.focus(); const sections = fieldRef.current.getSections().map((el) => el.type); setSelectedSections( position === 'start' ? sections.indexOf(selectedSectionType) : sections.lastIndexOf(selectedSectionType), ); }; const renderDateHeader = (position: RangePosition) => ( {position} {(['month', 'day', 'year'] as const).map((sectionName) => ( ))} ); return ( {renderDateHeader('start')} {renderDateHeader('end')} ); } ``` #### Usage with multi-input range fields [](/x/introduction/licensing/#pro-plan 'Pro plan') For multi-input range fields, you just have to make sure that the right input is focused before updating the selected section(s). Otherwise, the section(s) might be selected on the wrong input. ```tsx import * as React from 'react'; import Typography from '@mui/material/Typography'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { FieldSectionType, FieldSelectedSections } from '@mui/x-date-pickers/models'; import { RangePosition } from '@mui/x-date-pickers-pro/models'; import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; export default function ControlledSelectedSectionsMultiInputRangeField() { const [selectedSections, setSelectedSections] = React.useState(null); const startInputRef = React.useRef(null); const endInputRef = React.useRef(null); const setSelectedSectionType = ( selectedSectionType: FieldSectionType, position: RangePosition, ) => { if (position === 'start') { startInputRef.current?.focus(); } else { endInputRef.current?.focus(); } setSelectedSections(selectedSectionType); }; const renderDateHeader = (position: RangePosition) => ( {position} {(['month', 'day', 'year'] as const).map((sectionName) => ( ))} ); return ( {renderDateHeader('start')} {renderDateHeader('end')} ({ inputRef: ownerState.position === 'start' ? startInputRef : endInputRef, }), }} selectedSections={selectedSections} onSelectedSectionsChange={setSelectedSections} /> ); } ``` ### Clearable behavior You can use the `clearable` prop to enable the clearing behavior on a field. You can also add an event handler using the `onClear` callback prop. :::info For **multi-input** range fields the clearable behavior is not supported yet. ::: ```tsx import * as React from 'react'; import { Dayjs } from 'dayjs'; import { DemoItem } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; import Box from '@mui/material/Box'; import Alert from '@mui/material/Alert'; export default function ClearableBehavior() { const [value, setValue] = React.useState(null); const [cleared, setCleared] = React.useState(false); React.useEffect(() => { if (cleared) { const timeout = setTimeout(() => { setCleared(false); }, 1500); return () => clearTimeout(timeout); } return () => {}; }, [cleared]); return ( setValue(newValue)} onClear={() => setCleared(true)} clearable /> {cleared && !value && ( Field cleared! )} ); } ``` You can also customize the icon you want to be displayed inside the clear `IconButton`. ```tsx import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import BackspaceIcon from '@mui/icons-material/Backspace'; import HighlightOffIcon from '@mui/icons-material/HighlightOff'; export default function CustomizeClearIcon() { return ( ); } ``` --- # Source: https://mui.com/x/api/data-grid/filter-panel-trigger.md # FilterPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Data Grid - Filter Panel component 🚧](/x/react-data-grid/components/filter-panel) ## Import ```jsx import { FilterPanelTrigger } from '@mui/x-data-grid/components'; // or import { FilterPanelTrigger } from '@mui/x-data-grid'; // or import { FilterPanelTrigger } from '@mui/x-data-grid-pro'; // or import { FilterPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/filterPanel/FilterPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/filterPanel/FilterPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/components/filter-panel.md --- productId: x-data-grid components: FilterPanelTrigger packageName: '@mui/x-data-grid' githubLabel: 'scope: data grid' --- # Data Grid - Filter Panel component 🚧 Customize the Data Grid's filter panel. :::warning This component is incomplete. Currently, the Filter Panel Trigger is the only part of the Filter Panel component available. Future versions of the Filter Panel component will make it possible to compose each of its parts to create a custom filter panel. In the meantime, it's still possible to deeply customize the panel's subcomponents using custom slots. See [Filter customization—Custom filter panel](/x/react-data-grid/filtering/customization/#custom-filter-panel) for more details. ::: The [filter panel](/x/react-data-grid/filtering/) is enabled by default. Users can trigger the filter panel via the column menu, as well as from the toolbar when `showToolbar` is passed to the `` component. You can use the Filter Panel Trigger and [Toolbar](/x/react-data-grid/components/toolbar/) components when you need to customize the filter panel trigger, or when implementing a custom toolbar. ## Basic usage The demo below shows how to add a filter panel trigger to a custom toolbar. ```tsx import { DataGrid, Toolbar, ToolbarButton, FilterPanelTrigger, } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import Tooltip from '@mui/material/Tooltip'; import FilterListIcon from '@mui/icons-material/FilterList'; function CustomToolbar() { return ( }> ); } export default function GridFilterPanelTrigger() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 10, }); return (
); } ``` ## Anatomy ```tsx import { FilterPanelTrigger } from '@mui/x-data-grid'; ; ``` ### Filter Panel Trigger `` is a button that opens and closes the filter panel. It renders the `baseButton` slot. ## Custom elements Use the `render` prop to replace default elements. See [Components usage—Customization](/x/react-data-grid/components/usage/#customization) for more details, and [Toolbar—Custom elements demo](/x/react-data-grid/components/toolbar/#custom-elements) for an example of a custom Filter Panel Trigger. ## Accessibility ### ARIA You must apply a text label or an `aria-label` attribute to the ``. # FilterPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Data Grid - Filter Panel component 🚧](/x/react-data-grid/components/filter-panel) ## Import ```jsx import { FilterPanelTrigger } from '@mui/x-data-grid/components'; // or import { FilterPanelTrigger } from '@mui/x-data-grid'; // or import { FilterPanelTrigger } from '@mui/x-data-grid-pro'; // or import { FilterPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/filterPanel/FilterPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/filterPanel/FilterPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/filtering-recipes.md --- title: Data Grid - Filtering customization recipes --- # Data Grid - Filtering customization recipes Advanced filtering customization recipes. ## Persisting filters in local storage You can persist the filters in the local storage to keep the filters applied after the page is reloaded. In the demo below, the [`React.useSyncExternalStore` hook](https://react.dev/reference/react/useSyncExternalStore) is used to synchronize the filters with the local storage. ```tsx import * as React from 'react'; import { DataGrid, DataGridProps, GridFilterModel } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; const createFilterModelStore = () => { let listeners: Array<() => void> = []; const lsKey = 'gridFilterModel'; const emptyModel = 'null'; return { subscribe: (callback: () => void) => { listeners.push(callback); return () => { listeners = listeners.filter((listener) => listener !== callback); }; }, getSnapshot: () => { try { return localStorage.getItem(lsKey) || emptyModel; } catch (error) { return emptyModel; } }, getServerSnapshot: () => { return emptyModel; }, update: (filterModel: GridFilterModel) => { localStorage.setItem(lsKey, JSON.stringify(filterModel)); listeners.forEach((listener) => listener()); }, }; }; const usePersistedFilterModel = () => { const [filterModelStore] = React.useState(createFilterModelStore); const filterModelString = React.useSyncExternalStore( filterModelStore.subscribe, filterModelStore.getSnapshot, filterModelStore.getServerSnapshot, ); const filterModel = React.useMemo(() => { try { return (JSON.parse(filterModelString) as GridFilterModel) || undefined; } catch (error) { return undefined; } }, [filterModelString]); return React.useMemo( () => [filterModel, filterModelStore.update] as const, [filterModel, filterModelStore.update], ); }; export default function FilteringLocalStorage() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); const [filterModel, setFilterModel] = usePersistedFilterModel(); const onFilterModelChange = React.useCallback< NonNullable >( (newFilterModel) => { setFilterModel(newFilterModel); }, [setFilterModel], ); return (
); } ``` ## Save and manage filters from the panel Create a custom filter panel by wrapping the `GridFilterPanel` component and pass it to the `slots.filterPanel` prop. In the demo below, the custom component lets users to save and manage filters, which are stored in local storage. For a more scalable approach, you can replace local storage with a server-side database. ```tsx import * as React from 'react'; import { DataGridPro, GridFilterModel, gridFilterModelSelector, GridFilterPanel, useGridApiContext, useGridSelector, } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import TextField from '@mui/material/TextField'; import IconButton from '@mui/material/IconButton'; import Dialog from '@mui/material/Dialog'; import DialogTitle from '@mui/material/DialogTitle'; import DialogContent from '@mui/material/DialogContent'; import DialogActions from '@mui/material/DialogActions'; import List from '@mui/material/List'; import ListItem from '@mui/material/ListItem'; import ListItemButton from '@mui/material/ListItemButton'; import ListItemText from '@mui/material/ListItemText'; import Typography from '@mui/material/Typography'; import Alert from '@mui/material/Alert'; import Stack from '@mui/material/Stack'; import Tooltip from '@mui/material/Tooltip'; import Divider from '@mui/material/Divider'; import SaveIcon from '@mui/icons-material/Save'; import DeleteIcon from '@mui/icons-material/Delete'; import AddIcon from '@mui/icons-material/Add'; interface FilterPreset { id: string; name: string; filterModel: GridFilterModel; createdAt: string; } interface FilterPresetStore { presets: FilterPreset[]; activePresetId: string | null; } const STORAGE_KEY = 'dataGridFilterPresets'; const EMPTY_STORE: FilterPresetStore = { presets: [], activePresetId: null }; const createPresetsStore = () => { let listeners: Array<() => void> = []; return { subscribe: (callback: () => void) => { listeners.push(callback); return () => { listeners = listeners.filter((listener) => listener !== callback); }; }, getSnapshot: () => { try { const saved = localStorage.getItem(STORAGE_KEY); return saved || JSON.stringify(EMPTY_STORE); } catch { return JSON.stringify(EMPTY_STORE); } }, getServerSnapshot: () => { return JSON.stringify(EMPTY_STORE); }, update: (store: FilterPresetStore) => { try { localStorage.setItem(STORAGE_KEY, JSON.stringify(store)); } catch { // Silently fail if localStorage is not available } listeners.forEach((listener) => listener()); }, }; }; const usePersistedPresets = () => { const [presetsStore] = React.useState(createPresetsStore); const storeString = React.useSyncExternalStore( presetsStore.subscribe, presetsStore.getSnapshot, presetsStore.getServerSnapshot, ); const store = React.useMemo(() => { try { return JSON.parse(storeString) as FilterPresetStore; } catch { return EMPTY_STORE; } }, [storeString]); return React.useMemo( () => [store, presetsStore.update] as const, [store, presetsStore.update], ); }; type GridFilterPanelProps = React.ComponentProps; function CustomFilterPanel(props: GridFilterPanelProps) { const apiRef = useGridApiContext(); const [store, setStore] = usePersistedPresets(); const [createFilterDialogOpen, setCreateFilterDialogOpen] = React.useState(false); const [createFilterName, setCreateFilterName] = React.useState(''); const filterModel = useGridSelector(apiRef, gridFilterModelSelector); const hasActiveFilters = filterModel.items.length > 0; const handleSavePreset = () => { setStore({ ...store, presets: store.presets.map((p) => p.id === store.activePresetId ? { ...p, filterModel, } : p, ), }); }; const handleCreateFilter = () => { if (!createFilterName.trim()) { return; } const newPreset: FilterPreset = { id: `preset_${Date.now()}`, name: createFilterName.trim(), filterModel, createdAt: new Date().toISOString(), }; setStore({ ...store, presets: [...store.presets, newPreset], activePresetId: newPreset.id, }); setCreateFilterDialogOpen(false); setCreateFilterName(''); }; const handleLoadPreset = (presetId: string) => { const preset = store.presets.find((p) => p.id === presetId); if (preset) { apiRef.current.setFilterModel(preset.filterModel); setStore({ ...store, activePresetId: presetId, }); } }; const handleDeletePreset = (presetId: string) => { setStore({ ...store, presets: store.presets.filter((p) => p.id !== presetId), activePresetId: store.activePresetId === presetId ? null : store.activePresetId, }); }; return ( Saved Filter Presets setCreateFilterDialogOpen(true)} size="small" color="primary" > {store.presets.length === 0 ? ( ({ flex: 1, border: '1px solid', borderColor: 'divider', borderRadius: 1, bgcolor: 'grey.100', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', p: 2, color: 'text.secondary', ...theme.applyStyles('dark', { bgcolor: 'grey.900', }), })} > No saved filters yet ) : ( {store.presets.map((preset) => ( { event.stopPropagation(); handleDeletePreset(preset.id); }} > } > handleLoadPreset(preset.id)} sx={{ '&.Mui-selected': { bgcolor: 'action.selected', position: 'relative', '&::after': { content: '""', position: 'absolute', right: 0, top: '50%', transform: 'translateY(-50%)', width: 3, height: '60%', bgcolor: 'primary.main', borderRadius: '3px 0 0 3px', }, }, }} > {preset.filterModel.items.length} filter {preset.filterModel.items.length > 1 ? 's' : ''} } /> ))} )} setCreateFilterDialogOpen(false)} maxWidth="sm" > Create new filter setCreateFilterName(event.target.value)} fullWidth required /> {hasActiveFilters ? `This will save the current ${filterModel.items.length} active filter${filterModel.items.length !== 1 ? 's' : ''} as a new preset.` : 'This will create an empty filter preset that you can configure later.'} ); } export default function FilterPresetsPanel() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 10, }); return ( ); } ``` ## Quick filter outside of the grid The [Quick Filter](/x/react-data-grid/filtering/quick-filter/) component is typically used in the Data Grid's Toolbar component slot. Some use cases may call for placing components like the Quick Filter outside of the Grid. This requires certain considerations due to the Grid's context structure. The following example shows how to accomplish this: ```tsx import * as React from 'react'; import Portal from '@mui/material/Portal'; import Box from '@mui/material/Box'; import Grid from '@mui/material/Grid'; import { DataGrid, GridPortalWrapper, QuickFilter, QuickFilterClear, QuickFilterControl, ToolbarButton, ColumnsPanelTrigger, FilterPanelTrigger, Toolbar, } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import TextField from '@mui/material/TextField'; import InputAdornment from '@mui/material/InputAdornment'; import SearchIcon from '@mui/icons-material/Search'; import CancelIcon from '@mui/icons-material/Cancel'; import Tooltip from '@mui/material/Tooltip'; import Badge from '@mui/material/Badge'; import FilterListIcon from '@mui/icons-material/FilterList'; import ViewColumnIcon from '@mui/icons-material/ViewColumn'; function MyCustomToolbar() { return ( document.getElementById('filter-panel')!}> ( ), endAdornment: other.value ? ( ) : null, }, }} /> )} /> }> ( )} /> ); } const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function QuickFilterOutsideOfGrid() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 1000, }); // Otherwise filter will be applied on fields such as the hidden column id const columns = React.useMemo( () => data.columns.filter((column) => VISIBLE_FIELDS.includes(column.field)), [data.columns], ); return ( ); } ``` ## Calculating filtered rows in advance The [Grid API](/x/react-data-grid/api-object/#how-to-use-the-api-object) provides the [`getFilterState`](/x/api/data-grid/grid-api/#grid-api-prop-getFilterState) method, which lets you display the row count for predefined filters upfront without applying filters to the Data Grid: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { DataGridPro, useGridApiRef, GridFilterModel } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; const predefinedFilters: { label: string; filterModel: GridFilterModel }[] = [ { label: 'All', filterModel: { items: [] }, }, { label: 'Filled', filterModel: { items: [{ field: 'status', operator: 'is', value: 'Filled' }] }, }, { label: 'Open', filterModel: { items: [{ field: 'status', operator: 'is', value: 'Open' }] }, }, { label: 'Rejected', filterModel: { items: [{ field: 'status', operator: 'is', value: 'Rejected' }] }, }, { label: 'Partially Filled', filterModel: { items: [{ field: 'status', operator: 'is', value: 'PartiallyFilled' }], }, }, ]; export default function FilteredRowCount() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 1000, maxColumns: 10, }); const apiRef = useGridApiRef(); const [predefinedFiltersRowCount, setPredefinedFiltersRowCount] = React.useState< number[] >([]); const getFilteredRowsCount = React.useCallback( (filterModel: GridFilterModel) => { const rowIds = apiRef.current?.getAllRowIds(); const filterState = apiRef.current?.getFilterState(filterModel); if (!rowIds || !filterState) { return 0; } const { filteredRowsLookup } = filterState; return rowIds.filter((rowId) => filteredRowsLookup[rowId] !== false).length; }, [apiRef], ); React.useEffect(() => { // Calculate the row count for predefined filters if (data.rows.length === 0) { return; } setPredefinedFiltersRowCount( predefinedFilters.map(({ filterModel }) => getFilteredRowsCount(filterModel)), ); }, [apiRef, data.rows, getFilteredRowsCount]); return (
{predefinedFilters.map(({ label, filterModel }, index) => { const count = predefinedFiltersRowCount[index]; return ( ); })}
); } ``` --- # Source: https://mui.com/x/react-data-grid/filtering.md # Data Grid - Filtering Easily filter your rows based on one or several criteria. 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._ ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function BasicExampleDataGrid() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); return (
); } ``` ## 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` ([](/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` [](/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.Or` by default. ### Initialize the filters To initialize the filters without controlling them, provide the model to the `initialState` prop. ```jsx ', value: '2.5' }], }, }, }} /> ``` ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function InitialFilters() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); return (
', value: '2.5', }, ], }, }, }} />
); } ``` ### 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 ', value: '2.5' }], }} /> ``` ```tsx import * as React from 'react'; import { DataGrid, GridFilterModel } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function ControlledFilters() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); const [filterModel, setFilterModel] = React.useState({ items: [ { field: 'rating', operator: '>', value: '2.5', }, ], }); return (
setFilterModel(newFilterModel)} />
); } ``` ## Disable the filters ### For all columns Filters are enabled by default, but you can easily disable this feature by setting the `disableColumnFilter` prop. ```jsx ``` ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function DisableFilteringGridAllColumns() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); return (
); } ``` ### 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 ``` ```tsx import * as React from 'react'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function DisableFilteringGridSomeColumns() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); const columns = React.useMemo( () => data.columns.map((col) => col.field === 'rating' ? { ...col, filterable: false } : col, ), [data.columns], ); return (
); } ``` ### 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, ] ``` ```tsx import * as React from 'react'; import { DataGrid, GridFilterModel } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function ReadOnlyFilters() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); const columns = React.useMemo( () => data.columns.map((column) => ({ ...column, filterable: column.field !== 'name', })), [data.columns], ); const [filterModel, setFilterModel] = React.useState({ items: [ { field: 'name', operator: 'contains', value: 'a', }, ], }); return (
setFilterModel(newFilterModel)} />
); } ``` ## 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 ``` :::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. ::: ```jsx import ApiDocs from 'docsx/src/modules/components/ApiDocs'; import api from 'docsx/pages/x/api/data-grid/grid-filter-api.json'; export default function FilterApiNoSnap() { return ; } ``` ## 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/) --- # Source: https://mui.com/x/react-tree-view/rich-tree-view/focus.md # Source: https://mui.com/x/react-tree-view/simple-tree-view/focus.md --- productId: x-tree-view title: Simple Tree View - Focus components: SimpleTreeView, TreeItem packageName: '@mui/x-tree-view' githubLabel: 'scope: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ --- # Simple Tree View - Focus Learn how to focus Tree View items. ## Imperative API To use the `apiRef` object, you need to initialize it using the `useSimpleTreeViewApiRef()` hook as follows: ```tsx const apiRef = useSimpleTreeViewApiRef(); return ; ``` When your component first renders, `apiRef.current` is `undefined`. After the initial render, `apiRef` holds methods to interact imperatively with the Tree View. ### Focus a specific item Use the `focusItem()` API method to focus a specific item. ```ts apiRef.current.focusItem( // The DOM event that triggers the change event, // The id of the item to focus itemId, ); ``` :::info This method only works with items that are currently visible. Calling `apiRef.focusItem()` on an item with a collapsed parent has no effect. ::: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { useSimpleTreeViewApiRef } from '@mui/x-tree-view/hooks'; export default function ApiMethodFocusItem() { const apiRef = useSimpleTreeViewApiRef(); const handleButtonClick = (event: React.SyntheticEvent) => { apiRef.current?.focusItem(event, 'pickers'); }; return (
); } ``` --- # Source: https://mui.com/x/api/charts/focused-funnel-section.md # FocusedFunnelSection API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Funnel ## Import ```jsx import { FocusedFunnelSection } from '@mui/x-charts-pro/FunnelChart'; // or import { FocusedFunnelSection } from '@mui/x-charts-pro'; ``` > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/FunnelChart/FocusedFunnelSection.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/FunnelChart/FocusedFunnelSection.tsx) --- # Source: https://mui.com/x/api/charts/focused-heatmap-cell.md # FocusedHeatmapCell API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Heatmap ## Import ```jsx import { FocusedHeatmapCell } from '@mui/x-charts-pro/Heatmap'; // or import { FocusedHeatmapCell } from '@mui/x-charts-pro'; ``` > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/Heatmap/FocusedHeatmapCell.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/Heatmap/FocusedHeatmapCell.tsx) --- # Source: https://mui.com/x/api/charts/focused-radar-mark.md # FocusedRadarMark API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Radar](/x/react-charts/radar/) ## Import ```jsx import { FocusedRadarMark } from '@mui/x-charts/RadarChart'; // or import { FocusedRadarMark } from '@mui/x-charts'; // or import { FocusedRadarMark } from '@mui/x-charts-pro'; // or import { FocusedRadarMark } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/RadarChart/FocusedRadarMark.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/RadarChart/FocusedRadarMark.tsx) --- # Source: https://mui.com/x/api/charts/focused-sankey-link.md # FocusedSankeyLink API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Sankey 🧪 ## Import ```jsx import { FocusedSankeyLink } from '@mui/x-charts-pro/SankeyChart'; // or import { FocusedSankeyLink } from '@mui/x-charts-pro'; ``` > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/SankeyChart/FocusedSankeyLink.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/SankeyChart/FocusedSankeyLink.tsx) --- # Source: https://mui.com/x/api/charts/focused-sankey-node.md # FocusedSankeyNode API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Sankey 🧪 ## Import ```jsx import { FocusedSankeyNode } from '@mui/x-charts-pro/SankeyChart'; // or import { FocusedSankeyNode } from '@mui/x-charts-pro'; ``` > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/SankeyChart/FocusedSankeyNode.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/SankeyChart/FocusedSankeyNode.tsx) --- # Source: https://mui.com/x/api/charts/funnel-chart.md # FunnelChart API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Export - Charts - Funnel - Charts - Pyramid ## Import ```jsx import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; // or import { FunnelChart } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | axisHighlight | `{ x?: 'band' \| 'line' \| 'none', y?: 'band' \| 'line' \| 'none' }` | - | No | | | categoryAxis | `{ categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'band', size?: number, tickLabelStyle?: object, tickSize?: number } \| { categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'log', size?: number, tickLabelStyle?: object, tickSize?: number } \| { categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'symlog', size?: number, tickLabelStyle?: object, tickSize?: number } \| { categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'pow', size?: number, tickLabelStyle?: object, tickSize?: number } \| { categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'sqrt', size?: number, tickLabelStyle?: object, tickSize?: number } \| { categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'time', size?: number, tickLabelStyle?: object, tickSize?: number } \| { categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'utc', size?: number, tickLabelStyle?: object, tickSize?: number } \| { categories?: Array, disableLine?: bool, disableTicks?: bool, id?: number \| string, position?: 'bottom' \| 'left' \| 'none' \| 'right' \| 'top', scaleType?: 'linear', size?: number, tickLabelStyle?: object, tickSize?: number }` | `{ position: 'none' }` | No | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | disableAxisListener | `bool` | `false` | No | | | gap | `number` | `0` | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'funnel' }>` | - | No | | | hideLegend | `bool` | `false` | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'funnel' }>` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onAxisClick | `function(event: MouseEvent, data: null \| ChartsAxisData) => void` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onItemClick | `function(event: React.MouseEvent, funnelItemIdentifier: FunnelItemIdentifier) => void` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex: number, seriesId: number \| string, type: 'funnel' }` | - | No | | | width | `number` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). > Any other props supplied will be provided to the root element (native element). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | axisLabel | `ChartsText` | - | Custom component for axis label. | | axisLine | `'line'` | - | Custom component for the axis main line. | | axisTick | `'line'` | - | Custom component for the axis tick. | | axisTickLabel | `ChartsText` | - | Custom component for tick label. | | baseButton | `undefined` | - | | | baseIconButton | `undefined` | - | | | funnelSection | `FunnelSection` | - | Custom component for funnel section. | | funnelSectionLabel | `FunnelSectionLabel` | - | Custom component for funnel section label. | | legend | `ChartsLegend` | - | Custom rendering of the legend. | | loadingOverlay | `ChartsLoadingOverlay` | - | Overlay component rendered when the chart is in a loading state. | | noDataOverlay | `ChartsNoDataOverlay` | - | Overlay component rendered when the chart has no data to display. | | toolbar | `ChartsToolbar` | - | Custom component for the toolbar. | | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/FunnelChart/FunnelChart.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/FunnelChart/FunnelChart.tsx) --- # Source: https://mui.com/x/api/charts/funnel-plot.md # FunnelPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Funnel - Charts - Pyramid ## Import ```jsx import { FunnelPlot } from '@mui/x-charts-pro/FunnelChart'; // or import { FunnelPlot } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | onItemClick | `function(event: React.MouseEvent, funnelItemIdentifier: FunnelItemIdentifier) => void` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/FunnelChart/FunnelPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/FunnelChart/FunnelPlot.tsx) --- # Source: https://mui.com/x/api/charts/funnel-series.md # FunnelSeries API ## Import ```jsx import { FunnelSeries } from '@mui/x-charts-premium' // or import { FunnelSeries } from '@mui/x-charts-pro' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | data | `Readonly` | - | Yes | | | type | `'funnel'` | - | Yes | | | borderRadius | `number` | `8` | No | | | curve | `FunnelCurveType` | `'linear'` | No | | | funnelDirection | `'increasing' \| 'decreasing' \| 'auto'` | `'auto'` | No | | | highlightScope | `HighlightScope` | - | No | | | id | `SeriesId` | - | No | | | label | `string \| ((location: 'tooltip' \| 'legend') => string)` | - | No | | | labelMarkType | `ChartsLabelMarkType` | - | No | | | layout | `'horizontal' \| 'vertical'` | `'vertical'` | No | | | sectionLabel | `FunnelLabelOptions \| ((item: FunnelItem) => FunnelLabelOptions \| false) \| false` | `{ vertical: 'middle', horizontal: 'center' }` | No | | | valueFormatter | `SeriesValueFormatter` | - | No | | | variant | `'filled' \| 'outlined'` | `'filled'` | No | | | xAxisId | `AxisId` | - | No | | | yAxisId | `AxisId` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/react-charts/funnel.md --- title: React Funnel chart productId: x-charts components: FunnelChart, FunnelPlot, FocusedFunnelSection --- # Charts - Funnel [](/x/introduction/licensing/#pro-plan 'Pro plan') Funnel charts let you express quantity evolution along a process, such as audience engagement, population education levels, or yields of multiple processes. ## Basics Funnel charts series must contain a `data` property containing an array of objects. Each object corresponds to a section of the funnel. It must contain a property `value` and can have other optional properties, like `label` and `id`. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; export default function BasicFunnel() { return ( ); } ``` ### Display legends The funnel chart displays a legend by default. The only requirement is to provide a `label` value in the data objects. To hide the legend, set the `hideLegend` prop to `true`. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; export default function FunnelLegend() { const [hideLegend, setHideLegend] = React.useState(false); return ( ); } const funnelProps = { height: 300, slotProps: { legend: { position: { vertical: 'bottom' } } }, } as const; function Controls({ hideLegend, setHideLegend, }: { hideLegend: boolean; setHideLegend: React.Dispatch>; }) { return ( setHideLegend((prev) => !prev)} /> } label="Hide legend" /> ); } ``` ## Pyramid Chart The pyramid chart is a variation of the funnel chart. To create a pyramid chart, set the `curve` property to `pyramid` in the series. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; export default function PyramidFunnel() { return ( ); } ``` ## Labels The funnel chart displays labels by default. It shows the `value` of the data item in each section. To format the labels, a `valueFormatter` function can be provided. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelLabels() { return ( `${item.label}${context.dataIndex} ${item.value}.00`, }, ]} {...funnelProps} /> ); } const funnelProps = { height: 300, hideLegend: true, } as const; ``` ### Styling labels The labels can be styled by using the `funnelSectionClasses.label` helper. ```tsx import Box from '@mui/material/Box'; import { FunnelChart, funnelSectionClasses } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelLabelStyling() { return ( ); } const funnelProps = { height: 300, hideLegend: true, } as const; ``` ### Positioning labels The labels can be positioned relative to the section they represent. The `sectionLabel` property accepts an object with the following properties: - `position.vertical`: The vertical position of the label. It can be `top`, `center` or `bottom`. - `position.horizontal`: The horizontal position of the label. It can be `start`, `middle` or `end`. - `margin`: The margin between the label and the section. - `dominantBaseline`: The vertical alignment of the text. It can be `auto`, `baseline`, `text-before-edge`, `text-after-edge`, `central`, `hanging`, or `middle`. - `textAnchor`: The horizontal alignment of the text. It can be `start`, `middle` or `end`. The `sectionLabel` property can be set to `false` to hide the labels. It also accepts a function that receives the data object and should return the label configuration. ```tsx import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import Stack from '@mui/material/Stack'; export default function FunnelLabelPositioning() { return ( ( )} getCode={({ props }) => { if (props.hide) { return `import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; `; } return `import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; `; }} /> ); } ``` ## Styling ### Curve interpolation The interpolation between data points can be customized by the `curve` property. This property expects one of the following string values, corresponding to the interpolation method: `'linear'`, `'linear-sharp'`, `'bump'`, `'pyramid'`, `'step'` and `'step-pyramid'`. This series property adds the option to control the interpolation of a series. ```tsx import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import Stack from '@mui/material/Stack'; import { populationByEducationLevelPercentageSeries } from './populationByEducationLevel'; const curveTypes = [ 'bump', 'linear', 'linear-sharp', 'step', 'pyramid', 'step-pyramid', ] as const; export default function FunnelCurves() { return ( ( )} getCode={({ props }) => { return `import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; `; }} /> ); } ``` ### Gap The gap between the sections can be customized by the `gap` property. It accepts a number that represents the gap in pixels. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelGap() { return ( ); } ``` ### Border radius The border radius of the sections can be customized by the `borderRadius` property. It accepts a number that represents the radius in pixels. - The `bump` curve interpolation will not respect the border radius. - The `linear`, `linear-sharp` and `pyramid` curves respect the border radius to some extent due to the angle of the sections. - The `step` and `step-pyramid` curves respect the border radius. To understand how the border radius interacts with the `curve` prop, see the [curve interpolation example](/x/react-charts/funnel/#curve-interpolation) above. The `borderRadius` property will also behave differently depending on whether the `gap` property is greater than 0. - If the `gap` is 0, the border radius will be applied to the corners of the sections that are not connected to another section. - If the `gap` is greater than 0, the border radius will be applied to all the corners of the sections. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelBorderRadius() { return ( ); } ``` ### Variant The funnel sections can be displayed in two different styles using the `variant` property: - `'filled'` (default): Sections have a solid fill and no stroke. - `'outlined'`: Sections have a translucent fill with a colored stroke around them. The `outlined` variant creates a more lightweight visual style. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelVariant() { const data = [ { value: 200, label: 'Leads' }, { value: 150, label: 'Calls' }, { value: 90, label: 'Meetings' }, { value: 40, label: 'Deals' }, ]; return ( ); } ``` ### Colors The funnel colors can be customized in two ways. 1. You can provide a [color palette](/x/react-charts/styling/#color-palette). Each section of the funnel will be colored according to this palette. 2. You can provide a `color` property in `data` objects, which overrides the palette. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelColor() { return ( ); } ``` ### CSS The funnel chart can be styled using CSS. Each section group has a `data-series` attribute that can be used to target specific series sections. In order to target specific sections, you can use the `:nth-child` or `:nth-child-of-type` selectors as shown in the example below. ```tsx import Box from '@mui/material/Box'; import { FunnelChart, funnelSectionClasses } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelDataAttributes() { return ( ); } const funnelProps = { height: 300, hideLegend: true, series: [ { id: 'main', data: [{ value: 200 }, { value: 180 }, { value: 90 }, { value: 50 }], }, ], } as const; ``` ## Multiple funnels By default, multiple series are displayed on top of each other. Simply provide multiple series to the funnel chart and make sure that they have different colors or styles to differentiate them. The order of the series determines the display order. The first series is at the bottom and the last is at the top. ```tsx import Box from '@mui/material/Box'; import { FunnelChart, FunnelChartProps } from '@mui/x-charts-pro/FunnelChart'; export default function FunnelStacked() { return ( ); } const dataBig: FunnelChartProps['series'][any]['data'] = [ { value: 500, label: 'A1' }, { value: 280, label: 'B1' }, { value: 190, label: 'C1' }, { value: 70, label: 'D1' }, ]; const dataSmall: FunnelChartProps['series'][any]['data'] = [ { value: 200, label: 'A2' }, { value: 180, label: 'B2' }, { value: 90, label: 'C2' }, { value: 50, label: 'D2' }, ]; ``` ## Highlight The hovered element can be highlighted by setting `highlightScope.highlight` property to one of the possible values. To fade elements which are not hovered, set the `highlightScope.fade` property. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; import { FadeOptions, HighlightOptions } from '@mui/x-charts/context'; import { populationByEducationLevelPercentageSeriesLabeled } from './populationByEducationLevel'; export default function HighlightFunnel() { const [highlight, setHighlight] = React.useState('item'); const [fade, setFade] = React.useState('global'); return ( ); } const funnelChartParams = { height: 300, hideLegend: true, }; function Controls({ highlight, setHighlight, fade, setFade, }: { highlight: string; setHighlight: React.Dispatch>; fade: string; setFade: React.Dispatch>; }) { return ( setHighlight(event.target.value as HighlightOptions)} sx={{ minWidth: 150 }} > none item series setFade(event.target.value as FadeOptions)} sx={{ minWidth: 150 }} > none series global ); } ``` ## Category axis The funnel chart uses a category axis as the default axis. This axis always follows the orientation of the chart. The funnel chart does not display an axis by default. To display a category axis, pass a `position` and a list of `categories` to the `categoryAxis` props. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; import { populationByEducationLevelPercentageSeriesLabeled } from './populationByEducationLevel'; export default function FunnelCategoryAxis() { return ( ); } const funnelProps = { height: 300, hideLegend: true, } as const; ``` ### Scaled sections By default, the sections have the same size because they use the `band` scale type. A linear scale is also available, and scales the sections based on their values. To do so, set the `scaleType` property to `linear` in the `categoryAxis`. ```tsx import Box from '@mui/material/Box'; import { FunnelChart } from '@mui/x-charts-pro/FunnelChart'; import { populationByEducationLevelPercentageSeriesLabeled } from './populationByEducationLevel'; export default function FunnelLinearScale() { return ( ); } const funnelProps = { height: 300, hideLegend: true, } as const; ``` --- # Source: https://mui.com/x/api/charts/gauge-container.md # GaugeContainer API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Gauge](/x/react-charts/gauge/) ## Import ```jsx import { GaugeContainer } from '@mui/x-charts/Gauge'; // or import { GaugeContainer } from '@mui/x-charts'; // or import { GaugeContainer } from '@mui/x-charts-pro'; // or import { GaugeContainer } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | cornerRadius | `number \| string` | `0` | No | | | cx | `number \| string` | - | No | | | cy | `number \| string` | - | No | | | endAngle | `number` | `360` | No | | | height | `number` | - | No | | | id | `string` | - | No | | | innerRadius | `number \| string` | `'80%'` | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | outerRadius | `number \| string` | `'100%'` | No | | | skipAnimation | `bool` | - | No | | | startAngle | `number` | `0` | No | | | value | `number` | - | No | | | valueMax | `number` | `100` | No | | | valueMin | `number` | `0` | No | | | width | `number` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/Gauge/GaugeContainer.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/Gauge/GaugeContainer.tsx) --- # Source: https://mui.com/x/api/charts/gauge.md # Source: https://mui.com/x/react-charts/gauge.md --- title: React Gauge chart productId: x-charts components: Gauge, GaugeContainer packageName: '@mui/x-charts' githubLabel: 'scope: charts' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/meter/ --- # Charts - Gauge Gauge let the user evaluate metrics. {{"component": "@mui/docs/ComponentLinkHeader", "design": false}} ## Basics The Gauge displays a numeric value that varies within a defined range. ```tsx import Stack from '@mui/material/Stack'; import { Gauge } from '@mui/x-charts/Gauge'; export default function BasicGauges() { return ( ); } ``` ## Value range The Gauge's value is provided through the `value` props, which accept a value range between 0 and 100. To modify it, use the `valueMin` and `valueMax` props. ```tsx import Stack from '@mui/material/Stack'; import { Gauge } from '@mui/x-charts/Gauge'; export default function GaugeValueRange() { return ( ); } ``` ## Arcs configuration Modify the arc shape with the following props: - `startAngle` and `endAngle`: The angle range provided in degrees - `innerRadius` and `outerRadius`: The arc's radii. It can be a fixed number of pixels or a percentage string, which will be a percent of the maximal available radius - `cornerRadius`: It can be a fixed number of pixels or a percentage string, which will be a percent of the maximal available radius ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import Box from '@mui/material/Box'; import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; export default function ArcPlayground() { return ( ( )} getCode={({ props }) => { const { innerRadius, outerRadius, ...numberProps } = props; return `import { Gauge } from '@mui/x-charts/Gauge'; `${name}={${value}}`) .join('\n ')} ${Object.entries({ innerRadius, outerRadius }) .map(([name, value]) => `${name}="${value}%"`) .join('\n ')} // ... /> `; }} /> ); } ``` :::success Notice that the arc position is computed to let the Gauge take as much space as possible in the drawing area. Use the `cx` and/or `cy` props to fix the coordinate of the arc center. ::: ## Text configuration By default, the Gauge displays the value in the center of the arc. To modify it, use the `text` prop. This prop can be a string, or a formatter. In the second case, the formatter argument contains the `value`, `valueMin` and `valueMax`. To modify the text's layout, use the `gaugeClasses.valueText` class name. ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import Box from '@mui/material/Box'; import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; export default function TextPlayground() { return ( ( `${value} / ${valueMax}`} /> )} getCode={({ props, }) => `import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; \`\${value} / \${valueMax}\`} /> `} /> ); } ``` ## Arc design To customize the Gauge styles, use the `gaugeClasses` export to pull class names from different parts of the component, such as `valueText`, `valueArc`, and `referenceArc`. For a full reference list, visit the [API page](/x/api/charts/gauge/#classes). ```tsx import { Gauge, gaugeClasses } from '@mui/x-charts/Gauge'; const settings = { width: 200, height: 200, value: 60, }; export default function ArcDesign() { return ( ({ [`& .${gaugeClasses.valueText}`]: { fontSize: 40, }, [`& .${gaugeClasses.valueArc}`]: { fill: '#52b202', }, [`& .${gaugeClasses.referenceArc}`]: { fill: theme.palette.text.disabled, }, })} /> ); } ``` ## Adding elements ### Using the default Gauge To insert more elements into the Gauge, the first option would be to add them as children, which means they will be stacked on top of the default rendering. ```tsx import { Gauge } from '@mui/x-charts/Gauge'; ; ``` ### Using the Gauge container The second option is to make use of the following elements that are available within the Gauge module: - Gauge Reference Arc - Gauge Value Arc - Gauge Value Text ```tsx import { GaugeContainer, Gauge, GaugeReferenceArc, GaugeValueArc, } from '@mui/x-charts/Gauge'; ; ``` ### Creating your components To create your own components, use the `useGaugeState()` hook which provides all you need about the gauge configuration: - information about the value: `value`, `valueMin`, `valueMax` - information to plot the arc: `startAngle`, `endAngle`, `outerRadius`, `innerRadius`, `cornerRadius`, `cx`, and `cy` - computed values: - `maxRadius`: the maximal radius that can fit the drawing area - `valueAngle`: the angle associated with the current value ```tsx import { GaugeContainer, GaugeValueArc, GaugeReferenceArc, useGaugeState, } from '@mui/x-charts/Gauge'; function GaugePointer() { const { valueAngle, outerRadius, cx, cy } = useGaugeState(); if (valueAngle === null) { // No value to display return null; } const target = { x: cx + outerRadius * Math.sin(valueAngle), y: cy - outerRadius * Math.cos(valueAngle), }; return ( ); } export default function CompositionExample() { return ( ); } ``` ## Accessibility The MUI X Gauge is compliant with the [Meter ARIA pattern](https://www.w3.org/WAI/ARIA/apg/patterns/meter/), which includes the addition of the `meter` role to the parent container and correct usage of the `aria-valuenow`, `aria-valuemin`, and `aria-valuemax` attributes. ### Label If a visible label is available, reference it by adding `aria-labelledby` attribute. Otherwise, the label can be manually provided by `aria-label`. ### Presentation Assistive technologies often present the value as a percentage. This can be modified by providing `aria-valuetext` attribute. For example, a battery level indicator is better with an hour-long duration. ```jsx

Battery level

``` ## Composition Use the `` to provide all the parameters as props: `value`, `valueMin`, `valueMax`, `startAngle`, `endAngle`, etc. In addition to the common chart components available for [composition](/x/react-charts/composition/), you can use the following components: - `` renders the reference arc. - `` renders the value arc. - `` renders the text at the center. Here's how the Gauge is composed: ```jsx ``` --- # Source: https://mui.com/x/api/data-grid/grid-actions-col-def.md # GridActionsColDef API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Special column properties](/x/react-data-grid/column-definition/#special-properties) ## Import ```jsx import { GridActionsColDef } from '@mui/x-data-grid-premium' // or import { GridActionsColDef } from '@mui/x-data-grid-pro' // or import { GridActionsColDef } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | field | `string` | - | Yes | | | getActions | `(params: GridRowParams) => readonly React.ReactElement[]` | - | Yes | | | type | `'actions'` | `'actions'` | Yes | | | aggregable | `boolean` | `true` | No | | | align | `GridAlignment` | - | No | | | availableAggregationFunctions | `string[]` | - | No | | | cellClassName | `GridCellClassNamePropType` | - | No | | | chartable | `boolean` | `true` | No | | | colSpan | `number \| GridColSpanFn` | `1` | No | | | description | `string` | - | No | | | disableColumnMenu | `boolean` | `false` | No | | | disableExport | `boolean` | `false` | No | | | disableReorder | `boolean` | `false` | No | | | display | `'text' \| 'flex'` | - | No | | | editable | `boolean` | `false` | No | | | examples | `V[]` | - | No | | | filterable | `boolean` | `true` | No | | | filterOperators | `readonly GridFilterOperator[]` | - | No | | | flex | `number` | - | No | | | getApplyQuickFilterFn | `GetApplyQuickFilterFn` | - | No | | | getSortComparator | `(sortDirection: GridSortDirection) => GridComparatorFn \| undefined` | - | No | | | groupable | `boolean` | `true` | No | | | groupingValueGetter | `GridGroupingValueGetter` | - | No | | | groupingValueSetter | `GridGroupingValueSetter` | - | No | | | headerAlign | `GridAlignment` | - | No | | | headerClassName | `GridColumnHeaderClassNamePropType` | - | No | | | headerName | `string` | - | No | | | hideable | `boolean` | `true` | No | | | hideSortIcons | `boolean` | `false` | No | | | maxWidth | `number` | `Infinity` | No | | | minWidth | `number` | `50` | No | | | pastedValueParser | `GridPastedValueParser` | - | No | | | pinnable | `boolean` | `true` | No | | | pivotable | `boolean` | `true` | No | | | preProcessEditCellProps | `(params: GridPreProcessEditCellProps) => GridEditCellProps \| Promise` | - | No | | | renderCell | `(params: GridRenderCellParams) => React.ReactNode` | - | No | | | renderEditCell | `(params: GridRenderEditCellParams) => React.ReactNode` | - | No | | | renderHeader | `(params: GridColumnHeaderParams) => React.ReactNode` | - | No | | | renderHeaderFilter | `(params: GridRenderHeaderFilterProps) => React.ReactNode` | - | No | | | resizable | `boolean` | `true` | No | | | rowSpanValueGetter | `GridValueGetter` | - | No | | | sortable | `boolean` | `true` | No | | | sortComparator | `GridComparatorFn` | - | No | | | sortingOrder | `readonly GridSortDirection[]` | - | No | | | valueFormatter | `GridValueFormatter` | - | No | | | valueGetter | `GridValueGetter` | - | No | | | valueParser | `GridValueParser` | - | No | | | valueSetter | `GridValueSetter` | - | No | | | width | `number` | `100` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-aggregation-function-data-source.md # GridAggregationFunctionDataSource API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Server-side aggregation](/x/react-data-grid/server-side-data/aggregation/) ## Import ```jsx import { GridAggregationFunctionDataSource } from '@mui/x-data-grid-premium' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | applySorting | `boolean` | `false` | No | | | columnTypes | `string[]` | - | No | | | hasCellUnit | `boolean` | `true` | No | | | label | `string` | `apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})` | No | | | valueFormatter | `GridValueFormatter` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-aggregation-function.md # GridAggregationFunction API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Aggregation functions](/x/react-data-grid/aggregation/#aggregation-functions) ## Import ```jsx import { GridAggregationFunction } from '@mui/x-data-grid-premium' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | apply | `(params: GridAggregationParams, api?: GridApiPremium) => AV \| null \| undefined` | - | Yes | | | applySorting | `boolean` | `false` | No | | | columnTypes | `string[]` | - | No | | | getCellValue | `(params: GridAggregationGetCellValueParams) => V` | - | No | | | hasCellUnit | `boolean` | `true` | No | | | label | `string` | `apiRef.current.getLocaleText('aggregationFunctionLabel{capitalize(name)})` | No | | | valueFormatter | `GridValueFormatter` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-api.md # GridApi API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [API object](/x/react-data-grid/api-object/) ## Import ```jsx import { GridApi } from '@mui/x-data-grid-premium' // or import { GridApi } from '@mui/x-data-grid-pro' // or import { GridApi } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | addRowGroupingCriteria | `(groupingCriteriaField: string, groupingIndex?: number) => void` | - | Yes | | | aiAssistant | `{ /** * Calls the `onPrompt()` callback to evaluate the prompt and get the necessary updates to the grid state. * Adds the prompt to the current conversation. * Updates the grid state based on the prompt response. * @param {string} value The prompt to process * @returns {Promise} The grid state updates or a processing error */ processPrompt: (value: string) => Promise /** * Sets the conversations. * @param {Conversation[] \| ((prevConversations: Conversation[]) => Conversation[])} conversations The new conversations. */ setConversations: (conversations: Conversation[] \| ((prevConversations: Conversation[]) => Conversation[])) => void /** * Sets the active conversation index. * @param {number} index The index of the conversation that should become active. * @returns {Conversation} The active conversation. * @throws {Error} If the conversation index does not exist. */ setActiveConversationIndex: (index: number) => Conversation }` | - | Yes | | | applySorting | `() => void` | - | Yes | | | autosizeColumns | `(options?: GridAutosizeOptions) => Promise` | - | Yes | | | collapseAllRows | `() => void` | - | Yes | | | dataSource | `{ /** * Fetches the rows from the server. * If no `parentId` option is provided, it fetches the root rows. * Any missing parameter from `params` will be filled from the state (sorting, filtering, etc.). * @param {GridRowId} parentId The id of the parent node (default: `GRID_ROOT_GROUP_ID`). * @param {GridDataSourceFetchRowsParams} params Request parameters override. * @returns {Promise} A promise that resolves when the rows are fetched. */ fetchRows: (parentId?: GridRowId, params?: GridDataSourceFetchRowsParams) => Promise /** * The data source cache object. */ cache: GridDataSourceCache /** * Syncs the row with the server and updates in the grid. * @param {GridUpdateRowParams} params The parameters for the edit operation. * @returns {Promise \| undefined} The updated row or `undefined` if `dataSource.updateRow` is not passed. */ editRow: (params: GridUpdateRowParams) => Promise \| undefined }` | - | Yes | | | deleteFilterItem | `(item: GridFilterItem) => void` | - | Yes | | | expandAllRows | `() => void` | - | Yes | | | exportDataAsCsv | `(options?: GridCsvExportOptions) => void` | - | Yes | | | exportDataAsExcel | `(options?: GridExcelExportOptions) => Promise` | - | Yes | | | exportDataAsPrint | `(options?: GridPrintExportOptions) => void` | - | Yes | | | exportState | `(params?: GridExportStateParams) => InitialState` | - | Yes | | | getAllColumns | `() => GridStateColDef[]` | - | Yes | | | getAllGroupDetails | `() => GridColumnGroupLookup` | - | Yes | | | getAllRowIds | `() => GridRowId[]` | - | Yes | | | getCellElement | `(id: GridRowId, field: string) => HTMLDivElement \| null` | - | Yes | | | getCellMode | `(id: GridRowId, field: string) => GridCellMode` | - | Yes | | | getCellParams | `(id: GridRowId, field: string) => GridCellParams` | - | Yes | | | getCellSelectionModel | `() => GridCellSelectionModel` | - | Yes | | | getCellValue | `(id: GridRowId, field: string) => V` | - | Yes | | | getColumn | `(field: string) => GridStateColDef` | - | Yes | | | getColumnGroupPath | `(field: string) => GridColumnGroup['groupId'][]` | - | Yes | | | getColumnHeaderElement | `(field: string) => HTMLDivElement \| null` | - | Yes | | | getColumnHeaderParams | `(field: string) => GridColumnHeaderParams` | - | Yes | | | getColumnIndex | `(field: string, useVisibleColumns?: boolean) => number` | - | Yes | | | getColumnIndexRelativeToVisibleColumns | `(field: string) => number` | - | Yes | | | getColumnPosition | `(field: string) => number` | - | Yes | | | getDataAsCsv | `(options?: GridCsvExportOptions) => string` | - | Yes | | | getDataAsExcel | `(options?: GridExcelExportOptions) => Promise \| null` | - | Yes | | | getExpandedDetailPanels | `() => Set` | - | Yes | | | getFilterState | `(filterModel: GridFilterModel) => GridStateCommunity['filter']` | - | Yes | | | getLocaleText | `(key: T) => GridLocaleText[T]` | - | Yes | | | getPinnedColumns | `() => GridPinnedColumnFields` | - | Yes | | | getPropagatedRowSelectionModel | `(inputSelectionModel: GridRowSelectionModel) => GridRowSelectionModel` | - | Yes | | | getRootDimensions | `() => GridDimensions` | - | Yes | | | getRow | `(id: GridRowId) => R \| null` | - | Yes | | | getRowElement | `(id: GridRowId) => HTMLDivElement \| null` | - | Yes | | | getRowGroupChildren | `(params: GridRowGroupChildrenGetterParams) => GridRowId[]` | - | Yes | | | getRowId | `(row: R) => GridRowId` | - | Yes | | | getRowIdFromRowIndex | `(index: number) => GridRowId` | - | Yes | | | getRowIndexRelativeToVisibleRows | `(id: GridRowId) => number` | - | Yes | | | getRowMode | `(id: GridRowId) => GridRowMode` | - | Yes | | | getRowModels | `() => Map` | - | Yes | | | getRowNode | `(id: GridRowId) => N \| null` | - | Yes | | | getRowParams | `(id: GridRowId) => GridRowParams` | - | Yes | | | getRowsCount | `() => number` | - | Yes | | | getRowWithUpdatedValues | `(id: GridRowId, field: string) => GridRowModel` | - | Yes | | | getScrollPosition | `() => GridScrollParams` | - | Yes | | | getSelectedCellsAsArray | `() => GridCellCoordinates[]` | - | Yes | | | getSelectedRows | `() => Map` | - | Yes | | | getSortedRowIds | `() => GridRowId[]` | - | Yes | | | getSortedRows | `() => GridRowModel[]` | - | Yes | | | getSortModel | `() => GridSortModel` | - | Yes | | | getVisibleColumns | `() => GridStateColDef[]` | - | Yes | | | hideColumnMenu | `() => void` | - | Yes | | | hideFilterPanel | `() => void` | - | Yes | | | hideHeaderFilterMenu | `() => void` | - | Yes | | | hidePreferences | `() => void` | - | Yes | | | hideSidebar | `() => void` | - | Yes | | | history | `{ /** * Undo the last action. * @returns {Promise} True if the operation was successful, false otherwise. */ undo: () => Promise /** * Redo the last undone action. * @returns {Promise} True if the operation was successful, false otherwise. */ redo: () => Promise /** * Clear the entire history. */ clear: () => void /** * @returns {boolean} True if there are undo steps available, false otherwise. */ canUndo: () => boolean /** * @returns {boolean} True if there are redo steps available, false otherwise. */ canRedo: () => boolean }` | - | Yes | | | ignoreDiacritics | `DataGridProcessedProps['ignoreDiacritics']` | - | Yes | | | isCellEditable | `(params: GridCellParams) => boolean` | - | Yes | | | isCellSelected | `(id: GridRowId, field: GridColDef['field']) => boolean` | - | Yes | | | isColumnPinned | `(field: string) => GridPinnedColumnPosition \| false` | - | Yes | | | isRowSelectable | `(id: GridRowId) => boolean` | - | Yes | | | isRowSelected | `(id: GridRowId) => boolean` | - | Yes | | | pinColumn | `(field: string, side: GridPinnedColumnPosition) => void` | - | Yes | | | publishEvent | `GridEventPublisher` | - | Yes | | | removeRowGroupingCriteria | `(groupingCriteriaField: string) => void` | - | Yes | | | resetRowHeights | `() => void` | - | Yes | | | restoreState | `(stateToRestore: InitialState) => void` | - | Yes | | | scroll | `(params: Partial) => void` | - | Yes | | | scrollToIndexes | `(params: Partial) => boolean` | - | Yes | | | selectCellRange | `(start: GridCellCoordinates, end: GridCellCoordinates, keepOtherSelected?: boolean) => void` | - | Yes | | | selectRow | `(id: GridRowId, isSelected?: boolean, resetSelection?: boolean) => void` | - | Yes | | | selectRowRange | `(range: { startId: GridRowId; endId: GridRowId }, isSelected?: boolean, resetSelection?: boolean) => void` | - | Yes | | | selectRows | `(ids: GridRowId[], isSelected?: boolean, resetSelection?: boolean) => void` | - | Yes | | | setActiveChartId | `(chartId: string) => void` | - | Yes | | | setAggregationModel | `(model: GridAggregationModel) => void` | - | Yes | | | setCellFocus | `(id: GridRowId, field: string) => void` | - | Yes | | | setCellSelectionModel | `(newModel: GridCellSelectionModel) => void` | - | Yes | | | setChartsPanelOpen | `(open: boolean \| ((prev: boolean) => boolean)) => void` | - | Yes | | | setChartSynchronizationState | `(chartId: string, synced: boolean) => void` | - | Yes | | | setChartType | `(chartId: string, type: string) => void` | - | Yes | | | setColumnHeaderFilterFocus | `(field: string, event?: MuiBaseEvent) => void` | - | Yes | | | setColumnHeaderFocus | `(field: string, event?: MuiBaseEvent) => void` | - | Yes | | | setColumnIndex | `(field: string, targetIndexPosition: number) => void` | - | Yes | | | setColumnVisibility | `(field: string, isVisible: boolean) => void` | - | Yes | | | setColumnVisibilityModel | `(model: GridColumnVisibilityModel) => void` | - | Yes | | | setColumnWidth | `(field: string, width: number) => void` | - | Yes | | | setDensity | `(density: GridDensity) => void` | - | Yes | | | setEditCellValue | `(params: GridEditCellValueParams, event?: MuiBaseEvent) => Promise \| void` | - | Yes | | | setExpandedDetailPanels | `(ids: Set) => void` | - | Yes | | | setFilterLogicOperator | `(operator: GridLogicOperator) => void` | - | Yes | | | setFilterModel | `(model: GridFilterModel, reason?: GridControlledStateReasonLookup['filter']) => void` | - | Yes | | | setLoading | `(loading: boolean) => void` | - | Yes | | | setPage | `(page: number) => void` | - | Yes | | | setPageSize | `(pageSize: number) => void` | - | Yes | | | setPaginationMeta | `(paginationMeta: GridPaginationMeta) => void` | - | Yes | | | setPaginationModel | `(model: GridPaginationModel) => void` | - | Yes | | | setPinnedColumns | `(pinnedColumns: GridPinnedColumnFields) => void` | - | Yes | | | setPivotActive | `(active: boolean \| ((prev: boolean) => boolean)) => void` | - | Yes | | | setPivotModel | `(model: GridPivotModel \| ((prev: GridPivotModel) => GridPivotModel)) => void` | - | Yes | | | setPivotPanelOpen | `(open: boolean \| ((prev: boolean) => boolean)) => void` | - | Yes | | | setQuickFilterValues | `(values: any[]) => void` | - | Yes | | | setRowChildrenExpansion | `(id: GridRowId, isExpanded: boolean) => void` | - | Yes | | | setRowCount | `(rowCount: number) => void` | - | Yes | | | setRowGroupingCriteriaIndex | `(groupingCriteriaField: string, groupingIndex: number) => void` | - | Yes | | | setRowGroupingModel | `(model: GridRowGroupingModel) => void` | - | Yes | | | setRowIndex | `(rowId: GridRowId, targetIndex: number) => void \| Promise` | - | Yes | | | setRowPosition | `(sourceRowId: GridRowId, targetRowId: GridRowId, position: RowReorderDropPosition) => void \| Promise` | - | Yes | | | setRows | `(rows: GridRowModel[]) => void` | - | Yes | | | setRowSelectionModel | `(rowSelectionModel: GridRowSelectionModel, reason?: GridControlledStateReasonLookup['rowSelection']) => void` | - | Yes | | | setSortModel | `(model: GridSortModel) => void` | - | Yes | | | showColumnMenu | `(field: string) => void` | - | Yes | | | showFilterPanel | `(targetColumnField?: string, panelId?: string, labelId?: string) => void` | - | Yes | | | showHeaderFilterMenu | `(field: GridColDef['field']) => void` | - | Yes | | | showPreferences | `(newValue: GridPreferencePanelsValue, panelId?: string, labelId?: string) => void` | - | Yes | | | showSidebar | `(newValue: GridSidebarValue, sidebarId?: string, labelId?: string) => void` | - | Yes | | | sortColumn | `(field: GridColDef['field'], direction?: GridSortDirection, allowMultipleSorting?: boolean) => void` | - | Yes | | | startCellEditMode | `(params: GridStartCellEditModeParams) => void` | - | Yes | | | startHeaderFilterEditMode | `(field: GridColDef['field']) => void` | - | Yes | | | startRowEditMode | `(params: GridStartRowEditModeParams) => void` | - | Yes | | | state | `State` | - | Yes | | | stopCellEditMode | `(params: GridStopCellEditModeParams) => void` | - | Yes | | | stopHeaderFilterEditMode | `() => void` | - | Yes | | | stopRowEditMode | `(params: GridStopRowEditModeParams) => void` | - | Yes | | | subscribeEvent | `(event: E, handler: GridEventListener, options?: EventListenerOptions) => () => void` | - | Yes | | | toggleColumnMenu | `(field: string) => void` | - | Yes | | | toggleDetailPanel | `(id: GridRowId) => void` | - | Yes | | | unpinColumn | `(field: string) => void` | - | Yes | | | unstable_replaceRows | `(firstRowToReplace: number, newRows: GridRowModel[]) => void` | - | Yes | | | unstable_setColumnVirtualization | `(enabled: boolean) => void` | - | Yes | | | unstable_setPinnedRows | `(pinnedRows?: GridPinnedRowsProp) => void` | - | Yes | | | unstable_setVirtualization | `(enabled: boolean) => void` | - | Yes | | | updateChartDimensionsData | `(chartId: string, dimensions: GridChartsIntegrationItem[] \| ((prev: GridChartsIntegrationItem[]) => GridChartsIntegrationItem[])) => void` | - | Yes | | | updateChartValuesData | `(chartId: string, values: GridChartsIntegrationItem[] \| ((prev: GridChartsIntegrationItem[]) => GridChartsIntegrationItem[])) => void` | - | Yes | | | updateColumns | `(cols: GridColDef[]) => void` | - | Yes | | | updateRows | `(updates: GridRowModelUpdate[]) => void` | - | Yes | | | upsertFilterItem | `(item: GridFilterItem) => void` | - | Yes | | | upsertFilterItems | `(items: GridFilterItem[]) => void` | - | Yes | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-cell-params.md # GridCellParams API ## Import ```jsx import { GridCellParams } from '@mui/x-data-grid-premium' // or import { GridCellParams } from '@mui/x-data-grid-pro' // or import { GridCellParams } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | api | `GridApiCommunity` | - | Yes | | | cellMode | `GridCellMode` | - | Yes | | | colDef | `GridStateColDef` | - | Yes | | | field | `string` | - | Yes | | | hasFocus | `boolean` | - | Yes | | | id | `GridRowId` | - | Yes | | | row | `GridRowModel` | - | Yes | | | rowNode | `N` | - | Yes | | | tabIndex | `0 \| -1` | - | Yes | | | formattedValue | `F \| undefined` | - | No | | | isEditable | `boolean` | - | No | | | value | `V \| undefined` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-charts-panel.md # GridChartsPanel API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { GridChartsPanel } from '@mui/x-data-grid-premium/components'; // or import { GridChartsPanel } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | getColumnName | `function(field: string) => string \| undefined` | - | No | | | schema | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/chartsPanel/GridChartsPanel.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/chartsPanel/GridChartsPanel.tsx) --- # Source: https://mui.com/x/api/data-grid/grid-charts-renderer-proxy.md # GridChartsRendererProxy API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { GridChartsRendererProxy } from '@mui/x-data-grid-premium/context'; // or import { GridChartsRendererProxy } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | id | `string` | - | Yes | | | renderer | `func` | - | Yes | | | label | `string` | - | No | | | onRender | `func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/context/GridChartsRendererProxy.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/context/GridChartsRendererProxy.tsx) --- # Source: https://mui.com/x/api/data-grid/grid-col-def.md # GridColDef API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Column definition](/x/react-data-grid/column-definition/) ## Import ```jsx import { GridColDef } from '@mui/x-data-grid-premium' // or import { GridColDef } from '@mui/x-data-grid-pro' // or import { GridColDef } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | field | `string` | - | Yes | | | aggregable | `boolean` | `true` | No | | | align | `GridAlignment` | - | No | | | availableAggregationFunctions | `string[]` | - | No | | | cellClassName | `GridCellClassNamePropType` | - | No | | | chartable | `boolean` | `true` | No | | | colSpan | `number \| GridColSpanFn` | `1` | No | | | description | `string` | - | No | | | disableColumnMenu | `boolean` | `false` | No | | | disableExport | `boolean` | `false` | No | | | disableReorder | `boolean` | `false` | No | | | display | `'text' \| 'flex'` | - | No | | | editable | `boolean` | `false` | No | | | examples | `V[]` | - | No | | | filterable | `boolean` | `true` | No | | | filterOperators | `readonly GridFilterOperator[]` | - | No | | | flex | `number` | - | No | | | getApplyQuickFilterFn | `GetApplyQuickFilterFn` | - | No | | | getSortComparator | `(sortDirection: GridSortDirection) => GridComparatorFn \| undefined` | - | No | | | groupable | `boolean` | `true` | No | | | groupingValueGetter | `GridGroupingValueGetter` | - | No | | | groupingValueSetter | `GridGroupingValueSetter` | - | No | | | headerAlign | `GridAlignment` | - | No | | | headerClassName | `GridColumnHeaderClassNamePropType` | - | No | | | headerName | `string` | - | No | | | hideable | `boolean` | `true` | No | | | hideSortIcons | `boolean` | `false` | No | | | maxWidth | `number` | `Infinity` | No | | | minWidth | `number` | `50` | No | | | pastedValueParser | `GridPastedValueParser` | - | No | | | pinnable | `boolean` | `true` | No | | | pivotable | `boolean` | `true` | No | | | preProcessEditCellProps | `(params: GridPreProcessEditCellProps) => GridEditCellProps \| Promise` | - | No | | | renderCell | `(params: GridRenderCellParams) => React.ReactNode` | - | No | | | renderEditCell | `(params: GridRenderEditCellParams) => React.ReactNode` | - | No | | | renderHeader | `(params: GridColumnHeaderParams) => React.ReactNode` | - | No | | | renderHeaderFilter | `(params: GridRenderHeaderFilterProps) => React.ReactNode` | - | No | | | resizable | `boolean` | `true` | No | | | rowSpanValueGetter | `GridValueGetter` | - | No | | | sortable | `boolean` | `true` | No | | | sortComparator | `GridComparatorFn` | - | No | | | sortingOrder | `readonly GridSortDirection[]` | - | No | | | type | `GridColType` | `'singleSelect'` | No | | | valueFormatter | `GridValueFormatter` | - | No | | | valueGetter | `GridValueGetter` | - | No | | | valueParser | `GridValueParser` | - | No | | | valueSetter | `GridValueSetter` | - | No | | | width | `number` | `100` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-csv-export-options.md # GridCsvExportOptions API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [CSV export](/x/react-data-grid/export/#csv-export) ## Import ```jsx import { GridCsvExportOptions } from '@mui/x-data-grid-premium' // or import { GridCsvExportOptions } from '@mui/x-data-grid-pro' // or import { GridCsvExportOptions } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | allColumns | `boolean` | `false` | No | | | delimiter | `string` | `','` | No | | | escapeFormulas | `boolean` | `true` | No | | | fields | `string[]` | - | No | | | fileName | `string` | `document.title` | No | | | getRowsToExport | `(params: GridCsvGetRowsToExportParams) => GridRowId[]` | - | No | | | includeColumnGroupsHeaders | `boolean` | `true` | No | | | includeHeaders | `boolean` | `true` | No | | | utf8WithBom | `boolean` | `false` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-excel-export-options.md # GridExcelExportOptions API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Excel export](/x/react-data-grid/export/#excel-export) ## Import ```jsx import { GridExcelExportOptions } from '@mui/x-data-grid-premium' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | allColumns | `boolean` | `false` | No | | | columnsStyles | `ColumnsStylesInterface` | - | No | | | escapeFormulas | `boolean` | `true` | No | | | exceljsPostProcess | `(processInput: GridExceljsProcessInput) => Promise` | - | No | | | exceljsPreProcess | `(processInput: GridExceljsProcessInput) => Promise` | - | No | | | fields | `string[]` | - | No | | | fileName | `string` | `document.title` | No | | | getRowsToExport | `(params: GridGetRowsToExportParams) => GridRowId[]` | - | No | | | includeColumnGroupsHeaders | `boolean` | `true` | No | | | includeHeaders | `boolean` | `true` | No | | | valueOptionsSheetName | `string` | - | No | | | worker | `() => Worker` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-export-state-params.md # GridExportStateParams API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Restore state with `apiRef`](/x/react-data-grid/state/#restore-the-state-with-apiref) ## Import ```jsx import { GridExportStateParams } from '@mui/x-data-grid-premium' // or import { GridExportStateParams } from '@mui/x-data-grid-pro' // or import { GridExportStateParams } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | exportOnlyDirtyModels | `boolean` | `false` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-filter-form.md # GridFilterForm API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { GridFilterForm } from '@mui/x-data-grid/components'; // or import { GridFilterForm } from '@mui/x-data-grid'; // or import { GridFilterForm } from '@mui/x-data-grid-pro'; // or import { GridFilterForm } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | applyFilterChanges | `function(item: GridFilterItem) => void` | - | Yes | | | applyMultiFilterOperatorChanges | `function(operator: GridLogicOperator) => void` | - | Yes | | | deleteFilter | `function(item: GridFilterItem) => void` | - | Yes | | | hasMultipleFilters | `bool` | - | Yes | | | item | `{ field: string, id?: number \| string, operator: string, value?: any }` | - | Yes | | | columnInputProps | `any` | `{}` | No | | | columnsSort | `'asc' \| 'desc'` | - | No | | | deleteIconProps | `any` | `{}` | No | | | disableMultiFilterOperator | `bool` | - | No | | | filterColumns | `function(args: FilterColumnsArgs) => void` | - | No | | | focusElementRef | `func \| object` | - | No | | | logicOperatorInputProps | `any` | `{}` | No | | | logicOperators | `Array<'and' \| 'or'>` | `[GridLogicOperator.And, GridLogicOperator.Or]` | No | | | operatorInputProps | `any` | `{}` | No | | | readOnly | `bool` | `false` | No | | | showMultiFilterOperators | `bool` | - | No | | | valueInputProps | `any` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/panel/filterPanel/GridFilterForm.tsx) --- # Source: https://mui.com/x/api/data-grid/grid-filter-item.md # GridFilterItem API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom filter operator](/x/react-data-grid/filtering/customization/#create-a-custom-operator) ## Import ```jsx import { GridFilterItem } from '@mui/x-data-grid-premium' // or import { GridFilterItem } from '@mui/x-data-grid-pro' // or import { GridFilterItem } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | field | `GridBaseColDef['field']` | - | Yes | | | operator | `'contains' \| 'doesNotContain' \| 'equals' \| 'doesNotEqual' \| 'startsWith' \| 'endsWith' \| '=' \| '!=' \| '>' \| '>=' \| '<' \| '<=' \| 'is' \| 'not' \| 'after' \| 'onOrAfter' \| 'before' \| 'onOrBefore' \| 'isEmpty' \| 'isNotEmpty' \| 'isAnyOf' \| (string & {})` | - | Yes | | | id | `number \| string` | - | No | | | value | `any` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-filter-model.md # GridFilterModel API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Pass filters to the grid](/x/react-data-grid/filtering/#pass-filters-to-the-data-grid) ## Import ```jsx import { GridFilterModel } from '@mui/x-data-grid-premium' // or import { GridFilterModel } from '@mui/x-data-grid-pro' // or import { GridFilterModel } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | items | `GridFilterItem[]` | `[]` | Yes | | | logicOperator | `GridLogicOperator` | `GridLogicOperator.And` | No | | | quickFilterExcludeHiddenColumns | `boolean` | `true` | No | | | quickFilterLogicOperator | `GridLogicOperator` | `GridLogicOperator.And` | No | | | quickFilterValues | `any[]` | `[]` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-filter-operator.md # GridFilterOperator API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom filter operator](/x/react-data-grid/filtering/customization/#create-a-custom-operator) ## Import ```jsx import { GridFilterOperator } from '@mui/x-data-grid-premium' // or import { GridFilterOperator } from '@mui/x-data-grid-pro' // or import { GridFilterOperator } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | getApplyFilterFn | `GetApplyFilterFn` | - | Yes | | | value | `GridFilterItem['operator']` | - | Yes | | | getValueAsString | `(value: GridFilterItem['value']) => string` | - | No | | | headerLabel | `string` | - | No | | | InputComponent | `React.JSXElementConstructor` | - | No | | | InputComponentProps | `Partial` | - | No | | | label | `string` | - | No | | | requiresFilterValue | `boolean` | `true` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-filter-panel.md # GridFilterPanel API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { GridFilterPanel } from '@mui/x-data-grid/components'; // or import { GridFilterPanel } from '@mui/x-data-grid'; // or import { GridFilterPanel } from '@mui/x-data-grid-pro'; // or import { GridFilterPanel } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | columnsSort | `'asc' \| 'desc'` | - | No | | | disableAddFilterButton | `bool` | `false` | No | | | disableRemoveAllButton | `bool` | `false` | No | | | filterFormProps | `{ columnInputProps?: any, columnsSort?: 'asc' \| 'desc', deleteIconProps?: any, filterColumns?: func, logicOperatorInputProps?: any, operatorInputProps?: any, valueInputProps?: any }` | - | No | | | getColumnForNewFilter | `function(args: GetColumnForNewFilterArgs) => void` | - | No | | | logicOperators | `Array<'and' \| 'or'>` | `[GridLogicOperator.And, GridLogicOperator.Or]` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/panel/filterPanel/GridFilterPanel.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/panel/filterPanel/GridFilterPanel.tsx) --- # Source: https://mui.com/x/api/data-grid/grid-list-view-col-def.md # GridListViewColDef API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [List view](/x/react-data-grid/list-view/) ## Import ```jsx import { GridListViewColDef } from '@mui/x-data-grid-premium' // or import { GridListViewColDef } from '@mui/x-data-grid-pro' // or import { GridListViewColDef } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | field | `string` | - | Yes | | | align | `GridAlignment` | - | No | | | cellClassName | `GridCellClassNamePropType` | - | No | | | display | `'text' \| 'flex'` | - | No | | | renderCell | `(params: GridRenderCellParams) => React.ReactNode` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-print-export-options.md # GridPrintExportOptions API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Print export](/x/react-data-grid/export/#print-export) ## Import ```jsx import { GridPrintExportOptions } from '@mui/x-data-grid-premium' // or import { GridPrintExportOptions } from '@mui/x-data-grid-pro' // or import { GridPrintExportOptions } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | allColumns | `boolean` | `false` | No | | | bodyClassName | `string` | - | No | | | copyStyles | `boolean` | `true` | No | | | fields | `string[]` | - | No | | | fileName | `string` | `The title of the page.` | No | | | getRowsToExport | `(params: GridPrintGetRowsToExportParams) => GridRowId[]` | - | No | | | hideFooter | `boolean` | `false` | No | | | hideToolbar | `boolean` | `false` | No | | | includeCheckboxes | `boolean` | `false` | No | | | pageStyle | `string \| (() => string)` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-render-context.md # GridRenderContext API ## Import ```jsx import { GridRenderContext } from '@mui/x-data-grid-premium' // or import { GridRenderContext } from '@mui/x-data-grid-pro' // or import { GridRenderContext } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | firstColumnIndex | `number` | - | Yes | | | firstRowIndex | `number` | - | Yes | | | lastColumnIndex | `number` | - | Yes | | | lastRowIndex | `number` | - | Yes | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-row-class-name-params.md # GridRowClassNameParams API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Styling rows](/x/react-data-grid/style/#styling-rows) ## Import ```jsx import { GridRowClassNameParams } from '@mui/x-data-grid-premium' // or import { GridRowClassNameParams } from '@mui/x-data-grid-pro' // or import { GridRowClassNameParams } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | columns | `GridColDef[]` | - | Yes | | | id | `GridRowId` | - | Yes | | | indexRelativeToCurrentPage | `number` | - | Yes | | | isFirstVisible | `boolean` | - | Yes | | | isLastVisible | `boolean` | - | Yes | | | row | `R` | - | Yes | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-row-order-change-params.md # GridRowOrderChangeParams API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Flat row reordering](/x/react-data-grid/row-ordering/#implementing-row-reordering) ## Import ```jsx import { GridRowOrderChangeParams } from '@mui/x-data-grid-premium' // or import { GridRowOrderChangeParams } from '@mui/x-data-grid-pro' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | newParent | `GridRowId \| null` | - | Yes | | | oldIndex | `number` | - | Yes | | | oldParent | `GridRowId \| null` | - | Yes | | | row | `GridRowModel` | - | Yes | | | targetIndex | `number` | - | Yes | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-row-params.md # GridRowParams API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Master-detail row panels](/x/react-data-grid/master-detail/) ## Import ```jsx import { GridRowParams } from '@mui/x-data-grid-premium' // or import { GridRowParams } from '@mui/x-data-grid-pro' // or import { GridRowParams } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | columns | `GridColDef[]` | - | Yes | | | id | `GridRowId` | - | Yes | | | row | `R` | - | Yes | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-row-spacing-params.md # GridRowSpacingParams API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Row spacing](/x/react-data-grid/row-height/#row-spacing) ## Import ```jsx import { GridRowSpacingParams } from '@mui/x-data-grid-premium' // or import { GridRowSpacingParams } from '@mui/x-data-grid-pro' // or import { GridRowSpacingParams } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | id | `GridRowId` | - | Yes | | | indexRelativeToCurrentPage | `number` | - | Yes | | | isFirstVisible | `boolean` | - | Yes | | | isLastVisible | `boolean` | - | Yes | | | model | `R` | - | Yes | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-single-select-col-def.md # GridSingleSelectColDef API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Special column properties](/x/react-data-grid/column-definition/#special-properties) ## Import ```jsx import { GridSingleSelectColDef } from '@mui/x-data-grid-premium' // or import { GridSingleSelectColDef } from '@mui/x-data-grid-pro' // or import { GridSingleSelectColDef } from '@mui/x-data-grid' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | field | `string` | - | Yes | | | getOptionLabel | `(value: ValueOptions) => string` | `{defaultGetOptionLabel}` | Yes | | | getOptionValue | `(value: ValueOptions) => any` | `{defaultGetOptionValue}` | Yes | | | type | `'singleSelect'` | `'singleSelect'` | Yes | | | aggregable | `boolean` | `true` | No | | | align | `GridAlignment` | - | No | | | availableAggregationFunctions | `string[]` | - | No | | | cellClassName | `GridCellClassNamePropType` | - | No | | | chartable | `boolean` | `true` | No | | | colSpan | `number \| GridColSpanFn` | `1` | No | | | description | `string` | - | No | | | disableColumnMenu | `boolean` | `false` | No | | | disableExport | `boolean` | `false` | No | | | disableReorder | `boolean` | `false` | No | | | display | `'text' \| 'flex'` | - | No | | | editable | `boolean` | `false` | No | | | examples | `V[]` | - | No | | | filterable | `boolean` | `true` | No | | | filterOperators | `readonly GridFilterOperator[]` | - | No | | | flex | `number` | - | No | | | getApplyQuickFilterFn | `GetApplyQuickFilterFn` | - | No | | | getSortComparator | `(sortDirection: GridSortDirection) => GridComparatorFn \| undefined` | - | No | | | groupable | `boolean` | `true` | No | | | groupingValueGetter | `GridGroupingValueGetter` | - | No | | | groupingValueSetter | `GridGroupingValueSetter` | - | No | | | headerAlign | `GridAlignment` | - | No | | | headerClassName | `GridColumnHeaderClassNamePropType` | - | No | | | headerName | `string` | - | No | | | hideable | `boolean` | `true` | No | | | hideSortIcons | `boolean` | `false` | No | | | maxWidth | `number` | `Infinity` | No | | | minWidth | `number` | `50` | No | | | pastedValueParser | `GridPastedValueParser` | - | No | | | pinnable | `boolean` | `true` | No | | | pivotable | `boolean` | `true` | No | | | preProcessEditCellProps | `(params: GridPreProcessEditCellProps) => GridEditCellProps \| Promise` | - | No | | | renderCell | `(params: GridRenderCellParams) => React.ReactNode` | - | No | | | renderEditCell | `(params: GridRenderEditCellParams) => React.ReactNode` | - | No | | | renderHeader | `(params: GridColumnHeaderParams) => React.ReactNode` | - | No | | | renderHeaderFilter | `(params: GridRenderHeaderFilterProps) => React.ReactNode` | - | No | | | resizable | `boolean` | `true` | No | | | rowSpanValueGetter | `GridValueGetter` | - | No | | | sortable | `boolean` | `true` | No | | | sortComparator | `GridComparatorFn` | - | No | | | sortingOrder | `readonly GridSortDirection[]` | - | No | | | valueFormatter | `GridValueFormatter` | - | No | | | valueGetter | `GridValueGetter` | - | No | | | valueOptions | `Array \| ((params: GridValueOptionsParams) => Array)` | - | No | | | valueParser | `GridValueParser` | - | No | | | valueSetter | `GridValueSetter` | - | No | | | width | `number` | `100` | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/data-grid/grid-toolbar-quick-filter.md # GridToolbarQuickFilter API > ⚠️ **Warning**: This component is deprecated. Consider using an alternative component. ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [DataGrid](/x/react-data-grid/#community-version-free-forever) - [DataGridPro](/x/react-data-grid/#pro-version) - [DataGridPremium](/x/react-data-grid/#premium-version) ## Import ```jsx import { GridToolbarQuickFilter } from '@mui/x-data-grid/components'; // or import { GridToolbarQuickFilter } from '@mui/x-data-grid'; // or import { GridToolbarQuickFilter } from '@mui/x-data-grid-pro'; // or import { GridToolbarQuickFilter } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | debounceMs | `number` | `150` | No | | | quickFilterFormatter | `function(values: Array) => string` | `(values: string[]) => values.join(' ')` | No | | | quickFilterParser | `function(input: string) => Array` | `(searchText: string) => searchText .split(' ') .filter((word) => word !== '')` | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid/src/components/toolbar/GridToolbarQuickFilter.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid/src/components/toolbar/GridToolbarQuickFilter.tsx) --- # Source: https://mui.com/x/react-data-grid/filtering/header-filters.md --- title: Data Grid - Header filters --- # Data Grid - Header filters [](/x/introduction/licensing/#pro-plan 'Pro plan') Give users quick-access column filters in the Data Grid header. By default, users access the Data Grid's filtering features through the filter panel in the toolbar. The header filter feature adds a row to the top of the Data Grid Pro that lets users quickly filter columns directly in place. Filters added through the filter panel are synchronized with header filters, and vice versa. In the demo below, you can switch between different operators by clicking the operator button in the header filter cell or pressing ⌘ Command+Enter (or Ctrl+Enter on Windows) when focusing on a header filter cell. ```tsx import { DataGridPro } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function HeaderFilteringDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 100, }); return (
); } ``` ## Implementing header filters To enable header filters, pass the `headerFilters` prop to the Data Grid Pro: ```tsx ``` ### Disabling the default filter panel You can disable the default filter panel using the `disableColumnFilter` prop, and show only the default operator by passing `slots.headerFilterMenu` as `null`. ```tsx import { DataGridPro, gridClasses } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function SimpleHeaderFilteringDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 100, }); return (
); } ``` ### Inline clear button By default, the **Clear filter** button is located in the header filter menu. To display the button in the header filter cell instead, set `slotProps.headerFilterCell.showClearIcon` to `true`: ```tsx import * as React from 'react'; import { DataGridPro } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'website']; export default function HeaderFilteringInlineClearDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 100, visibleFields: VISIBLE_FIELDS, }); const columns = React.useMemo(() => { return data.columns.map((col) => ({ ...col, minWidth: 200, })); }, [data.columns]); return (
', value: 2 }, ], }, }, }} headerFilters slotProps={{ headerFilterCell: { showClearIcon: true, }, }} />
); } ``` ## Customizing header filters You can override header filter cells individually or across the entire row. ### One header filter cell in a specific column Use the `renderHeaderFilter()` method of the `GridColDef` to customize the header filter cell for a specific column. ```tsx const columns: GridColDef[] = [ { field: 'isAdmin', renderHeaderFilter: (params: GridHeaderFilterCellProps) => ( ), }, ]; ``` The demo below uses the `renderHeaderFilter()` method to hide the header filter cell for the **Phone** column and customize it for the **Is admin?** column: ```tsx import * as React from 'react'; import FormControl from '@mui/material/FormControl'; import InputLabel from '@mui/material/InputLabel'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import MenuItem from '@mui/material/MenuItem'; import { DataGridPro, GridRenderHeaderFilterProps, gridFilterModelSelector, useGridSelector, useGridApiContext, } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; const getDefaultFilter = (field: string) => ({ field, operator: 'is' }); function AdminFilter(props: GridRenderHeaderFilterProps) { const { colDef } = props; const apiRef = useGridApiContext(); const filterModel = useGridSelector(apiRef, gridFilterModelSelector); const currentFieldFilters = React.useMemo( () => filterModel.items?.filter(({ field }) => field === colDef.field), [colDef.field, filterModel.items], ); const handleChange = React.useCallback( (event: SelectChangeEvent) => { if (!event.target.value) { if (currentFieldFilters[0]) { apiRef.current.deleteFilterItem(currentFieldFilters[0]); } return; } apiRef.current.upsertFilterItem({ ...(currentFieldFilters[0] || getDefaultFilter(colDef.field)), value: event.target.value, }); }, [apiRef, colDef.field, currentFieldFilters], ); const value = currentFieldFilters[0]?.value ?? ''; const label = !value ? 'Filter' : 'Is admin'; return ( {label} ); } export default function CustomHeaderFilterSingleDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 100, visibleFields: ['name', 'website', 'phone', 'isAdmin', 'salary'], }); const columns = React.useMemo( () => data.columns.map((colDef) => { if (colDef.field === 'isAdmin') { return { ...colDef, width: 200, renderHeaderFilter: (params: GridRenderHeaderFilterProps) => ( ), }; } if (colDef.field === 'phone') { // no header filter for `phone` field return { ...colDef, renderHeaderFilter: () => null }; } return colDef; }), [data.columns], ); return (
); } ``` ### All header filter cells in every column Use `slots.headerFilterCell` to override all header filter cells in the row with a custom component: ```tsx ``` The default slot component handles keyboard navigation and focus management, so your custom component should also account for these accessibility features. The demo below shows how to do this. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import { DataGridPro, useGridSelector, gridFilterModelSelector, useGridApiContext, GridHeaderFilterCellProps, GridHeaderFilterEventLookup, } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; function CustomHeaderFilter(props: GridHeaderFilterCellProps) { const { colDef, width, height, hasFocus, colIndex, tabIndex } = props; const apiRef = useGridApiContext(); const cellRef = React.useRef(null); React.useLayoutEffect(() => { if (hasFocus && cellRef.current) { const focusableElement = cellRef.current!.querySelector('[tabindex="0"]'); const elementToFocus = focusableElement || cellRef.current; elementToFocus?.focus({ preventScroll: true, }); } }, [apiRef, hasFocus]); const publish = React.useCallback( ( eventName: keyof GridHeaderFilterEventLookup, propHandler?: React.EventHandler, ) => (event: React.SyntheticEvent) => { apiRef.current.publishEvent( eventName, apiRef.current.getColumnHeaderParams(colDef.field), event as any, ); if (propHandler) { propHandler(event); } }, [apiRef, colDef.field], ); const onMouseDown = React.useCallback( (event: React.MouseEvent) => { if (!hasFocus) { cellRef.current?.focus(); apiRef.current.setColumnHeaderFilterFocus(colDef.field, event); } }, [apiRef, colDef.field, hasFocus], ); const mouseEventsHandlers = React.useMemo( () => ({ onKeyDown: publish('headerFilterKeyDown'), onClick: publish('headerFilterClick'), onMouseDown: publish('headerFilterMouseDown', onMouseDown), }), [publish, onMouseDown], ); const filterModel = useGridSelector(apiRef, gridFilterModelSelector); const activeFiltersCount = filterModel.items?.filter(({ field }) => field === colDef.field).length ?? 0; return ( ); } export default function CustomHeaderFilterDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 100, }); return (
); } ``` :::success Similarly, you can use `slots.headerFilterMenu` if you need to customize the header filter menu. ::: ### Header filter cells with custom filter operators If you're using a [custom input component](/x/react-data-grid/filtering/customization/#custom-input-component) for the filter operator, you can use that same component in the header filter cell for a better user experience. The custom input component receives the `headerFilterMenu` and `clearButton` props that you can use to render the filter operator menu and **Clear filter** button, respectively. In the demo below, the **Rating** column uses a custom input, and you can filter by clicking on a star rating in the header filter cell: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Rating, { RatingProps } from '@mui/material/Rating'; import { DataGridPro, getGridNumericOperators, GridFilterInputValueProps, } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; function RatingInputValue( props: GridFilterInputValueProps & { headerFilterMenu: React.ReactNode; clearButton: React.ReactNode; }, ) { const { item, applyValue, focusElementRef, headerFilterMenu, clearButton } = props; const ratingRef: React.Ref = React.useRef(null); React.useImperativeHandle(focusElementRef, () => ({ focus: () => { ratingRef.current .querySelector(`input[value="${Number(item.value) || ''}"]`) .focus(); }, })); const handleFilterChange: RatingProps['onChange'] = (event, newValue) => { applyValue({ ...item, value: newValue }); }; return ( {headerFilterMenu} {clearButton} ); } export default function CustomHeaderFilterOperatorDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 100, visibleFields: VISIBLE_FIELDS, }); const columns = React.useMemo( () => data.columns.map((colDef) => { if (colDef.field === 'rating') { return { ...colDef, minWidth: 200, filterOperators: getGridNumericOperators() .filter((operator) => operator.value !== 'isAnyOf') .map((operator) => ({ ...operator, InputComponent: operator.InputComponent ? RatingInputValue : undefined, })), }; } return colDef; }), [data.columns], ); return (
); } ``` ### Header filter row height By default, the height of the header filter row is the same as the header row (represented by `columnHeaderHeight` prop). You can use the `headerFilterHeight` prop to change this: ```tsx ``` ## 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 ``` :::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/). ::: ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/api/charts/heatmap-plot.md # HeatmapPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Heatmap ## Import ```jsx import { HeatmapPlot } from '@mui/x-charts-pro/Heatmap'; // or import { HeatmapPlot } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/Heatmap/HeatmapPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/Heatmap/HeatmapPlot.tsx) --- # Source: https://mui.com/x/api/charts/heatmap-series.md # HeatmapSeries API ## Import ```jsx import { HeatmapSeries } from '@mui/x-charts-premium' // or import { HeatmapSeries } from '@mui/x-charts-pro' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | type | `'heatmap'` | - | Yes | | | data | `readonly HeatmapValueType[]` | - | No | | | dataKey | `string` | - | No | | | highlightScope | `HighlightScope` | - | No | | | id | `SeriesId` | - | No | | | label | `string \| ((location: 'tooltip' \| 'legend') => string)` | - | No | | | labelMarkType | `ChartsLabelMarkType` | - | No | | | valueFormatter | `SeriesValueFormatter` | - | No | | | xAxisId | `AxisId` | - | No | | | yAxisId | `AxisId` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/api/charts/heatmap-tooltip-content.md # HeatmapTooltipContent API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Heatmap ## Import ```jsx import { HeatmapTooltipContent } from '@mui/x-charts-pro/Heatmap'; // or import { HeatmapTooltipContent } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/Heatmap/HeatmapTooltip/HeatmapTooltipContent.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/Heatmap/HeatmapTooltip/HeatmapTooltipContent.tsx) --- # Source: https://mui.com/x/api/charts/heatmap-tooltip.md # HeatmapTooltip API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Heatmap ## Import ```jsx import { HeatmapTooltip } from '@mui/x-charts-pro/Heatmap'; // or import { HeatmapTooltip } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | anchor | `'node' \| 'pointer'` | `'pointer'` | No | | | anchorEl | `HTML element \| object \| func` | - | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | component | `elementType` | - | No | | | components (deprecated) | `{ Root?: elementType }` | `{}` | No | ⚠️ use the `slots` prop instead. This prop will be removed in a future major release. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | | componentsProps (deprecated) | `{ root?: func \| object }` | `{}` | No | ⚠️ use the `slotProps` prop instead. This prop will be removed in a future major release. [How to migrate](/material-ui/migration/migrating-from-deprecated-apis/). | | container | `(props, propName) => { if (props[propName] == null) { return new Error(`Prop '${propName}' is required but wasn't specified`); } if (typeof props[propName] !== 'object' \| \| props[propName].nodeType !== 1) { return new Error(`Expected prop '${propName}' to be of type Element`); } return null; } \| func` | - | No | | | disablePortal | `bool` | `false` | No | | | keepMounted | `bool` | `false` | No | | | modifiers | `Array<{ data?: object, effect?: func, enabled?: bool, fn?: func, name?: any, options?: object, phase?: 'afterMain' \| 'afterRead' \| 'afterWrite' \| 'beforeMain' \| 'beforeRead' \| 'beforeWrite' \| 'main' \| 'read' \| 'write', requires?: Array, requiresIfExists?: Array }>` | - | No | | | open | `bool` | - | No | | | placement | `'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top'` | `'bottom'` | No | | | popperOptions | `{ modifiers?: array, onFirstUpdate?: func, placement?: 'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top', strategy?: 'absolute' \| 'fixed' }` | `{}` | No | | | popperRef | `func \| { current?: { destroy: func, forceUpdate: func, setOptions: func, state: { attributes: object, elements: object, modifiersData: object, options: object, orderedModifiers: Array, placement: 'auto-end' \| 'auto-start' \| 'auto' \| 'bottom-end' \| 'bottom-start' \| 'bottom' \| 'left-end' \| 'left-start' \| 'left' \| 'right-end' \| 'right-start' \| 'right' \| 'top-end' \| 'top-start' \| 'top', rects: object, reset: bool, scrollParents: object, strategy: 'absolute' \| 'fixed', styles: object }, update: func } }` | - | No | | | position | `'bottom' \| 'left' \| 'right' \| 'top'` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | transition | `bool` | `false` | No | | | trigger | `'item' \| 'none'` | `'item'` | No | | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/Heatmap/HeatmapTooltip/HeatmapTooltip.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/Heatmap/HeatmapTooltip/HeatmapTooltip.tsx) --- # Source: https://mui.com/x/api/charts/heatmap.md # Source: https://mui.com/x/react-charts/heatmap.md --- title: React Heatmap chart productId: x-charts components: Heatmap, HeatmapPlot, HeatmapTooltip, HeatmapTooltipContent, FocusedHeatmapCell --- # Charts - Heatmap [](/x/introduction/licensing/#pro-plan 'Pro plan') Heatmap charts visually represents data with color variations to highlight patterns and trends across two dimensions. ## Overview Heatmaps are ideal for visualizing intensity variations across two categorical or continuous dimensions. They highlight areas of high and low concentration in a dataset, making it easy to detect trends, clusters, or anomalies at a glance. Each cell in a heatmap represents the intersection of two variables, with color encoding used to convey the magnitude of a numerical value. ```tsx import { interpolateBlues } from 'd3-scale-chromatic'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import { HeatmapValueType } from '@mui/x-charts-pro/models'; import bikeData from '../dataset/ParisBicycle.json'; const days = [ new Date(2025, 1, 24), new Date(2025, 1, 25), new Date(2025, 1, 26), new Date(2025, 1, 27), new Date(2025, 1, 28), new Date(2025, 2, 1), new Date(2025, 2, 2), ]; const hours = [ '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', ]; const shortDayFormatter = new Intl.DateTimeFormat('en-US', { weekday: 'short' }) .format; const dateFormatter = new Intl.DateTimeFormat('en-US', { weekday: 'short', day: 'numeric', month: 'short', year: 'numeric', }).format; export default function HeatmapDemo() { return ( Bicycle count: Paris - Rivoli street (West-East)
{ return context.location === 'tick' ? shortDayFormatter(value) : dateFormatter(value); }, tickLabelStyle: { angle: 45 }, height: 70, }, ]} yAxis={[ { data: hours, label: 'Hour of the day', tickLabelInterval: (_, index) => index % 2 === 0, valueFormatter: (value) => `${value}h`, width: 60, }, ]} series={[ { data: bikeData as unknown as HeatmapValueType[], label: 'Bicycle count', highlightScope: { highlight: 'item', fade: 'global' }, }, ]} zAxis={[ { colorMap: { max: 700, type: 'continuous', color: (t: number) => interpolateBlues(Math.sqrt(t)), }, }, ]} hideLegend={false} slotProps={{ legend: { direction: 'vertical', position: { vertical: 'top' }, sx: { height: 200 }, }, }} />
Data from{' '} Paris Data
); } ``` ## Basics Heatmap charts series must contain a `data` property containing an array of 3-tuples. The first two numbers in each tuple correspond to the x and y indexes of the cell, respectively. The third number is the value for the given cell. ```jsx ``` You can specify x and y ticks with the `xAxis` and `yAxis` props. ```tsx import Box from '@mui/material/Box'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import { data } from './dumbData'; export default function BasicHeatmap() { return ( ); } ``` ## Color mapping To customize the color mapping, use the `zAxis` configuration. You can either use the piecewise or continuous [color mapping](https://mui.com/x/react-charts/styling/#values-color). ```tsx import { interpolateBlues } from 'd3-scale-chromatic'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import { HeatmapValueType } from '@mui/x-charts-pro/models'; const dataset = [ { london: 59, paris: 57, newYork: 86, seoul: 21, month: 'January', }, { london: 50, paris: 52, newYork: 78, seoul: 28, month: 'February', }, { london: 47, paris: 53, newYork: 106, seoul: 41, month: 'March', }, { london: 54, paris: 56, newYork: 92, seoul: 73, month: 'April', }, { london: 57, paris: 69, newYork: 92, seoul: 99, month: 'May', }, { london: 60, paris: 63, newYork: 103, seoul: 144, month: 'June', }, { london: 59, paris: 60, newYork: 105, seoul: 319, month: 'July', }, { london: 65, paris: 60, newYork: 106, seoul: 249, month: 'August', }, { london: 51, paris: 51, newYork: 95, seoul: 131, month: 'September', }, { london: 60, paris: 65, newYork: 97, seoul: 55, month: 'October', }, { london: 67, paris: 64, newYork: 76, seoul: 48, month: 'November', }, { london: 61, paris: 70, newYork: 103, seoul: 25, month: 'December', }, ]; const data = dataset.flatMap( ({ london, paris, newYork, seoul }, monthIndex): HeatmapValueType[] => [ [0, monthIndex, london], [1, monthIndex, paris], [2, monthIndex, newYork], [3, monthIndex, seoul], ], ); const xData = ['London', 'Paris', 'NewYork', 'Seoul']; const yData = dataset.flatMap(({ month }) => month); export default function ColorConfig() { return ( ); } ``` ## Highlight You can choose to highlight the hovered element by setting `highlightScope.highlight` to `'item'`. To fade the other item, set `highlightScope.fade` to `'global'`. ```tsx import Box from '@mui/material/Box'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import { data } from './dumbData'; export default function HighlightHeatmap() { return ( ); } ``` By default highlighted/faded effect is obtained by applying the CSS property `filter: saturate(...)` to cells. To modify this styling, use the `heatmapClasses.highlighted` and `heatmapClasses.faded` CSS classes to override the applied style. In the following demo, we replace the highlight saturation by a border radius and reduce the saturation of the faded cells. ```tsx import Box from '@mui/material/Box'; import { Heatmap, heatmapClasses } from '@mui/x-charts-pro/Heatmap'; import { data } from './dumbData'; export default function HighlightClasses() { return ( ); } ``` ## Click event Use `onItemClick` to know which cell is clicked by user. The first argument is the click event. The second one is the item identifier. It contains the properties `xIndex` and `yIndex` that are the indexes of the clicked cell along the x- and y-axes respectively. If this cell has associated data, the `dataIndex` property indicates the position of the cell's data within the series' `data` array. ```tsx import * as React from 'react'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import type { HeatmapItemIdentifier } from '@mui/x-charts-pro/models'; import { data } from './dumbData'; export default function HeatmapCellClick() { const [cellData, setCellData] = React.useState(null); return ( index !== 5 && index !== 13), highlightScope: { highlight: 'item' }, }, ]} height={300} onItemClick={(event, params) => setCellData(params)} /> Click on the chart { setCellData(null); }} > ); } ``` ## Common features The heatmap shares several features with other charts. This section only explains the details that are specific to the heatmap. If you'd like to learn more about the shared features, you can visit their dedicated pages. ### Axes The Heatmap axes can be customized like any other chart axis. The available options are available in the [axis customization page](/x/react-charts/axis/#axis-customization). ### Tooltip The Heatmap has an item tooltip that can be customized as described in the [Tooltip documentation page](/x/react-charts/tooltip/). The only difference of the Heatmap Tooltip is its default content. You can import the default tooltip, or only its content as follows: ```js import { HeatmapTooltip, HeatmapTooltipContent } from '@mui/x-charts/Heatmap', ``` ### Legend The Heatmap comes with a legend which is by default the [ContinuousColorLegend](/x/react-charts/legend/#color-legend). To display it set `hideLegend` to `false`. You can modify it with `slots.legend` and `slotProps.legend`. ```tsx import Box from '@mui/material/Box'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import { data } from './dumbData'; export default function HeatmapLegend() { return ( ); } ``` ## Custom item ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { Heatmap } from '@mui/x-charts-pro/Heatmap'; import { data } from './dumbData'; function CustomCell(props: any) { const { x, y, width, height, ownerState, ...other } = props; return ( {ownerState.value} ); } export default function CustomItem() { return ( ); } ``` --- # Source: https://mui.com/x/react-charts/hooks.md --- title: Charts - Hooks productId: x-charts --- # Charts - Hooks The package provides a set of hooks to access chart data and utilities for building custom components. ## Available hooks The charts package provides several categories of hooks: ### Series and Data hooks - [**useSeries**](/x/react-charts/hooks/use-series/) - Access raw series data for all chart types - Specific series hooks for individual chart types (`useBarSeries`, `useLineSeries`, etc.) - [**useDataset**](/x/react-charts/hooks/use-dataset/) - Access the dataset used to populate series and axes data, only if `dataset` prop is used. ### Axes hooks - [**useAxes**](/x/react-charts/hooks/use-axes/) - Access axis configuration and properties for cartesian and polar charts - Cartesian axes hooks (`useXAxes`, `useYAxes`, `useXAxis`, `useYAxis`) - Polar axes hooks (`useRotationAxes`, `useRadiusAxes`, `useRotationAxis`, `useRadiusAxis`) ### Legend hooks - [**useLegend**](/x/react-charts/hooks/use-legend/) - Access formatted legend data for creating custom legend components ### Layout and positioning hooks - [**useDrawingArea**](/x/react-charts/hooks/use-drawing-area/) - Access the chart's drawing area dimensions and coordinates - [**useScale**](/x/react-charts/hooks/use-scale/) - Access D3 scale functions for coordinate transformations (`useXScale`, `useYScale`) ## Quick start All chart hooks are available from the `@mui/x-charts/hooks` import, with pro and premium packages also providing additional hooks. ```js import { useSeries, useLegend, ... } from '@mui/x-charts/hooks'; import { useSeries, useLegend, ... } from '@mui/x-charts-pro/hooks'; import { useSeries, useLegend, ... } from '@mui/x-charts-premium/hooks'; ``` ## Caveats All charts hooks must be used within a chart context. This means a component using those hook should follow one of the below mentioned structure: 1. a `slot` of a chart component 2. a child of a chart component 3. a child of the `` For example if you create a component `` that uses the `useLegend()` hook, you could use it as follow: ```jsx // ✅ Correct usage with slot API // ✅ Correct usage with chart component {/* useLegend works here */} // ✅ Correct usage with composition API {/* useLegend works here */} ``` ```jsx // ❌ Incorrect usage - outside chart context
{/* useLegend will not work here */}
``` --- # Source: https://mui.com/x/react-data-grid/demos/inventory.md # Data Grid - Inventory Dashboard An inventory dashboard for vendors showcasing product availability. --- # Source: https://mui.com/x/react-tree-view/rich-tree-view/items.md # Source: https://mui.com/x/react-tree-view/simple-tree-view/items.md --- productId: x-tree-view title: Simple Tree View - Items components: SimpleTreeView, TreeItem packageName: '@mui/x-tree-view' githubLabel: 'scope: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ --- # Simple Tree View - Items Learn how to add simple data to the Tree View component. ## Basics ```jsx import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; ``` `SimpleTreeView` receives its items directly as JSX children. ```tsx import Box from '@mui/material/Box'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; export default function BasicSimpleTreeView() { return ( ); } ``` ### Item identifier Each `TreeItem` must have a unique `itemId`. This is used internally to identify the item in various models and to track it across updates. ```tsx ``` ### Item label You must pass a `label` prop to each `TreeItem`, as shown below: ```tsx ``` ### Disabled items Use the `disabled` prop on `TreeItem` to disable interaction and focus: ```tsx import Box from '@mui/material/Box'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; export default function DisabledJSXItem() { return ( ); } ``` #### Focusable disabled items The demo below includes a switch that toggles the `disabledItemsFocusable` prop, which controls whether or not a disabled `TreeItem` can be focused. When this prop is set to false: - Disabled items will not receive focus when navigating with keyboard arrow keys—they next non-disabled item is focused instead. - Typing the first character of a disabled item's label will not move the focus to it. - Mouse or keyboard interactions will not expand or collapse disabled items. - Mouse or keyboard interactions will not select disabled items. - Shift + arrow keys will skip disabled items, and the next non-disabled item will be selected instead. - Programmatic focus will not focus disabled items. When it's set to true: - Disabled items will receive focus when navigating with keyboard arrow keys. - Typing the first character of a disabled item's label will move focus to it. - Mouse or keyboard interactions will not expand or collapse disabled items. - Mouse or keyboard interactions will not select disabled items. - Shift + arrow keys will not skip disabled items, but the disabled item will not be selected. - Programmatic focus will focus disabled items. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import Switch from '@mui/material/Switch'; import FormControlLabel from '@mui/material/FormControlLabel'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; export default function DisabledItemsFocusable() { const [disabledItemsFocusable, setDisabledItemsFocusable] = React.useState(false); const handleToggle = (event: React.ChangeEvent) => { setDisabledItemsFocusable(event.target.checked); }; return ( } label="Allow focusing disabled items" /> ); } ``` ## Track item clicks Use the `onItemClick` prop to track the clicked item: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; export default function OnItemClick() { const [lastClickedItem, setLastClickedItem] = React.useState(null); return ( {lastClickedItem == null ? 'No item click recorded' : `Last clicked item: ${lastClickedItem}`} setLastClickedItem(itemId)}> ); } ``` ## Imperative API To use the `apiRef` object, you need to initialize it using the `useSimpleTreeViewApiRef()` hook as follows: ```tsx const apiRef = useSimpleTreeViewApiRef(); return ; ``` When your component first renders, `apiRef.current` is `undefined`. After the initial render, `apiRef` holds methods to interact imperatively with the Tree View. ### Get an item's DOM element by ID Use the `getItemDOMElement()` API method to get an item's DOM element by its ID. ```ts const itemElement = apiRef.current.getItemDOMElement( // The id of the item to get the DOM element of itemId, ); ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Button from '@mui/material/Button'; import { SimpleTreeView } from '@mui/x-tree-view/SimpleTreeView'; import { TreeItem } from '@mui/x-tree-view/TreeItem'; import { useSimpleTreeViewApiRef } from '@mui/x-tree-view/hooks'; export default function ApiMethodGetItemDOMElement() { const apiRef = useSimpleTreeViewApiRef(); const handleScrollToChartsCommunity = (event: React.SyntheticEvent) => { apiRef.current!.focusItem(event, 'charts-community'); apiRef .current!.getItemDOMElement('charts-community') ?.scrollIntoView({ block: 'nearest' }); }; return (
); } ``` --- # Source: https://mui.com/x/react-charts/label.md --- title: Charts - Label productId: x-charts components: BarChart, ScatterChart, LineChart, PieChart --- # Charts - Label Customize how series and data points are labeled in charts. A label is the text that identifies a series or data point in a chart, appearing in locations such as the legend, tooltip, or directly on chart elements. You can set a series label by passing a string to the `label` property of a series. The label appears in different locations such as the legend and tooltip. :::info The Pie chart has specific behavior described in [Pie chart labels](#pie-chart-labels) below. ::: ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function BasicLabel() { return ( ); } const props = { height: 300, xAxis: [{ data: ['A', 'B', 'C'] }], yAxis: [{ width: 50 }], }; ``` ## Conditional formatting The `label` property accepts a function that lets you change the label content based on location. The function receives `location` as its first argument, which can have the following values: - `'legend'`: Format the label in the [Legend](/x/react-charts/legend/) - `'tooltip'`: Format the label in the [Tooltip](/x/react-charts/tooltip/) ```tsx import { BarChart } from '@mui/x-charts/BarChart'; export default function FunctionLabel() { return ( `${location} label` }, ]} /> ); } const props = { height: 300, xAxis: [{ data: ['A', 'B', 'C'] }], yAxis: [{ width: 50 }], }; ``` ## Pie chart labels The [Pie chart](/x/react-charts/pie/) behaves differently due to its nature. It has labels per slice instead of per series, and provides one additional location where labels can be rendered. Instead of receiving the `label` as part of the series, it receives it as part of the `data` set inside a series. The `location` argument can have the following values: - `'legend'`: Format the label in the [Legend](/x/react-charts/legend/) - `'tooltip'`: Format the label in the [Tooltip](/x/react-charts/tooltip/) - `'arc'`: Format the [Arc label](/x/react-charts/pie/#labels) when `arcLabel` is set to `'label'` ```tsx import { PieChart } from '@mui/x-charts/PieChart'; export default function PieLabel() { return ( `${location}+A` }, { id: 1, value: 15, label: (location) => `${location}+B` }, { id: 2, value: 20, label: (location) => `${location}+C` }, ], type: 'pie', arcLabel: 'label', }, ]} /> ); } const props = { width: 200, height: 200, }; ``` --- # Source: https://mui.com/x/react-data-grid/layout.md # Data Grid - Layout The Data Grid offers multiple layout modes. :::error The Data Grid has no intrinsic dimensions: you must set the dimensions using one of the approaches below or else it may not display correctly. By default, the Data Grid fills the space of its parent container, so that container must have intrinsic dimensions. In other words, if the container has no child elements, then it still must have non-zero dimensions. ::: ## Flex parent container :::success When to use: - You want the Data Grid to take its content height, but with a minimum or maximum height constraints. - You want the Data Grid height to be dynamic, and use row virtualization when rows do not fit the Data Grid viewport. When not to use: - You want the Data Grid to always take the height of its content, with no vertical scrollbar, and no row virtualization. In this case, use the [`autoHeight`](/x/react-data-grid/layout/#auto-height) prop. ::: The Data Grid can be placed inside a flex container with `flex-direction: column`. Without setting the minimum and maximum height, the Data Grid takes as much space as it needs to display all rows. :::warning Consider setting `maxHeight` on the flex parent container, otherwise row virtualization will not be able to improve performance by limiting the number of elements rendered in the DOM. ::: ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function FlexGrid() { const [nbRows, setNbRows] = React.useState(3); const removeRow = () => setNbRows((x) => Math.max(0, x - 1)); const addRow = () => setNbRows((x) => Math.min(100, x + 1)); const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return (
); } ``` ### Minimum and maximum height In the demo below, the Data Grid is placed inside a flex container with a minimum height of `200px` and a maximum height of `400px` and adapts its height when the number of rows changes. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import Typography from '@mui/material/Typography'; const minHeight = 200; const maxHeight = 400; export default function MinMaxHeightGrid() { const [nbRows, setNbRows] = React.useState(3); const removeRow = () => setNbRows((x) => Math.max(0, x - 1)); const addRow = () => setNbRows((x) => Math.min(100, x + 1)); const containerRef = React.useRef(null); const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return (
{/** Visualize max and min container height */}
); } function ContainerMeasurements({ containerRef, }: { containerRef: React.RefObject; }) { const [containerHeight, setContainerHeight] = React.useState(0); React.useEffect(() => { const target = containerRef.current; const observer = new ResizeObserver((entries) => { setContainerHeight(entries[0].contentRect.height); }); if (target) { observer.observe(target); } return () => { observer.disconnect(); }; }, [containerRef]); const label = `${containerHeight}px`; if (containerHeight === 0) { return null; } return ( ({ position: 'absolute', top: 0, left: -20, width: 20, height: containerHeight, borderColor: theme.palette.text.secondary, borderStyle: 'dashed', borderTopWidth: 1, borderRightWidth: 0, borderBottomWidth: 1, borderLeftWidth: 1, })} > ({ position: 'absolute', top: '50%', left: 0, transform: 'rotate(180deg) translate(0, 50%)', writingMode: 'vertical-lr', color: theme.palette.text.secondary, textWrap: 'nowrap', lineHeight: 1.2, fontSize: '15px', })} > {label} ); } ``` ## Percentage dimensions When using percentages (%) for height or width, make sure that the Data Grid's parent container has intrinsic dimensions. Browsers adjust the element based on a percentage of its parent's size. If the parent has no size, the percentage will be zero. ## Predefined dimensions You can predefine dimensions for the parent of the Data Grid. ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function FixedSizeGrid() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 5, maxColumns: 6, }); return (
); } ``` ## Overlay height When data grid has no content, overlays (such as ["Loading"](/x/react-data-grid/overlays/#loading-overlay) or ["No rows"](/x/react-data-grid/overlays/#no-rows-overlay)) take the height of two rows by default. To customize the overlay height, use the `--DataGrid-overlayHeight` CSS variable. ```tsx import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; import { styled } from '@mui/material/styles'; const StyledGridOverlay = styled('div')(({ theme }) => ({ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', '& .no-rows-primary': { fill: '#3D4751', ...theme.applyStyles('light', { fill: '#AEB8C2', }), }, '& .no-rows-secondary': { fill: '#1D2126', ...theme.applyStyles('light', { fill: '#E8EAED', }), }, })); function CustomNoRowsOverlay() { return ( No rows ); } export default function GridOverlayHeight() { return ( ); } ``` ## Auto height :::success When to use: - You don't need to set a minimum or maximum height for the Data Grid - You want the Data Grid to always take the height of its content, with no vertical scrollbar, and no row virtualization. When not to use: - You need to set a minimum or maximum height for the Data Grid, or want the Data Grid height to be dynamic. In this case, use the [flex parent container](/x/react-data-grid/layout/#flex-parent-container) instead. ::: The `autoHeight` prop enables the Data Grid to adjust its size based on its content. This means that the Data Grid's height will be determined by the number of rows, ensuring that all rows will be visible to the user simultaneously. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function AutoHeightGrid() { const [nbRows, setNbRows] = React.useState(3); const removeRow = () => setNbRows((x) => Math.max(0, x - 1)); const addRow = () => setNbRows((x) => Math.min(100, x + 1)); const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return ( ); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/server-side-data/lazy-loading.md # Source: https://mui.com/x/react-tree-view/rich-tree-view/lazy-loading.md --- productId: x-tree-view title: Rich Tree View - Lazy loading components: RichTreeViewPro, TreeItem packageName: '@mui/x-tree-view-pro' githubLabel: 'scope: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ --- # Rich Tree View - Lazy loading [](/x/introduction/licensing/#pro-plan 'Pro plan') Lazy load the data from your Tree View. ## Basic usage To dynamically load data from the server, including lazy-loading of children, you must create a data source and pass the `dataSource` prop to `RichTreeView`. The data source also requires the `getChildrenCount()` attribute to handle tree data. `getChildrenCount()` returns the number of children for the item. If the children count is not available, but there are children present, it returns `-1`. The `items` prop serves as the initial state. ```tsx import Box from '@mui/material/Box'; import { randomInt, randomName, randomId, randomBoolean, } from '@mui/x-data-grid-generator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { initialItems, ItemType } from './items'; const fetchData = async (): Promise => { const length: number = randomInt(2, 10); const rows = Array.from({ length }, () => ({ id: randomId(), label: randomName({}, {}), ...(randomBoolean() ? { childrenCount: length } : {}), })); return new Promise((resolve) => { setTimeout(() => { resolve(rows); }, 1000); }); }; export default function LazyLoadingInitialState() { return ( item?.childrenCount as number, getTreeItems: fetchData, }} /> ); } ``` If you want to dynamically load all items of `RichTreeView`, you can pass an empty array to the `items` prop, and the `getTreeItems()` method will be called on the first render. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; import { randomInt, randomName, randomId, randomBoolean, } from '@mui/x-data-grid-generator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; type ItemType = TreeViewBaseItem<{ id: string; label: string; childrenCount?: number; }>; function getSliderAriaValueText(value: number) { return `${value}°C`; } export default function BasicLazyLoading() { const [latency, setLatency] = React.useState(1000); const handleSliderChange = (_event: Event, newLatency: number | number[]) => { setLatency(newLatency as number); }; const fetchData = async (): Promise => { const length: number = randomInt(5, 10); const rows = Array.from({ length }, () => ({ id: randomId(), label: randomName({}, {}), ...(randomBoolean() ? { childrenCount: length } : {}), })); return new Promise((resolve) => { setTimeout(() => { resolve(rows); }, latency); }); }; return ( Loading latency: {latency} (ms) item?.childrenCount as number, getTreeItems: fetchData, }} /> ); } ``` ### Using react-query The following demo uses `fetchQuery` from `react-query` to load data. ```tsx import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { randomInt, randomName, randomId, randomBoolean, } from '@mui/x-data-grid-generator'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { QueryClient, QueryClientProvider, useQueryClient, } from '@tanstack/react-query'; const queryClient = new QueryClient(); type ItemType = TreeViewBaseItem<{ id: string; label: string; childrenCount?: number; }>; const items: ItemType[] = []; const fetchData = async (_parentId?: string): Promise => { const length: number = randomInt(5, 10); const rows = Array.from({ length }, () => ({ id: randomId(), label: randomName({}, {}), ...(randomBoolean() ? { childrenCount: length } : {}), })); return new Promise((resolve) => { setTimeout(() => { resolve(rows); }, 1000); }); }; export function FetchChildren() { const myQueryClient = useQueryClient(); const fetchTreeItems = async (parentId?: string) => { const queryKey = parentId ? ['treeItems', parentId] : ['treeItems', 'root']; const data = await myQueryClient.fetchQuery({ queryKey, queryFn: () => fetchData(parentId), }); return data; }; return ( item?.childrenCount as number, getTreeItems: fetchTreeItems, }} /> ); } export default function FetchingWithReactQuery() { return ( ); } ``` ## Data caching ### Custom cache To provide a custom cache, use the `dataSourceCache` prop, which may be created from scratch or based on a third-party cache library. This prop accepts a generic interface of type `DataSourceCache`. The following demo uses `QueryClient` from `react-query` as a data source cache. ```tsx import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { randomInt, randomName, randomId, randomBoolean, } from '@mui/x-data-grid-generator'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { DataSourceCache } from '@mui/x-tree-view/utils'; const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60 * 60, }, }, }); const cache: DataSourceCache = { set: (key: string, value) => { queryClient.setQueryData([key], value); }, get: (key: string) => { return queryClient.getQueryData([key]); }, clear: () => { queryClient.clear(); }, }; type ItemType = TreeViewBaseItem<{ id: string; label: string; childrenCount?: number; }>; const fetchData = async (_parentId?: string): Promise => { const length: number = randomInt(5, 10); const rows = Array.from({ length }, () => ({ id: randomId(), label: randomName({}, {}), ...(randomBoolean() ? { childrenCount: length } : {}), })); return new Promise((resolve) => { setTimeout(() => { resolve(rows); }, 1000); }); }; export function FetchChildren() { return ( item?.childrenCount as number, getTreeItems: fetchData, }} dataSourceCache={cache} /> ); } export default function ReactQueryCache() { return ( ); } ``` ### Customize the cache lifetime The `DataSourceCacheDefault` has a default time to live (`ttl`) of 5 minutes. To customize it, pass the `ttl` option in milliseconds to the `DataSourceCacheDefault` constructor, and then pass it as the `dataSourceCache` prop. ```tsx import Box from '@mui/material/Box'; import { randomInt, randomName, randomId } from '@mui/x-data-grid-generator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { DataSourceCacheDefault } from '@mui/x-tree-view/utils'; const fetchData = async (): Promise< TreeViewBaseItem<{ id: string; label: string; childrenCount?: number; }>[] > => { const rows = Array.from({ length: 10 }, () => ({ id: randomId(), label: randomName({}, {}), ...(randomInt(0, 1) ? { childrenCount: 10 } : {}), })); return new Promise((resolve) => { setTimeout(() => { resolve(rows); }, 1000); }); }; const lowTTLCache = new DataSourceCacheDefault({ ttl: 1000 * 10 }); // 10 seconds export default function LowTTLCache() { return ( item?.childrenCount as number, getTreeItems: fetchData, }} dataSourceCache={lowTTLCache} /> ); } ``` ## Error management ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import { randomName, randomId } from '@mui/x-data-grid-generator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { initialItems, ItemType } from './items'; export default function ErrorManagement() { const [failRequests, setFailRequests] = React.useState(false); const fetchData = async (): Promise => { const rows = Array.from({ length: 10 }, () => ({ id: randomId(), label: randomName({}, {}), childrenCount: 10, })); // make the promise fail conditionally return new Promise((resolve, reject) => { setTimeout(() => { if (failRequests) { reject(new Error('Error fetching data')); } else { resolve(rows); } }, 1000); }); }; return ( item?.childrenCount as number, getTreeItems: fetchData, }} /> ); } ``` ## Lazy loading and label editing To store the updated item labels on your server, use the `onItemLabelChange()` callback function. Changes to the label are not automatically updated in the `dataSourceCache` and must be updated manually. The demo below shows you how to update the cache once a label is changed so the changes are reflected in the tree. ```tsx import Box from '@mui/material/Box'; import { randomInt, randomName, randomId } from '@mui/x-data-grid-generator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { TreeViewBaseItem, TreeViewItemId } from '@mui/x-tree-view/models'; import { DataSourceCacheDefault } from '@mui/x-tree-view/utils'; import { useRichTreeViewProApiRef } from '@mui/x-tree-view-pro/hooks'; const fetchData = async (): Promise< TreeViewBaseItem<{ id: string; label: string; childrenCount?: number; }>[] > => { const rows = Array.from({ length: 10 }, () => ({ id: randomId(), label: randomName({}, {}), ...(randomInt(0, 1) ? { childrenCount: 10 } : {}), })); return new Promise((resolve) => { setTimeout(() => { resolve(rows); }, 1000); }); }; const customCache = new DataSourceCacheDefault({}); // 10 seconds export default function LazyLoadingAndLabelEditing() { const apiRef = useRichTreeViewProApiRef(); const handleItemLabelChange = (itemId: TreeViewItemId, newLabel: string) => { const parentId = apiRef.current?.getParentId(itemId) || 'root'; const cachedData = customCache.get(parentId); if (cachedData !== undefined && cachedData !== -1) { const newCache = cachedData.map((item) => { const newItem = item; if (item.id === itemId) { newItem.label = newLabel; } return newItem; }); customCache.set(parentId, newCache); } }; return ( item?.childrenCount as number, getTreeItems: fetchData, }} dataSourceCache={customCache} /> ); } ``` ## Imperative API To use the `apiRef` object, you need to initialize it using the `useRichTreeViewProApiRef()` hook as follows: ```tsx const apiRef = useRichTreeViewProApiRef(); return ; ``` When your component first renders, `apiRef.current` is `undefined`. After the initial render, `apiRef` holds methods to interact imperatively with `RichTreeView`. ### Update the children of an item Use the `updateItemChildren()` API method to fetch the children of an item: ```ts apiRef.current.updateItemChildren( // The id of the item to update the children of // null if the entire tree needs to be reloaded itemId, ); ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import IconButton from '@mui/material/IconButton'; import CachedIcon from '@mui/icons-material/Cached'; import { randomInt, randomName, randomId, randomBoolean, } from '@mui/x-data-grid-generator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { TreeItemContent, TreeItemIconContainer, TreeItemGroupTransition, TreeItemLabel, TreeItemRoot, TreeItemCheckbox, TreeItemProps, } from '@mui/x-tree-view/TreeItem'; import { TreeViewBaseItem, TreeViewCancellableEventHandler, } from '@mui/x-tree-view/models'; import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; import { useTreeItem } from '@mui/x-tree-view/useTreeItem'; type ItemType = TreeViewBaseItem<{ id: string; label: string; childrenCount?: number; }>; const LATENCY_MS = 300; const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: TreeItemProps, ref: React.Ref, ) { const { id, itemId, label, disabled, children, ...other } = props; const { getContextProviderProps, getRootProps, getContentProps, getIconContainerProps, getCheckboxProps, getLabelProps, getGroupTransitionProps, getDragAndDropOverlayProps, status, publicAPI, } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref, }); const refreshChildren: TreeViewCancellableEventHandler = ( event, ) => { event.defaultMuiPrevented = true; publicAPI.updateItemChildren!(itemId); }; return ( {status.expandable && status.expanded && ( )} {children && } ); }); export default function ApiMethodUpdateItemChildren() { const fetchData = async (): Promise => { const length: number = randomInt(5, 10); const rows = Array.from({ length }, () => ({ id: randomId(), label: randomName({}, {}), ...(randomBoolean() ? { childrenCount: length } : {}), })); return new Promise((resolve) => { setTimeout(() => { resolve(rows); }, LATENCY_MS); }); }; return ( item?.childrenCount as number, getTreeItems: fetchData, }} slots={{ item: CustomTreeItem }} /> ); } ``` --- # Source: https://mui.com/x/api/charts/legend-item-params.md # LegendItemParams API ## Import ```jsx import { LegendItemParams } from '@mui/x-charts-premium' // or import { LegendItemParams } from '@mui/x-charts-pro' // or import { LegendItemParams } from '@mui/x-charts' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | color | `string` | - | Yes | | | id | `number \| string` | - | Yes | | | label | `string` | - | Yes | | | markType | `ChartsLabelMarkProps['type']` | - | Yes | | | maxValue | `number \| Date \| null` | - | Yes | | | minValue | `number \| Date \| null` | - | Yes | | | seriesId | `SeriesId` | - | Yes | | | dataIndex | `number` | - | No | | | itemId | `PieItemId` | - | No | | | type | `ChartSeriesType` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/react-charts/legend.md --- title: Charts - Legend productId: x-charts components: ChartsLegend, ChartsText, ContinuousColorLegend, PiecewiseColorLegend --- # Charts - Legend Legend is the UI element mapping symbols and colors to the series' label. ## Basic display In chart components, the legend links series with `label` properties and their color. ```tsx import { ScatterChart } from '@mui/x-charts/ScatterChart'; import dataset from '../dataset/random/scatterParallel.json'; export default function BasicLegend() { return ( ); } ``` ## Toggle visibility You can enable interactive visibility toggling by setting the `toggleVisibilityOnClick` prop to `true`. When enabled, clicking on a legend item hides or shows the corresponding series or data item in the chart. Hidden items are visually indicated in the legend with reduced opacity. ```tsx import * as React from 'react'; import { BarChart } from '@mui/x-charts/BarChart'; import { dataset, valueFormatter } from '../dataset/weather'; const chartSetting = { xAxis: [ { label: 'rainfall (mm)', }, ], height: 300, }; export default function ToggleSeriesVisibility() { return ( ); } ``` ### Visibility change callback You can listen to visibility changes using the `onHiddenItemsChange` prop on the chart component. This callback receives an array of hidden item identifiers whenever the visibility state changes. To set the initial hidden items, you can use the `initialHiddenItems` prop. The following demo shows a line chart where you can toggle series' visibility and see the count of currently visible series. ```tsx import * as React from 'react'; import { LineChart } from '@mui/x-charts/LineChart'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import type { VisibilityIdentifier } from '@mui/x-charts/plugins'; const series = [ { id: 'series-a', data: [20, 30, 25, 40, 30], label: 'Series A' }, { id: 'series-b', data: [15, 25, 20, 35, 20], label: 'Series B' }, { id: 'series-c', data: [10, 20, 15, 30, 25], label: 'Series C' }, ]; export default function VisibilityOnChange() { const [hiddenItems, setHiddenItems] = React.useState([]); const visibleCount = series.length - hiddenItems.length; return ( setHiddenItems(newHiddenItems)} /> Visible series: {visibleCount} / {series.length} ); } ``` :::info The `toggleVisibilityOnClick` prop can be combined with the `onItemClick` handler. When both are in use, the `onItemClick` callback is called first, followed by `onHiddenItemsChange`. ::: ### Controlled visibility You can control the visibility state externally using the `hiddenItems` prop. This prop accepts an array of item identifiers that should be hidden in the chart. Different chart types have different identifier formats: - All identifiers require a `type` field indicating the series type (for example, `'line'`, `'bar'`, `'pie'`, etc.). - Use `VisibilityIdentifier` type to build such identifiers. - It accepts a series type as generic parameter, and can be used as `VisibilityIdentifier<'line'>` in order to narrow the allowed values. The demo below shows how to control which items are visible using buttons. ```tsx import * as React from 'react'; import { PieChart } from '@mui/x-charts/PieChart'; import Stack from '@mui/material/Stack'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import type { VisibilityIdentifier } from '@mui/x-charts/plugins'; const data = [ { value: 10, label: 'Series A' }, { value: 15, label: 'Series B' }, { value: 20, label: 'Series C' }, ]; export default function ControlledVisibility() { const [hiddenItems, setHiddenItems] = React.useState< VisibilityIdentifier<'pie'>[] >([{ type: 'pie', seriesId: 'custom', dataIndex: 0 }]); const handleShowAll = () => { setHiddenItems([]); }; const handleHideAll = () => { setHiddenItems([ { type: 'pie', seriesId: 'custom', dataIndex: 0 }, { type: 'pie', seriesId: 'custom', dataIndex: 1 }, { type: 'pie', seriesId: 'custom', dataIndex: 2 }, ]); }; const handleShowOnlyA = () => { setHiddenItems([ { type: 'pie', seriesId: 'custom', dataIndex: 1 }, { type: 'pie', seriesId: 'custom', dataIndex: 2 }, ]); }; const handleToggleChange = ( _event: React.MouseEvent, newValue: string | null, ) => { if (newValue === 'all') { handleShowAll(); } else if (newValue === 'none') { handleHideAll(); } else if (newValue === 'onlyA') { handleShowOnlyA(); } }; const getCurrentValue = () => { const allVisible = hiddenItems.length === 0; const allHidden = hiddenItems.length === data.length; const onlyAVisible = hiddenItems.length === 2 && hiddenItems[0].dataIndex === 1 && hiddenItems[1].dataIndex === 2; if (allVisible) { return 'all'; } if (allHidden) { return 'none'; } if (onlyAVisible) { return 'onlyA'; } return null; }; return ( Controlled Highlighting Show All Hide All Show Only A setHiddenItems(newIdentifiers)} /> ); } ``` ## Customization This section explains how to customize the legend using classes and properties. ### Dimensions Much of the customization can be done using CSS properties. There is a main class for the legend container, `.MuiChartsLegend-root`. Alternatively the `legendClasses` variable can be used if using CSS-in-JS to target the elements. Each legend item is composed of two main elements: the `mark` and the `label`. The example below explains how it is possible to customize some parts the legend. And shows how to use both the `legendClasses` variable and the CSS class directly. ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { PieChart } from '@mui/x-charts/PieChart'; import { legendClasses } from '@mui/x-charts/ChartsLegend'; const data = [ { id: 0, value: 10, label: 'Series A' }, { id: 1, value: 15, label: 'Series B' }, { id: 2, value: 20, label: 'Series C' }, { id: 3, value: 10, label: 'Series D' }, { id: 4, value: 15, label: 'Series E' }, { id: 5, value: 20, label: 'Series F' }, { id: 6, value: 10, label: 'Series G' }, ]; export default function LegendDimension() { return ( ( )} getCode={({ props }) => { return `import { PieChart } from '@mui/x-charts/PieChart'; import { legendClasses } from '@mui/x-charts/ChartsLegend'; `; }} /> ); } ``` ### Position The legend can either be displayed in a `'vertical'` or `'horizontal'` layout controlled with the `direction` property. It can also be moved with the `position: { vertical, horizontal }` property which defines how the legend aligns itself in the parent container. - `vertical` can be `'top'`, `'middle'`, or `'bottom'`. - `horizontal` can be `'left'`, `'middle'`, or `'right'`. By default, the legend is placed above the charts. The position management relies on a [grid-template](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/grid-template). If you create a custom legend component, you need to set the CSS property `grid-area` to `'legend'` to get your component correctly placed. :::warning The `position` property is only available in the `slotProps`, but not in the `` props. In the second case, you are free to place the legend where you want. ::: ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { PieChart } from '@mui/x-charts/PieChart'; const data = [ { id: 0, value: 10, label: 'Series A' }, { id: 1, value: 15, label: 'Series B' }, { id: 2, value: 20, label: 'Series C' }, { id: 3, value: 10, label: 'Series D' }, { id: 4, value: 15, label: 'Series E' }, { id: 5, value: 20, label: 'Series F' }, { id: 6, value: 10, label: 'Series G' }, { id: 7, value: 15, label: 'Series H' }, { id: 8, value: 20, label: 'Series I' }, { id: 9, value: 10, label: 'Series J' }, { id: 10, value: 15, label: 'Series K' }, { id: 11, value: 20, label: 'Series L' }, { id: 12, value: 10, label: 'Series M' }, { id: 13, value: 15, label: 'Series N' }, { id: 14, value: 20, label: 'Series O' }, ]; export default function LegendPosition() { return ( ( )} getCode={({ props }) => { return `import { PieChart } from '@mui/x-charts/PieChart'; `; }} /> ); } ``` ### Hiding You can hide the legend with the `hideLegend` prop of the Chart. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { PieChart } from '@mui/x-charts/PieChart'; const series = [ { data: [ { id: 0, value: 10, label: 'series A' }, { id: 1, value: 15, label: 'series B' }, { id: 2, value: 20, label: 'series C' }, ], }, ]; export default function HiddenLegend() { const [isHidden, setIsHidden] = React.useState(false); const Toggle = ( setIsHidden(event.target.checked)} />} label="hide the legend" labelPlacement="end" sx={{ margin: 'auto' }} /> ); return ( {Toggle} ); } ``` ### Label styling Changing the `label` style can be done by targeting the root component's font properties. To change the `mark` color or shape, the `fill` class is used instead. Keep in mind that the `mark` is an SVG element, so the `fill` property is used to change its color. ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { PieChart } from '@mui/x-charts/PieChart'; import { labelMarkClasses } from '@mui/x-charts/ChartsLabel'; const data = [ { id: 0, value: 10, label: 'Series A' }, { id: 1, value: 15, label: 'Series B' }, { id: 2, value: 20, label: 'Series C' }, { id: 3, value: 10, label: 'Series D' }, ]; export default function LegendTextStyling() { return ( ( )} getCode={({ props }) => { return `import { PieChart } from '@mui/x-charts/PieChart'; import { labelMarkClasses } from '@mui/x-charts/ChartsLabel'; `; }} /> ); } ``` ### Change mark shape To change the mark shape, you can use the `labelMarkType` property of the series item. For the `pie` series, the `labelMarkType` property is available for each of the pie slices too. ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { BarChart } from '@mui/x-charts/BarChart'; const series = [ { id: 0, data: [10], label: 'Series A' }, { id: 1, data: [15], label: 'Series B' }, { id: 2, data: [20], label: 'Series C' }, { id: 3, data: [10], label: 'Series D' }, ]; export default function LegendMarkType() { return ( ( ({ ...seriesItem, labelMarkType: props.markType, }))} xAxis={[{ data: ['A'] }]} height={200} /> )} getCode={({ props }) => { return `import { BarChart } from '@mui/x-charts/BarChart'; ({ ...seriesItem, labelMarkType: '${props.markType}', })) } /> `; }} /> ); } ``` #### Custom shapes For more advanced use cases, you can also provide a component to the `labelMarkType` property of each series to fully customize the mark. ```tsx import { BarChart } from '@mui/x-charts/BarChart'; import { ChartsLabelCustomMarkProps } from '@mui/x-charts/ChartsLabel'; function HTMLCircle({ className, color }: ChartsLabelCustomMarkProps) { return (
); } function SVGDiamond({ className, color }: ChartsLabelCustomMarkProps) { return ( ); } export default function LegendCustomLabelMark() { return ( ); } ``` Passing a component to `labelMarkType` affects not only the legend but other places where the label mark is shown, such as tooltips. Customizing the mark shape of a pie chart depending on the series is slightly different. You can find how to do it in [this example](/x/react-charts/pie-demo/#pie-chart-with-custom-mark-in-legend-and-tooltip). To ensure compatibility with [gradients and patterns](/x/react-charts/styling/#gradients-and-patterns), consider using SVG instead of HTML in the `labelMarkType`. ### Scrollable legend The legend can be made scrollable by setting the `overflowY` for vertical legends or `overflowX` for horizontal legends. Make sure that the legend container has a fixed height or width to enable scrolling. ```tsx import Stack from '@mui/material/Stack'; import { PieChart } from '@mui/x-charts/PieChart'; const series = [ { data: [ { id: 0, value: 10, label: 'Series A' }, { id: 1, value: 15, label: 'Series B' }, { id: 2, value: 20, label: 'Series C' }, { id: 3, value: 10, label: 'Series D' }, { id: 4, value: 15, label: 'Series E' }, { id: 5, value: 20, label: 'Series F' }, { id: 6, value: 10, label: 'Series G' }, { id: 7, value: 15, label: 'Series H' }, { id: 8, value: 20, label: 'Series I' }, { id: 9, value: 10, label: 'Series J' }, { id: 10, value: 15, label: 'Series K' }, { id: 11, value: 20, label: 'Series L' }, { id: 12, value: 10, label: 'Series M' }, { id: 13, value: 15, label: 'Series N' }, { id: 14, value: 20, label: 'Series O' }, ], }, ]; export default function ScrollableLegend() { return ( ); } ``` ### Series styling You can use CSS to style the series in the legend. Each legend item has a `data-series` attribute where its value is the ID of the series it represents. ```tsx import { LineChart, LineChartProps, lineElementClasses, markElementClasses, } from '@mui/x-charts/LineChart'; import { legendClasses } from '@mui/x-charts/ChartsLegend'; import { ChartsLabelCustomMarkProps, labelMarkClasses, } from '@mui/x-charts/ChartsLabel'; const monthlySalesData = [ { month: 'Jan', productA: 120, productB: 90 }, { month: 'Feb', productA: 130, productB: 100 }, { month: 'Mar', productA: 125, productB: 110 }, { month: 'Apr', productA: 150, productB: 95 }, { month: 'May', productA: 160, productB: 105 }, { month: 'Jun', productA: 170, productB: 115 }, { month: 'Jul', productA: 165, productB: 120 }, { month: 'Aug', productA: 175, productB: 130 }, { month: 'Sep', productA: 180, productB: 125 }, { month: 'Oct', productA: 190, productB: 135 }, { month: 'Nov', productA: 200, productB: 140 }, { month: 'Dec', productA: 210, productB: 145 }, ]; const settings = { series: [ { data: monthlySalesData.map((d) => d.productA), label: 'Product A', id: 'a', labelMarkType: Line, }, { data: monthlySalesData.map((d) => d.productB), label: 'Product B', id: 'b', labelMarkType: Line, }, ], xAxis: [ { scaleType: 'point', data: monthlySalesData.map((d) => d.month), }, ], yAxis: [{ width: 50, label: 'Sales' }], height: 300, margin: { right: 24 }, } satisfies LineChartProps; export default function LegendStyleSeries() { return ( ); } function Line({ className, color }: ChartsLabelCustomMarkProps) { return ( ); } ``` ### Custom component For advanced customization, you can create your own legend with `useLegend`. This hook returns the items that the default legend would plot so you can focus on the rendering. This demo also shows how to use `labelMarkType` together with a custom legend to create a legend with custom shapes. This approach uses slots to render the legend items. Another demo in [HTML components docs](/x/react-charts/components/#html-components) shows how to use it with composition. ```tsx import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { useTheme } from '@mui/material/styles'; import { useLegend } from '@mui/x-charts/hooks'; import { LineChart, lineElementClasses } from '@mui/x-charts/LineChart'; import { ChartsLabelCustomMarkProps, ChartsLabelMark, } from '@mui/x-charts/ChartsLabel'; function LineWithMark({ color, className }: ChartsLabelCustomMarkProps) { return ( ); } function DashedLine({ color, className }: ChartsLabelCustomMarkProps) { return ( ); } function MyCustomLegend() { const { items } = useLegend(); return ( {items.map((item) => { const { label, id, color, seriesId, markType } = item; return ( {`${label}`} ); })} ); } const dataset = [ { month: 'Jan', '1991_2020_avg': 4.1, 2023: 3.9 }, { month: 'Fev', '1991_2020_avg': 4.7, 2023: 8.9 }, { month: 'Mar', '1991_2020_avg': 7.5, 2023: 9.5 }, { month: 'Apr', '1991_2020_avg': 10.6, 2023: 11.5 }, { month: 'May', '1991_2020_avg': 13.8, 2023: 15.5 }, { month: 'Jun', '1991_2020_avg': 16.7, 2023: 16.4 }, { month: 'Jul', '1991_2020_avg': 18.9, 2023: 19.5 }, { month: 'Aug', '1991_2020_avg': 18.8, 2023: 20.5 }, { month: 'Sep', '1991_2020_avg': 15.8, 2023: 16.4 }, { month: 'Oct', '1991_2020_avg': 11.9, 2023: 13.2 }, { month: 'Nov', '1991_2020_avg': 7.6, 2023: 8.1 }, { month: 'Dec', '1991_2020_avg': 4.7, 2023: 6.1 }, ]; export default function CustomLegend() { const theme = useTheme(); return ( ); } ``` ## Color legend To display legend associated to a [colorMap](https://mui.com/x/react-charts/styling/#values-color), you can use: - `` if you're using `colorMap.type='continuous'` - `` if you're using `colorMap.type='piecewise'`. Then it is possible to override the `legend` slot to display the wanted legend, or use the [composition API](https://mui.com/x/react-charts/composition/) to add as many legends as needed. ```tsx import { LineChart, LineChartProps } from '@mui/x-charts/LineChart'; import { PiecewiseColorLegend } from '@mui/x-charts/ChartsLegend'; import Stack from '@mui/material/Stack'; import { dataset } from './tempAnomaly'; const data: LineChartProps = { dataset, series: [ { label: 'Global temperature anomaly relative to 1961-1990', dataKey: 'anomaly', showMark: false, valueFormatter: (value) => `${value?.toFixed(2)}°`, }, ], xAxis: [ { scaleType: 'time', dataKey: 'year', disableLine: true, valueFormatter: (value) => value.getFullYear().toString(), colorMap: { type: 'piecewise', thresholds: [new Date(1961, 0, 1), new Date(1990, 0, 1)], colors: ['blue', 'gray', 'red'], }, }, ], yAxis: [ { disableLine: true, disableTicks: true, valueFormatter: (value: number) => `${value}°`, }, ], grid: { horizontal: true }, height: 300, margin: { top: 20, right: 20 }, }; export default function VeryBasicColorLegend() { return ( ); } ``` ### Select data To select the color mapping to represent, use the following props: - `axisDirection` can be `'x'`, `'y'`, or `'z'`. It indicates which axis contain the `colorMap` definition. - `axisId` The id of the axis to use in case the selected direction contains multiple ones. ```tsx import Typography from '@mui/material/Typography'; import { LineChart } from '@mui/x-charts/LineChart'; import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; import { PiecewiseColorLegend } from '@mui/x-charts/ChartsLegend'; import Stack from '@mui/material/Stack'; import { dataset } from './tempAnomaly'; export default function BasicColorLegend() { return ( Global temperature anomaly relative to 1961-1990 average `${value?.toFixed(2)}°`, }, ]} xAxis={[ { scaleType: 'time', dataKey: 'year', disableLine: true, valueFormatter: (value) => value.getFullYear().toString(), colorMap: { type: 'piecewise', thresholds: [new Date(1961, 0, 1), new Date(1990, 0, 1)], colors: ['blue', 'gray', 'red'], }, }, ]} yAxis={[ { disableLine: true, disableTicks: true, valueFormatter: (value: number) => `${value}°`, }, ]} grid={{ horizontal: true }} height={300} slotProps={{ legend: { axisDirection: 'x', direction: 'vertical', }, }} slots={{ legend: PiecewiseColorLegend, }} > ); } ``` ### Position This component position is done exactly the same way as the [legend for series](#position). ### Label position The labels can be positioned in relation to the marks or gradient with the `labelPosition` prop. The general values accepted are `'start'`, `'end'`, `'extremes'`. While the piecewise legend has two more options, `'inline-start'`, and `'inline-end'`. - With `direction='horizontal'`, using `'start'` places the labels above the visual marker, while `end` places them below. - When `direction='vertical'`, is `'start'` or `'end'` the labels are positioned `left` and `right` of the visual markers, respectively. - With the `'extremes'` value, the labels are positioned at both the beginning and end of the visual marker. For the piecewise legend, two extra values are accepted - With `direction='horizontal'`, using `'inline-start'` and `'inline-end'` positions the labels inline with the marker. - When `direction='vertical'`, it works the same as `'start'` and `'end'`. ```tsx import { interpolateRdYlBu } from 'd3-scale-chromatic'; import { ContinuousColorLegend, piecewiseColorDefaultLabelFormatter, PiecewiseColorLegend, PiecewiseLabelFormatterParams, } from '@mui/x-charts/ChartsLegend'; import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; import { ChartsAxesGradients } from '@mui/x-charts/internals'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import Divider from '@mui/material/Divider'; export default function LegendLabelPositions() { const piecewiseFormatter = (params: PiecewiseLabelFormatterParams) => params.index === 0 || params.index === params.length ? piecewiseColorDefaultLabelFormatter(params) : ''; return ( `${value}°`, colorMap: { type: 'continuous', min: -0.5, max: 1.5, color: (t) => interpolateRdYlBu(1 - t), }, }, ]} xAxis={[ { valueFormatter: (value: number) => `${value}°`, colorMap: { type: 'piecewise', thresholds: [0, 1.5], colors: [ interpolateRdYlBu(0.9), interpolateRdYlBu(0.5), interpolateRdYlBu(0.1), ], }, }, ]} > Continuous Horizontal div': { flex: 1 } }} >
start
end
extremes
Vertical div': { flex: 1, height: '100%', display: 'flex', flexDirection: 'column', }, '& .MuiContinuousColorLegend-root': { flex: 1 }, }} >
start
end
extremes
Piecewise Horizontal div': { flex: 1 } }} >
start
end
extremes
inline-start
inline-end
Vertical div': { flex: 1, height: '100%', display: 'flex', flexDirection: 'column', }, }} >
start
end
extremes
inline-start
inline-end
); } ``` ### Continuous color mapping To modify the shape of the gradient, use the `length` and `thickness` props. The `length` can either be a number (in px) or a percentage string. The `"100%"` corresponds to the parent dimension. To format labels use the `minLabel`/`maxLabel`. They accept either a string to display. Or a function `({value, formattedValue}) => string`. It is also possible to reverse the gradient with the `reverse` prop. ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { interpolateRdYlBu } from 'd3-scale-chromatic'; import { LineChart } from '@mui/x-charts/LineChart'; import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; import { ContinuousColorLegend } from '@mui/x-charts/ChartsLegend'; import { dataset } from './tempAnomaly'; export default function ContinuousInteractiveDemo() { return ( ( `${value?.toFixed(2)}°`, }, ]} xAxis={[ { scaleType: 'time', dataKey: 'year', disableLine: true, valueFormatter: (value) => value.getFullYear().toString(), }, ]} yAxis={[ { disableLine: true, disableTicks: true, valueFormatter: (value: number) => `${value}°`, colorMap: { type: 'continuous', min: -0.5, max: 1.5, color: (t) => interpolateRdYlBu(1 - t), }, }, ]} grid={{ horizontal: true }} height={300} slots={{ legend: ContinuousColorLegend }} slotProps={{ legend: { axisDirection: 'y', direction: props.direction, thickness: props.thickness, labelPosition: props.labelPosition, reverse: props.reverse, sx: { [props.direction === 'horizontal' ? 'width' : 'height']: `${props.length}${props.direction === 'horizontal' ? '%' : 'px'}`, }, }, }} > )} getCode={({ props }) => { return `import { ContinuousColorLegend } from '@mui/x-charts/ChartsLegend'; `; }} /> ); } ``` ### Piecewise color mapping The piecewise Legend is quite similar to the series legend. It accepts the same props for [customization](#dimensions). To override labels generated by default, provide a `labelFormatter` prop. It takes the min/max of the piece and returns the label. Values can be `null` for the first and last pieces. And returning `null` removes the piece from the legend. Returning an empty string removes any label, but still display the `mark`. ```ts labelFormatter = ({ index, length, min, max, formattedMin, formattedMax }) => string | null; ``` The `markType` can be changed with the `markType` prop. Since the color values are based on the axis, and not the series, the `markType` has to be set directly on the legend. ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { LineChart } from '@mui/x-charts/LineChart'; import { piecewiseColorDefaultLabelFormatter, PiecewiseColorLegend, } from '@mui/x-charts/ChartsLegend'; import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; import { dataset } from './tempAnomaly'; export default function PiecewiseInteractiveDemo() { return ( ( `${value?.toFixed(2)}°`, }, ]} xAxis={[ { scaleType: 'time', dataKey: 'year', disableLine: true, valueFormatter: (value) => value.getFullYear().toString(), colorMap: { type: 'piecewise', thresholds: [new Date(1961, 0, 1), new Date(1990, 0, 1)], colors: ['blue', 'gray', 'red'], }, }, ]} yAxis={[ { disableLine: true, disableTicks: true, valueFormatter: (value: number) => `${value}°`, }, ]} grid={{ horizontal: true }} height={300} slots={{ legend: PiecewiseColorLegend, }} slotProps={{ legend: { axisDirection: 'x', direction: props.direction, markType: props.markType, labelPosition: props.labelPosition, labelFormatter: props.onlyShowExtremes ? (params) => params.index === 0 || params.index === params.length ? piecewiseColorDefaultLabelFormatter(params) : '' : undefined, sx: { padding: props.padding, }, }, }} > )} getCode={({ props }) => { return `import { PiecewiseColorLegend, piecewiseColorDefaultLabelFormatter, } from '@mui/x-charts/ChartsLegend'; \n params.index === 0 || params.index === params.length\n ? piecewiseColorDefaultLabelFormatter(params) \n : ''" : ''} }, }} /> `; }} /> ); } ``` ## Click event You can pass an `onItemClick` function to the `ChartsLegend` or `PiecewiseColorLegend` components to handle click events. They both provide the following signature. ```js const clickHandler = ( event, // The click event. context, // An object that identifies the clicked item. index, // The index of the clicked item. ) => {}; ``` The `context` object contains different properties depending on the legend type. Click the legend items to see their content. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined'; import { ChartsLegend, PiecewiseColorLegend } from '@mui/x-charts/ChartsLegend'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { ChartDataProvider } from '@mui/x-charts/ChartDataProvider'; const pieSeries = [ { type: 'pie', id: 'series-1', data: [ { label: 'Pie A', id: 'P1-A', value: 400 }, { label: 'Pie B', id: 'P2-B', value: 300 }, ], }, ] as const; const barSeries = [ { type: 'bar', id: 'series-1', label: 'Series 1', data: [0, 1, 2], }, { type: 'bar', id: 'series-2', label: 'Series 2', data: [0, 1, 2], }, ] as const; const lineSeries = [ { type: 'line', id: 'series-1', label: 'Series 1', data: [0, 1, 2], }, { type: 'line', id: 'series-2', label: 'Series 2', data: [0, 1, 2], }, ] as const; export default function LegendClick() { const [itemData, setItemData] = React.useState(); return ( Chart Legend setItemData([context, index])} /> Pie Chart Legend setItemData([context, index])} /> Piecewise Color Legend setItemData([context, index])} /> Click on the chart { // @ts-ignore setItemData(null); }} > ); } ``` --- # Source: https://mui.com/x/react-date-pickers/lifecycle.md --- productId: x-date-pickers title: Components lifecycle githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Components lifecycle This page explains when the onChange, onAccept, and onClose callbacks are called. ## Lifecycle on simple fields :::info The information below is applicable to standalone fields (when rendering ``), as well as to pickers for field editing (when rendering `` and using the input to edit the value). ::: The field components have an internal state controlling the visible value. It will only call the `onChange` callback when: - the user completes all sections of a field. The value reflects the field. - when the date is not parseable, the `onChange` prop receives an `Invalid Date` (for example, if the [year is less than "100"](https://github.com/iamkun/dayjs/issues/1237) in case of `dayjs`). - the user cleans at least one or all sections of a completed field. The value equals `null`. The example below shows the last value received by `onChange`. ```tsx import * as React from 'react'; import { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DateField } from '@mui/x-date-pickers/DateField'; export default function LifeCycleDateFieldEmpty() { const [value, setValue] = React.useState(null); return ( Value: {value == null ? 'null' : value.format('L')} ); } ``` ## Lifecycle on range fields [](/x/introduction/licensing/#pro-plan 'Pro plan') On range fields (`SingleInputDateRangeField` / `MultiInputDateRangeField` / ... ), `onChange` is called if the date you are modifying matches one of the conditions above, regardless of the other date state. The example below shows the last value received by `onChange`. Note how changing the value of the start date section will call `onChange` even if the end date is empty or partially filled. ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { DemoContainer } from '@mui/x-date-pickers/internals/demo'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { SingleInputDateRangeField } from '@mui/x-date-pickers-pro/SingleInputDateRangeField'; import { DateRange } from '@mui/x-date-pickers-pro/models'; export default function LifeCycleDateRangeField() { const [value, setValue] = React.useState>([ dayjs('2022-04-17'), null, ]); return ( Value:{' '} {value.map((date) => (date == null ? 'null' : date.format('L'))).join(' – ')} ); } ``` ## Lifecycle on pickers: "onClose" ### When is "onClose" called? :::info In all the below scenarios, the picker closes when `onClose` is called, except if you are controlling the `open` prop. ::: #### When the last view is completed When a selection in the last view is made, `onClose` will be called only if the `closeOnSelect` prop is equal to `true`. The default value of `closeOnSelect` depends on the component: - Date Picker and Date Range Picker: `true` on desktop and `false` on mobile variants; - Time Picker, Date Time Picker, and Date Time Range Picker: `false` on desktop and mobile variants. Here are a few examples: :::info The examples below are using the desktop and mobile variants of the pickers, but the behavior is exactly the same when using the responsive variant (`DatePicker`, `TimePicker`, ...) on a mobile or desktop environment. ::: - ```tsx ``` - Default `views` prop: `['year', 'day']` - Default `closeOnSelect` prop: `true` **Behavior:** The picker will close when selecting the day. - ```tsx ``` - Default `views` prop: `['year', 'day']` - Explicit `closeOnSelect` prop: `false` **Behavior:** The picker will not close when selecting a day. The user will have to click on the _OK_ action to close it. :::success If you want to set `closeOnSelect` to `false` on a desktop picker, you should consider enabling the action bar to let the user validate the value: ```tsx ``` ::: - ```tsx ``` - Default `views` prop: `['year', 'day']` - Default `closeOnSelect` prop: `false` **Behavior:** The picker will not close when selecting a day. The user will have to click on the _OK_ action to close it. - ```tsx ``` - Explicit `views` prop: `['day', 'month', 'year']` - Default `closeOnSelect` prop: `true` **Behavior:** The picker will close when selecting the year. - ```tsx ``` - Default `views` prop: `['hours', 'minutes']` (plus a `meridiem` view if the locale is in 12-hours format) - Default `closeOnSelect` prop: `false` **Behavior:** The picker will not close when selecting the minutes or meridiem (if a 12-hour clock is used). :::info You don't have to fill all the views for the picker to close automatically. For example, on the `DatePicker`, the `year` and `month` views are not in the default workflow since they are before the opening view (`day`), so the picker will close even if you never went to those views. ::: #### When the picker is manually closed Pressing Escape or clicking outside the picker will close the picker. #### When a value is selected using the action bar Clicking on any built-in button of the action bar will close the picker. #### When a shortcut is picked Clicking on a shortcut will close the picker, except if the `changeImportance` property has been set to `"set"` instead of the default value `"accept"`. You can find more information [in the dedicated doc section](/x/react-date-pickers/shortcuts/#behavior-when-selecting-a-shortcut). ## Lifecycle on pickers: "onChange" ### Usage The `onChange` callback is called whenever the current value changes. If you don't want to listen to the intermediary steps, consider using the [`onAccept` prop](/x/react-date-pickers/lifecycle/#lifecycle-on-pickers-quot-onaccept-quot) instead. ```tsx setValue(value)} /> ``` :::success You can use the second argument passed to the `onChange` callback to get the validation error associated with the current value: ```tsx { setValue(value); if (context.validationError == null) { runSomeLogic(); } }} /> ``` ::: ### When is "onChange" called? #### When the field calls "onChange" When editing your value through the input(s) of your field, the picker will just re-publish the `onChange` callback. Take a look at the [dedicated section](/x/react-date-pickers/lifecycle/#lifecycle-on-simple-fields) for more information. #### When the user interacts with the view If the component is controlled (if it has a `value` prop that isn't undefined), clicking on a value will call `onChange` if the value to publish is different from the current value (for example clicking on the already selected day in the `day` view will not call `onChange`). If the component is not controlled, the behavior is the same, except if no value has ever been published, in which case clicking on the current value will fire `onChange` (for example clicking on the already selected day in the `day` view will call `onChange` if `onChange` has never been called before). Some views can decide not to call `onChange` for some value modifications. The most common example is the mobile time views (using the [`TimeClock`](/x/react-date-pickers/time-clock/) component). The `onChange` is only fired once when the dragging (touching) of the clock hand ends even though the UI updates on each position change. #### When a value is selected using the action bar If the component is controlled (if it has a `value` prop that isn't undefined), clicking on any built-in actions will call `onChange` if the value to publish is different from the current value. If the component is not controlled, the behavior is the same, except for the _Clear_, _Today_, and _OK_ actions that will call `onChange` if no value has ever been published, even if the current value equals the value to publish. #### When a shortcut is picked Clicking on a shortcut will call `onChange`. You can find more information [in the dedicated doc section](/x/react-date-pickers/shortcuts/#behavior-when-selecting-a-shortcut). ## Lifecycle on pickers: "onAccept" ### Usage The `onAccept` callback lets you get the final value selected by the user without caring about the intermediary steps. ```tsx sendValueToServer(value)} /> ``` The `onAccept` callback receives a second argument `context` with extra information about why and how the value was accepted. - `validationError`: the validation result of the accepted value. - `source`: string that indicates where a change or acceptance originated from. The value is one of: - `'field'`: committed from the input field (typing, paste, arrow keys, clear, Enter, etc.). - `'view'`: any interaction inside the picker's view - `'unknown'`: unspecified or third‑party triggers. - `shortcut` (optional): the shortcut metadata when the value was accepted via a shortcut selection. For custom error handling, you can use the `validationError` property of the `context` object. ```tsx { if (context.validationError == null) { runSomeLogic(); } }} /> ``` The `source` property allows you to implement different behaviors depending on the source of the acceptance. ```tsx { if (context.validationError != null) { return; // ignore invalid values } switch (context.source) { case 'view': analytics.track('date_accepted_from_view', { value: newValue, shortcut: context.shortcut?.id, }); break; case 'field': analytics.track('date_accepted_from_field', { value: newValue }); break; case 'unknown': default: analytics.track('date_accepted_from_unknown', { value: newValue }); } }} /> ``` ### When is "onAccept" called? #### When the last view is completed When a selection in the last view is made, `onAccept` will be called only if the `closeOnSelect` prop is equal to `true` and the value has been modified since the last time `onAccept` was called. The default value of `closeOnSelect` depends on the component used: - Date Picker and Date Range Picker: `true` on desktop and `false` on mobile variants; - Time Picker, Date Time Picker, and Date Time Range Picker: `false` on desktop and mobile variants. Here are a few examples: :::info The examples below are using the desktop and mobile variants of the pickers, but the behavior is exactly the same when using the responsive variant (`DatePicker`, `TimePicker`, ...) on a mobile or desktop environment. ::: - ```tsx ``` - Default `views` prop: `['year', 'day']` - Default `closeOnSelect` prop: `true` **Behavior:** The picker will call `onAccept` when selecting the day. - ```tsx ``` - Default `views` prop: `['year', 'day']` - Explicit `closeOnSelect` prop: `false` **Behavior:** The picker will not call `onAccept` when selecting a value. :::success If you want to set `closeOnSelect` to `false` on a desktop picker, you should consider enabling the action bar to let the user validate the value: ```tsx ``` ::: - ```tsx ``` - Explicit `views` prop: `['day', 'month', 'year']` - Default `closeOnSelect` prop: `true` **Behavior:** The picker will call `onAccept` when selecting the year. - ```tsx ``` - Default `views` prop: `['hours', 'minutes']` (plus a `meridiem` view if the locale is in 12-hours format) - Default `closeOnSelect` prop: `false` **Behavior:** The picker will not call `onAccept` when selecting the minutes or meridiem (if a 12-hour clock is used). #### When the picker is manually closed When the user presses Escape or clicks outside the picker, `onAccept` is called with: - the current value, if the last view has been completed - the last accepted value, if the last view has not been completed #### When a value is selected using the action bar If the component is controlled (if it has a `value` prop that isn't undefined), clicking on any built-in actions will call `onAccept` if the value to publish is different from the current value. If the component is not controlled, the behavior is the same, except for the _Clear_, _Today_, and _OK_ actions that will call `onAccept` if no value has ever been published, even if the current value equals the value to publish. #### When a shortcut is picked Clicking on a shortcut will call `onAccept`, except if the `changeImportance` property has been set to `"set"` instead of `"accept"`. You can find more information [in the dedicated doc section](/x/react-date-pickers/shortcuts/#behavior-when-selecting-a-shortcut). ## Classic scenarios ### "DatePicker" on desktop #### Controlled "DesktopDatePicker": basic usage ```tsx setValue(newValue)} /> ``` **Action n°1:** Opening the picker - Opens the picker on the `day` view **Action n°2:** Clicking on a day - Fires `onClose` (and closes the picker if the `open` prop is not controlled) - Fires `onChange` with the selected day (keeps the time of the previous value) - Fires `onAccept` with the selected day (keeps the time of the previous value) #### Controlled "DesktopDatePicker": picking year, month and day ```tsx setValue(newValue)} views={['year', 'month', 'day']} /> ``` **Action n°1:** Opening the picker - Opens the picker on the `day` view **Action n°2:** Switch to the `year` view on the header **Action n°3:** Clicking on a year - Fires `onChange` with the selected year (keeps the month, date and time of the previous value) - Moves to the `month` view **Action n°4:** Clicking on a month - Fires `onChange` with the selected month (keeps the date and time of the previous value) - Moves to the `day` view **Action n°4:** Clicking on a day - Fires `onClose` (and closes the picker if the `open` prop is not controlled) - Fires `onChange` with the selected day (keeps the time of the previous value) - Fires `onAccept` with the selected day (keeps the time of the previous value) ### "DatePicker" on mobile #### Controlled "MobileDatePicker": basic usage ```tsx setValue(newValue)} /> ``` **Action n°1:** Opening the picker - Opens the picker on the `day` view **Action n°2:** Clicking on a day - Fires `onChange` with the selected day (keeps the time of the previous value) **Action n°3:** Clicking on the _OK_ action - Fires `onClose` (and closes the picker if the `open` prop is not controlled) - Fires `onAccept` with the selected day (keeps the time of the previous value) ## Only update for valid values The `onChange` callback receives a 2nd parameter (context object) containing the validation error associated with the current value. If you want to update your state only when the value is valid, you can ignore any `onChange` call with a non-null `validationError`. In the example below, `onChange` will only be called if the date is valid and its year is 2022: ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; export default function LifeCycleIgnoreInvalidValue() { const [value, setValue] = React.useState(null); return ( { if (context.validationError == null) { setValue(newValue); } }} minDate={dayjs('2022-01-01')} maxDate={dayjs('2022-12-31')} /> Value: {value == null ? 'null' : value.format('L')} ); } ``` ## Server interaction If the selected value is used to interact with the server, you might want to avoid sending all the intermediate states. Especially if the user is setting the date using the keyboard arrow interaction. In such a case, the recommended UI is to add a button for validating the form. If for some reason, you need to send the data to the server without having the user pressing a validation button, you can debounce the `onChange` as follows. The following demo shows how to extend the Date Field component by adding an `onAccept` prop, which is a debounced version of `onChange`. You can find more information about the `onAccept` prop [in the dedicated doc section](/x/react-date-pickers/lifecycle/#lifecycle-on-pickers-quot-onaccept-quot). ```tsx import * as React from 'react'; import dayjs, { Dayjs } from 'dayjs'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import Divider from '@mui/material/Divider'; import Button from '@mui/material/Button'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { DateField, DateFieldProps } from '@mui/x-date-pickers/DateField'; import useControlled from '@mui/utils/useControlled'; type DisplayEventsProps = { logs: (Dayjs | null)[]; title: string; }; function DisplayEvents(props: DisplayEventsProps) { const { logs, title } = props; return ( {title} {logs .map( (value) => `- ${ // eslint-disable-next-line no-nested-ternary value === null ? 'null' : value.isValid() ? value.format('DD/MM/YYYY') : 'Invalid Date' }`, ) .join('\n')} ); } // debounce function function debounce(func: (...arg: any) => void, wait = 500) { let timeout: ReturnType; function debounced(...args: any) { const later = () => { func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); } debounced.clear = () => { clearTimeout(timeout); }; return debounced; } function DateFieldWithAccept( props: DateFieldProps & { onAccept: (value: Dayjs | null) => void }, ) { const { value: valueProp, defaultValue, onAccept, onChange, ...other } = props; const [value, setValue] = useControlled({ name: 'FieldAcceptValue', state: 'value', controlled: valueProp, default: defaultValue, }); // Debounced function needs to be memoized to keep the same timeout between each render. // For the same reason, the `onAccept` needs to be wrapped in useCallback. const debouncedOnAccept = React.useMemo( () => debounce(onAccept, 1000), [onAccept], ); return ( { setValue(newValue); debouncedOnAccept(newValue); onChange?.(newValue, context); }} {...other} /> ); } export default function ServerInteraction() { const [logsFromOnChange, setLogsFromOnChange] = React.useState<(Dayjs | null)[]>( [], ); const [logsFromOnAccept, setLogsFromOnAccept] = React.useState<(Dayjs | null)[]>( [], ); const onAccept = React.useCallback((newValue: Dayjs | null) => { setLogsFromOnAccept((prev) => [newValue, ...prev]); }, []); return ( { setLogsFromOnChange((prev) => [newValue, ...prev]); }} sx={{ width: 150 }} label="debounced field" defaultValue={dayjs('2022-04-17')} /> ); } ``` ### Source values in `context.source` Pickers expose a simplified `context.source` string that indicates where a change or acceptance originated from. The value is one of: - `'field'`: committed from the input field (typing, paste, arrow keys, clear, Enter, etc.). - `'view'`: any interaction inside the picker's view - `'unknown'`: unspecified or third‑party triggers. Example usage: ```tsx { if (context.validationError) return; switch (context.source) { case 'view': analytics.track('date_accept_from_view', { value, shortcut: context.shortcut?.id, }); break; case 'field': analytics.track('date_accept_from_field', { value }); break; case 'unknown': default: analytics.track('date_accept_from_unknown', { value }); } }} /> ``` --- # Source: https://mui.com/x/api/charts/line-chart-pro.md # LineChartPro API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Charts - Export - [Charts - Lines](/x/react-charts/lines/) - Charts - Zoom and pan ## Import ```jsx import { LineChartPro } from '@mui/x-charts-pro/LineChartPro'; // or import { LineChartPro } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | axisHighlight | `{ x?: 'band' \| 'line' \| 'none', y?: 'band' \| 'line' \| 'none' }` | `{ x: 'line' }` | No | | | brushConfig | `{ enabled?: bool, preventHighlight?: bool, preventTooltip?: bool }` | - | No | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | disableAxisListener | `bool` | `false` | No | | | disableLineItemHighlight | `bool` | - | No | | | experimentalFeatures | `{ preferStrictDomainInLineCharts?: bool }` | - | No | | | grid | `{ horizontal?: bool, vertical?: bool }` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'line' }>` | - | No | | | hideLegend | `bool` | - | No | | | highlightedAxis | `Array<{ axisId: number \| string, dataIndex: number }>` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'line' }>` | - | No | | | initialZoom | `Array<{ axisId: number \| string, end: number, start: number }>` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onAreaClick | `func` | - | No | | | onAxisClick | `function(event: MouseEvent, data: null \| ChartsAxisData) => void` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onHighlightedAxisChange | `function(axisItems: Array) => void` | - | No | | | onLineClick | `func` | - | No | | | onMarkClick | `func` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | onZoomChange | `function(zoomData: Array) => void` | - | No | | | showToolbar | `bool` | `false` | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex?: number, seriesId: number \| string, type: 'line' }` | - | No | | | width | `number` | - | No | | | xAxis | `Array<{ axis?: 'x', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool }>` | - | No | | | yAxis | `Array<{ axis?: 'y', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number, zoom?: { filterMode?: 'discard' \| 'keep', maxEnd?: number, maxSpan?: number, minSpan?: number, minStart?: number, panning?: bool, slider?: { enabled?: bool, preview?: bool, showTooltip?: 'always' \| 'hover' \| 'never', size?: number }, step?: number } \| bool }>` | - | No | | | zAxis | `Array<{ colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, id?: string, max?: number, min?: number }>` | - | No | | | zoomData | `Array<{ axisId: number \| string, end: number, start: number }>` | - | No | | | zoomInteractionConfig | `{ pan?: Array<'drag' \| 'pressAndDrag' \| 'wheel' \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'drag' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'pressAndDrag' } \| { allowedDirection?: 'x' \| 'xy' \| 'y', pointerMode?: any, requiredKeys?: Array, type: 'wheel' }>, zoom?: Array<'brush' \| 'doubleTapReset' \| 'pinch' \| 'tapAndDrag' \| 'wheel' \| { pointerMode?: any, requiredKeys?: Array, type: 'wheel' } \| { pointerMode?: any, requiredKeys?: array, type: 'pinch' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'tapAndDrag' } \| { pointerMode?: 'mouse' \| 'touch', requiredKeys?: Array, type: 'doubleTapReset' } \| { pointerMode?: any, requiredKeys?: array, type: 'brush' }> }` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | area | `AnimatedArea` | - | The component that renders the area. | | axisLabel | `ChartsText` | - | Custom component for axis label. | | axisLine | `'line'` | - | Custom component for the axis main line. | | axisTick | `'line'` | - | Custom component for the axis tick. | | axisTickLabel | `ChartsText` | - | Custom component for tick label. | | baseButton | `undefined` | - | | | baseDivider | `undefined` | - | | | baseIconButton | `undefined` | - | | | baseMenuItem | `undefined` | - | | | baseMenuList | `undefined` | - | | | basePopper | `undefined` | - | | | baseTooltip | `undefined` | - | | | exportIcon | `ChartsExportIcon` | - | Icon displayed on the toolbar's export button. | | legend | `ChartsLegend` | - | Custom rendering of the legend. | | line | `LineElementPath` | - | The component that renders the line. | | lineHighlight | `undefined` | - | | | loadingOverlay | `ChartsLoadingOverlay` | - | Overlay component rendered when the chart is in a loading state. | | mark | `undefined` | - | | | noDataOverlay | `ChartsNoDataOverlay` | - | Overlay component rendered when the chart has no data to display. | | toolbar | `ChartsToolbar` | - | Custom component for the toolbar. | | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | | zoomInIcon | `ChartsZoomInIcon` | - | Icon displayed on the toolbar's zoom in button. | | zoomOutIcon | `ChartsZoomOutIcon` | - | Icon displayed on the toolbar's zoom out button. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/LineChartPro/LineChartPro.tsx) --- # Source: https://mui.com/x/api/charts/line-chart.md # LineChart API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Label](/x/react-charts/label/) - [Charts - Line demos](/x/react-charts/line-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { LineChart } from '@mui/x-charts/LineChart'; // or import { LineChart } from '@mui/x-charts'; // or import { LineChart } from '@mui/x-charts-pro'; // or import { LineChart } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | axisHighlight | `{ x?: 'band' \| 'line' \| 'none', y?: 'band' \| 'line' \| 'none' }` | `{ x: 'line' }` | No | | | brushConfig | `{ enabled?: bool, preventHighlight?: bool, preventTooltip?: bool }` | - | No | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | disableAxisListener | `bool` | `false` | No | | | disableLineItemHighlight | `bool` | - | No | | | experimentalFeatures | `{ preferStrictDomainInLineCharts?: bool }` | - | No | | | grid | `{ horizontal?: bool, vertical?: bool }` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'line' }>` | - | No | | | hideLegend | `bool` | - | No | | | highlightedAxis | `Array<{ axisId: number \| string, dataIndex: number }>` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'line' }>` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onAreaClick | `func` | - | No | | | onAxisClick | `function(event: MouseEvent, data: null \| ChartsAxisData) => void` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onHighlightedAxisChange | `function(axisItems: Array) => void` | - | No | | | onLineClick | `func` | - | No | | | onMarkClick | `func` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | showToolbar | `bool` | `false` | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex?: number, seriesId: number \| string, type: 'line' }` | - | No | | | width | `number` | - | No | | | xAxis | `Array<{ axis?: 'x', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func } \| { axis?: 'x', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, height?: number, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'bottom' \| 'none' \| 'top', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelMinGap?: number, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func }>` | - | No | | | yAxis | `Array<{ axis?: 'y', barGapRatio?: number, categoryGapRatio?: number, classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'band', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { colors: Array, type: 'ordinal', unknownColor?: string, values?: Array } \| { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, groups?: Array<{ getValue: func, tickLabelStyle?: object, tickSize?: number }>, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, offset?: number, ordinalTimeTicks?: Array<'biweekly' \| 'days' \| 'hours' \| 'months' \| 'quarterly' \| 'weeks' \| 'years' \| { format: func, getTickNumber: func, isTick: func }>, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'point', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'log', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, constant?: number, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'symlog', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'pow', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'sqrt', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'time', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number \| { valueOf: func }, min?: number \| { valueOf: func }, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'utc', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number } \| { axis?: 'y', classes?: object, colorMap?: { color: Array \| func, max?: Date \| number, min?: Date \| number, type: 'continuous' } \| { colors: Array, thresholds: Array, type: 'piecewise' }, data?: array, dataKey?: string, disableLine?: bool, disableTicks?: bool, domainLimit?: 'nice' \| 'strict' \| func, hideTooltip?: bool, id?: number \| string, ignoreTooltip?: bool, label?: string, labelStyle?: object, max?: number, min?: number, offset?: number, position?: 'left' \| 'none' \| 'right', reverse?: bool, scaleType?: 'linear', slotProps?: object, slots?: object, sx?: Array \| func \| object, tickInterval?: 'auto' \| array \| func, tickLabelInterval?: 'auto' \| func, tickLabelPlacement?: 'middle' \| 'tick', tickLabelStyle?: object, tickMaxStep?: number, tickMinStep?: number, tickNumber?: number, tickPlacement?: 'end' \| 'extremities' \| 'middle' \| 'start', tickSize?: number, tickSpacing?: number, valueFormatter?: func, width?: number }>` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). > Any other props supplied will be provided to the root element (native element). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | area | `AnimatedArea` | - | The component that renders the area. | | axisLabel | `ChartsText` | - | Custom component for axis label. | | axisLine | `'line'` | - | Custom component for the axis main line. | | axisTick | `'line'` | - | Custom component for the axis tick. | | axisTickLabel | `ChartsText` | - | Custom component for tick label. | | baseButton | `undefined` | - | | | baseIconButton | `undefined` | - | | | legend | `ChartsLegend` | - | Custom rendering of the legend. | | line | `LineElementPath` | - | The component that renders the line. | | lineHighlight | `undefined` | - | | | loadingOverlay | `ChartsLoadingOverlay` | - | Overlay component rendered when the chart is in a loading state. | | mark | `undefined` | - | | | noDataOverlay | `ChartsNoDataOverlay` | - | Overlay component rendered when the chart has no data to display. | | toolbar | `ChartsToolbar` | - | Custom component for the toolbar. | | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/LineChart.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/LineChart.tsx) --- # Source: https://mui.com/x/react-charts/line-demo.md --- title: Charts - Line demos productId: x-charts components: LineChart, LineElement, LineHighlightElement, LineHighlightPlot, LinePlot, MarkElement, MarkPlot --- # Charts - Line demos This page groups demos using line charts. ## SimpleLineChart ```tsx import Box from '@mui/material/Box'; import { LineChart } from '@mui/x-charts/LineChart'; const margin = { right: 24 }; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function SimpleLineChart() { return ( ); } ``` ## TinyLineChart ```tsx import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { LinePlot, MarkPlot, lineElementClasses, markElementClasses, } from '@mui/x-charts/LineChart'; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function TinyLineChart() { return ( ); } ``` ## DashedLineChart ```tsx import Box from '@mui/material/Box'; import { LineChart, lineElementClasses, markElementClasses, } from '@mui/x-charts/LineChart'; const margin = { right: 24 }; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function DashedLineChart() { return ( ); } ``` ## BiaxialLineChart ```tsx import Box from '@mui/material/Box'; import { LineChart } from '@mui/x-charts/LineChart'; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function BiaxialLineChart() { return ( ); } ``` ## LineChartWithReferenceLines ```tsx import Box from '@mui/material/Box'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { ChartsReferenceLine } from '@mui/x-charts/ChartsReferenceLine'; import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; const margin = { right: 24 }; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function LineChartWithReferenceLines() { return ( ); } ``` ## LineChartConnectNulls ```tsx import Stack from '@mui/material/Stack'; import { LineChart } from '@mui/x-charts/LineChart'; const margin = { right: 24 }; const data = [4000, 3000, 2000, null, 1890, 2390, 3490]; const xData = ['Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G']; export default function LineChartConnectNulls() { return ( ); } ``` ## CustomLabelLineChart ```tsx import Box from '@mui/material/Box'; import { LineChart, MarkElementProps } from '@mui/x-charts/LineChart'; const margin = { right: 24 }; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; function CustomMark(props: MarkElementProps) { const { x, y, color } = props; return ( {pData[props.dataIndex].toString()} ); } export default function CustomLabelChart() { return ( ); } ``` ## Line chart with live data ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import { LineChart } from '@mui/x-charts/LineChart'; const dateFormatter = Intl.DateTimeFormat(undefined, { month: '2-digit', day: '2-digit', }); const oneDay = 24 * 60 * 60 * 1000; // in milliseconds const length = 50; const initialFirstData = Array.from({ length }).map( (_, __, array) => (array.at(-1) ?? 0) + randBetween(-100, 500), ); const initialSecondData = Array.from({ length }).map( (_, __, array) => (array.at(-1) ?? 0) + randBetween(-500, 100), ); export default function LiveLineChartNoSnap() { const [running, setRunning] = React.useState(false); const [date, setDate] = React.useState(new Date(2000, 0, 0)); const [firstData, setFirstData] = React.useState(initialFirstData); const [secondData, setSecondData] = React.useState(initialSecondData); React.useEffect(() => { if (!running) { return undefined; } const intervalId = setInterval(() => { setDate((prev) => new Date(prev.getTime() + oneDay)); setFirstData((prev) => [ ...prev.slice(1), prev.at(-1)! + randBetween(-500, 500), ]); setSecondData((prev) => [ ...prev.slice(1), prev.at(-1)! + randBetween(-500, 500), ]); }, 100); return () => { clearInterval(intervalId); }; }, [running]); return ( new Date(date.getTime() + i * oneDay), ), valueFormatter: (value: Date) => dateFormatter.format(value), }, ]} yAxis={[{ width: 50 }]} margin={{ right: 24 }} /> ); } function randBetween(min: number, max: number) { return Math.floor(Math.random() * (max - min + 1) + min); } ``` ## Line with forecast To show that parts of the data have different meanings, you can render stylised lines for each of them. In the following example, the chart shows a dotted line to exemplify that the data is estimated. To do so, the `slots.line` is set with a custom component that render the default line twice. - The first one is clipped to show known values (from the left of the chart to the limit). - The second one is clipped to show predictions (from the limit to the right of the chart) with dash styling. Additionally, an uncertainty area is shown to represent the uncertainty of the forecast. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { AnimatedLine, AnimatedLineProps, LinePlot, MarkPlot, } from '@mui/x-charts/LineChart'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { ChartsTooltip } from '@mui/x-charts/ChartsTooltip'; import { ChartsClipPath } from '@mui/x-charts/ChartsClipPath'; import { useChartId, useDrawingArea, useLineSeries, useXAxis, useXScale, useYScale, } from '@mui/x-charts/hooks'; import * as d3Shape from '@mui/x-charts-vendor/d3-shape'; import { SxProps } from '@mui/system'; import { useTheme, Theme } from '@mui/material/styles'; interface CustomAnimatedLineProps extends AnimatedLineProps { limit?: number; sxBefore?: SxProps; sxAfter?: SxProps; } function CustomAnimatedLine(props: CustomAnimatedLineProps) { const { limit, sxBefore, sxAfter, ...other } = props; const { top, bottom, height, left, width } = useDrawingArea(); const scale = useXScale(); const chartId = useChartId(); if (limit === undefined) { return ; } const limitPosition = scale(limit); // Convert value to x coordinate. if (limitPosition === undefined) { return ; } const clipIdleft = `${chartId}-${props.ownerState.id}-line-limit-${limit}-1`; const clipIdRight = `${chartId}-${props.ownerState.id}-line-limit-${limit}-2`; return ( {/* Clip to show the line before the limit */} {/* Clip to show the line after the limit */} ); } function ForecastArea({ limit, forecast, }: { limit: number; forecast: { y0: number; y1: number }[]; }) { const lineSeries = useLineSeries(); const xAxis = useXAxis(); const xScale = useXScale(); const yScale = useYScale(); const xAxisData: number[] = xAxis.data?.slice(limit) ?? []; if (!yScale) { return null; } return ( {lineSeries.map((series) => { const data = xAxisData.map((v, i) => ({ x: v, y0: forecast[i].y0, y1: forecast[i].y1, })); const path = d3Shape .area<(typeof data)[number]>() .x((d) => xScale(d.x)!) .y0((d) => yScale(d.y0)!) .y1((d) => yScale(d.y1)!)(data)!; return ; })} ); } function ShadedBackground({ limit }: { limit: number }) { const { top, bottom, height, left, width } = useDrawingArea(); const scale = useXScale(); const limitPosition = scale(limit)!; const theme = useTheme(); const fill = theme.palette.mode === 'dark' ? theme.palette.grey[900] : theme.palette.grey[400]; return ( ); } export default function LineWithUncertaintyArea() { const id = React.useId(); const clipPathId = `${id}-clip-path`; return ( `${v}${i.dataIndex > 5 ? ' (estimated)' : ''}`, }, ]} xAxis={[{ data: [0, 1, 2, 3, 4, 5, 6, 7, 8] }]} sx={{ '& .line-after path': { strokeDasharray: '10 5' } }} > ); } ``` ## CustomLineMarks Notice that using another shape than "circle" renders a `` instead of the `` for mark elements. This modification results in a small drop in rendering performance (around 50ms to render 1,000 marks). ```tsx import Box from '@mui/material/Box'; import { LineChart } from '@mui/x-charts/LineChart'; const margin = { right: 24 }; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; export default function CustomLineMarks() { return ( index % 2 === 0, }, { data: uData, label: 'uv', shape: 'diamond', showMark: ({ index }) => index % 2 === 0, }, ]} xAxis={[{ scaleType: 'point', data: xLabels, height: 28 }]} yAxis={[{ width: 50 }]} margin={margin} /> ); } ``` ## Larger interaction area A line is highlighted when a pointer is hovering over it. Which is a narrow interaction area. While a permanent solution isn't implemented, it's possible to define a larger interaction area with slots. The idea is to have two paths: A small one to display the line, and a larger invisible one that handles the interactions. This solution has an issue when lines cross over each other, as the highlight is not on the closest line to the pointer, but by the last defined series. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Checkbox from '@mui/material/Checkbox'; import FormControlLabel from '@mui/material/FormControlLabel'; import { AnimatedLineProps, LineChart } from '@mui/x-charts/LineChart'; import { HighlightScope } from '@mui/x-charts/context'; const margin = { right: 24 }; const uData = [4000, 3000, 2000, 2780, 1890, 2390, 3490]; const pData = [2400, 1398, 9800, 3908, 4800, 3800, 4300]; const xLabels = [ 'Page A', 'Page B', 'Page C', 'Page D', 'Page E', 'Page F', 'Page G', ]; const highlightScope: HighlightScope = { highlight: 'item', fade: 'global', }; const settings = { height: 300, series: [ { data: pData, label: 'pv', highlightScope }, { data: uData, label: 'uv', highlightScope }, ], xAxis: [{ scaleType: 'point', data: xLabels }], yAxis: [{ width: 50 }], margin, } as const; function CustomLine(props: AnimatedLineProps) { const { d, ownerState, className, ...other } = props; return ( ); } export default function LargerHighlightLineNoSnap() { const [showInteractionArea, setShowInteractionArea] = React.useState(true); return ( setShowInteractionArea(event.target.checked)} /> } label="Show highlight area" labelPlacement="end" /> ); } ``` --- # Source: https://mui.com/x/api/charts/line-element.md # LineElement API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Line demos](/x/react-charts/line-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { LineElement } from '@mui/x-charts/LineChart'; // or import { LineElement } from '@mui/x-charts'; // or import { LineElement } from '@mui/x-charts-pro'; // or import { LineElement } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | hidden | `bool` | - | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | line | `LineElementPath` | - | The component that renders the line. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | faded | Styles applied to the root element when faded. | | - | highlighted | Styles applied to the root element when highlighted. | | - | root | Styles applied to the root element. | | - | series | Styles applied to the root element for a specified series. Needs to be suffixed with the series ID: `.${lineElementClasses.series}-${seriesId}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/LineElement.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/LineElement.tsx) --- # Source: https://mui.com/x/api/charts/line-highlight-element.md # LineHighlightElement API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Line demos](/x/react-charts/line-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { LineHighlightElement } from '@mui/x-charts/LineChart'; // or import { LineHighlightElement } from '@mui/x-charts'; // or import { LineHighlightElement } from '@mui/x-charts-pro'; // or import { LineHighlightElement } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/LineHighlightElement.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/LineHighlightElement.tsx) --- # Source: https://mui.com/x/api/charts/line-highlight-plot.md # LineHighlightPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Line demos](/x/react-charts/line-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { LineHighlightPlot } from '@mui/x-charts/LineChart'; // or import { LineHighlightPlot } from '@mui/x-charts'; // or import { LineHighlightPlot } from '@mui/x-charts-pro'; // or import { LineHighlightPlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | lineHighlight | `undefined` | - | | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/LineHighlightPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/LineHighlightPlot.tsx) --- # Source: https://mui.com/x/api/charts/line-plot.md # LinePlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Line demos](/x/react-charts/line-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { LinePlot } from '@mui/x-charts/LineChart'; // or import { LinePlot } from '@mui/x-charts'; // or import { LinePlot } from '@mui/x-charts-pro'; // or import { LinePlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | onItemClick | `function(event: React.MouseEvent, lineItemIdentifier: LineItemIdentifier) => void` | - | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | line | `LineElementPath` | - | The component that renders the line. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/LinePlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/LinePlot.tsx) --- # Source: https://mui.com/x/api/charts/line-series.md # LineSeries API ## Import ```jsx import { LineSeries } from '@mui/x-charts-premium' // or import { LineSeries } from '@mui/x-charts-pro' // or import { LineSeries } from '@mui/x-charts' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | type | `'line'` | - | Yes | | | area | `boolean` | - | No | | | baseline | `number \| 'min' \| 'max'` | `0` | No | | | color | `string` | - | No | | | colorGetter | `(data: ColorCallbackValue) => string` | - | No | | | connectNulls | `boolean` | `false` | No | | | curve | `CurveType` | `'monotoneX'` | No | | | data | `readonly (number \| null)[]` | - | No | | | dataKey | `string` | - | No | | | disableHighlight | `boolean` | `false` | No | | | highlightScope | `HighlightScope` | - | No | | | id | `SeriesId` | - | No | | | label | `string \| ((location: 'tooltip' \| 'legend') => string)` | - | No | | | labelMarkType | `ChartsLabelMarkType` | - | No | | | shape | `'circle' \| 'cross' \| 'diamond' \| 'square' \| 'star' \| 'triangle' \| 'wye'` | `'circle'` | No | | | showMark | `boolean \| ((params: ShowMarkParams) => boolean)` | - | No | | | stack | `string` | - | No | | | stackOffset | `StackOffsetType` | `'none'` | No | | | stackOrder | `StackOrderType` | `'none'` | No | | | strictStepCurve | `boolean` | - | No | | | valueFormatter | `SeriesValueFormatter` | - | No | | | xAxisId | `AxisId` | - | No | | | yAxisId | `AxisId` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/react-charts/lines.md --- title: React Line chart productId: x-charts components: LineChart, LineChartPro, LineElement, LineHighlightElement, LineHighlightPlot, LinePlot, MarkElement, MarkPlot, AreaElement, AreaPlot, AnimatedLine, AnimatedArea, ChartsGrid --- # Charts - Lines Line charts can express qualities about data, such as hierarchy, highlights, and comparisons. ## Overview Line charts are ideal for showing how values change over continuous dimensions such as time or measurement scales. They emphasize trends, patterns, and fluctuations, making them useful for exploring relationships, detecting cycles, or tracking performance over time. Each line typically represents a series, allowing easy comparison between multiple variables or groups. ```tsx import * as React from 'react'; import Typography from '@mui/material/Typography'; import Box from '@mui/material/Box'; import { alpha, useTheme } from '@mui/material/styles'; import { ChartDataProviderPro } from '@mui/x-charts-pro/ChartDataProviderPro'; import { ChartsSurface } from '@mui/x-charts-pro/ChartsSurface'; import { LinePlot } from '@mui/x-charts-pro/LineChart'; import { ChartsXAxis } from '@mui/x-charts-pro/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts-pro/ChartsYAxis'; import { useDrawingArea, useXScale } from '@mui/x-charts-pro/hooks'; import { ChartsTooltip } from '@mui/x-charts-pro/ChartsTooltip'; import { ChartsGrid } from '@mui/x-charts-pro/ChartsGrid'; import { ChartZoomSlider } from '@mui/x-charts-pro/ChartZoomSlider'; import { ChartsClipPath } from '@mui/x-charts-pro/ChartsClipPath'; import { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight'; import { ChartsLegend } from '@mui/x-charts-pro/ChartsLegend'; import { usaUnemploymentAndGdp } from '../dataset/usaUnemploymentAndGdp'; type RecessionPeriod = { start: Date; end: Date; label: string; }; const recessions = [ { start: new Date('2001-03-01'), end: new Date('2001-11-01'), label: 'Early 2000s', }, { start: new Date('2007-12-01'), end: new Date('2009-06-01'), label: 'Great Recession', }, { start: new Date('2020-02-01'), end: new Date('2020-04-01'), label: 'COVID-19' }, ]; function RecessionBands({ periods }: { periods: RecessionPeriod[] }) { const { top, left, width, height } = useDrawingArea(); const xScale = useXScale(); const theme = useTheme(); const labelFill = alpha(theme.palette.text.primary, 0.7); return ( {periods.map((p, index) => { const xStart = xScale(p.start.getTime()); const xEnd = xScale(p.end.getTime()); if (xStart === undefined || xEnd === undefined) { return null; } // Stick to the left of the drawing area boundaries let textX: number; if (xStart >= left && xStart <= left + width) { textX = xStart; } else if (xEnd >= left && xEnd <= left + width) { textX = left; } else { return null; } return ( {p.label} ); })} ); } export default function LineOverview() { const clipPathId = React.useId(); return ( US unemployment rate comparison with GDP per capita (value == null ? '' : `${value.toFixed(1)}%`), }, { type: 'line', dataKey: 'gdpPerCapita', label: 'GDP per capita', color: '#4caf50', showMark: false, yAxisId: 'gdp-axis', connectNulls: true, valueFormatter: (value) => value == null ? '' : `${(value / 1000).toFixed(1)}k`, }, ]} xAxis={[ { scaleType: 'time', dataKey: 'date', tickNumber: 4, valueFormatter: (date, context) => { if (context.location !== 'tick') { return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', }); } return date.getMonth() === 0 ? date.toLocaleDateString('en-US', { year: 'numeric', }) : date.toLocaleDateString('en-US', { month: 'short', }); }, zoom: { slider: { enabled: true }, }, }, ]} yAxis={[ { id: 'unemployment-axis', scaleType: 'linear', valueFormatter: (value) => `${value}%`, width: 55, position: 'left', }, { id: 'gdp-axis', scaleType: 'linear', width: 50, position: 'right', valueFormatter: (value) => `${(value / 1000).toLocaleString()}k`, }, ]} > Source: FRED ); } ``` ## Basics ### Data format Line charts series should contain a `data` property containing an array of numbers. This `data` array corresponds to y-values. You can specify x-values with the `xAxis` prop. This axis can have any `scaleType` and its `data` should have the same length as your series. By default, those y-values will be associated with integers starting from 0 (0, 1, 2, 3, ...). ```tsx import { LineChart } from '@mui/x-charts/LineChart'; export default function BasicLineChart() { return ( ); } ``` ### 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 axis, thanks to the `dataKey` property. For example `xAxis={[{ dataKey: 'x'}]}` or `series={[{ dataKey: 'y'}]}`. Here is a plot of the evolution of world electricity production by source. ```tsx import { LineChart } from '@mui/x-charts/LineChart'; import { worldElectricityProduction, keyToLabel, colors, } from '../dataset/worldElectricityProduction'; const stackStrategy = { stack: 'total', area: true, stackOffset: 'none', // To stack 0 on top of others } as const; const customize = { height: 350, hideLegend: true, experimentalFeatures: { preferStrictDomainInLineCharts: true }, }; export default function LineDataset() { return ( value.toString() }, ]} yAxis={[{ width: 50 }]} series={Object.keys(keyToLabel).map((key) => ({ dataKey: key, label: keyToLabel[key], color: colors[key], showMark: false, ...stackStrategy, }))} dataset={worldElectricityProduction} {...customize} /> ); } ``` ### Area You can fill the area of the line by setting the series' `area` property to `true`. ```tsx import { LineChart } from '@mui/x-charts/LineChart'; export default function BasicArea() { return ( ); } ``` ### Log scale A y-axis with a log scale cannot plot a line that crosses zero nor an area chart because the logarithm of zero is undefined. You can work around this limitation by using a [symlog scale](/x/react-charts/axis/#symlog-scale). ### Stacking Each line series can get a `stack` property which expects a string value. Series with the same `stack` will be stacked on top of each other. You can use the `stackOffset` and `stackOrder` properties to define how the series will be stacked. By default, they are stacked in the order you defined them, with positive values stacked above 0 and negative values stacked below 0. For more information, see [stacking docs](/x/react-charts/stacking/). ```tsx import { LineChart } from '@mui/x-charts/LineChart'; import { dataset } from '../dataset/gdpPerCapitaEvolution'; export default function StackedAreas() { return (
date.getFullYear().toString(), }, ]} yAxis={[{ width: 70 }]} series={[ { id: 'France', label: 'French GDP per capita', dataKey: 'fr', stack: 'total', area: true, showMark: false, }, { id: 'Germany', label: 'German GDP per capita', dataKey: 'dl', stack: 'total', area: true, showMark: false, }, { id: 'United Kingdom', label: 'UK GDP per capita', dataKey: 'gb', stack: 'total', area: true, showMark: false, }, ]} experimentalFeatures={{ preferStrictDomainInLineCharts: true }} height={300} />
); } ``` ### Axis domain By default, axes round their limits to match human-readable values. For example, if your data ranges from 2 to 195, the axis displays values from 0 to 200. This behavior can be modified by the [axis property `domainLimit`](/x/react-charts/axis/#relative-axis-subdomain). :::info The current default behavior can lead to empty space on left/right of the line chart. To fix that issue, future major version will default the x-axis domain limit to `'strict'`. To test this behavior, add the `experimentalFeatures` prop to your chart with `preferStrictDomainInLineCharts: true` value. You can also enable it globally using [theme default props](/material-ui/customization/theme-components/#theme-default-props) ```js components: { MuiChartDataProvider: { defaultProps: { experimentalFeatures: { preferStrictDomainInLineCharts: true } }, }, } ``` ::: ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { LineChart } from '@mui/x-charts/LineChart'; import { dataset } from '../dataset/gdpPerCapitaEvolution'; export default function LineDefaultDomainLimit() { const [preferStrictDomainInLineCharts, setPreferStrictDomainInLineCharts] = React.useState(false); return ( setPreferStrictDomainInLineCharts(event.target.checked) } /> } label="Strict domain limit" labelPlacement="end" />
date.getFullYear().toString(), }, ]} yAxis={[{ width: 70 }]} series={[ { id: 'France', label: 'French GDP per capita', dataKey: 'fr', stack: 'total', area: true, showMark: false, }, { id: 'Germany', label: 'German GDP per capita', dataKey: 'dl', stack: 'total', area: true, showMark: false, }, { id: 'United Kingdom', label: 'UK GDP per capita', dataKey: 'gb', stack: 'total', area: true, showMark: false, }, ]} height={300} />
); } ``` ## Partial data ### Skip missing points Line series can have fewer data points than the axis. You can handle lines with partial data or data starting at different points by providing `null` values. By default, the tooltip does not show series if they have no value. To override this behavior, use the `valueFormatter` to return a string if the value is `null` or `undefined`. ```tsx import { LineChart } from '@mui/x-charts/LineChart'; export default function DifferentLength() { return ( (value == null ? 'NaN' : value.toString()), }, { data: [null, null, null, null, 5.5, 2, 8.5, 1.5, 5], }, { data: [7, 8, 5, 4, null, null, 2, 5.5, 1], valueFormatter: (value) => (value == null ? '?' : value.toString()), }, ]} height={200} margin={{ bottom: 10 }} /> ); } ``` :::info When series data length is smaller than the axis one, overflowing values are `undefined` and not `null`. The following code plots a line for x between 2 and 4. - For x<2, values are set to `null` and then not shown. - For x>4, values are set to `undefined` and then not shown. ```jsx ``` ::: ### Connect missing points Line series accepts a `connectNulls` property which will continue the interpolation across points with a `null` value. This property can link two sets of points, with `null` data between them. However, it cannot extrapolate the curve before the first non-null data point or after the last one. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { LineChart } from '@mui/x-charts/LineChart'; export default function ConnectNulls() { const [connectNulls, setConnectNulls] = React.useState(true); return ( setConnectNulls(event.target.checked)} /> } label="connectNulls" labelPlacement="end" /> ); } ``` ## Click event Line charts provides multiple click handlers: - `onAreaClick` for click on a specific area. - `onLineClick` for click on a specific line. - `onMarkClick` for click on a specific mark. - `onAxisClick` for a click anywhere in the chart They all provide the following signature. ```js const clickHandler = ( event, // The mouse event. params, // An object that identifies the clicked elements. ) => {}; ``` ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined'; import { LineChart } from '@mui/x-charts/LineChart'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { ChartsAxisData, LineItemIdentifier } from '@mui/x-charts/models'; const lineChartsParams = { series: [ { id: 'series-1', data: [3, 4, 1, 6, 5], label: 'A', area: true, stack: 'total', highlightScope: { highlight: 'item', }, }, { id: 'series-2', data: [4, 3, 1, 5, 8], label: 'B', area: true, stack: 'total', highlightScope: { highlight: 'item', }, }, { id: 'series-3', data: [4, 2, 5, 4, 1], label: 'C', area: true, stack: 'total', highlightScope: { highlight: 'item', }, }, ], xAxis: [{ data: [0, 3, 6, 9, 12], scaleType: 'linear', id: 'axis1' }], height: 400, } as const; export default function LineClick() { const [itemData, setItemData] = React.useState(); const [axisData, setAxisData] = React.useState(); return ( setItemData(d)} onMarkClick={(event, d) => setItemData(d)} onLineClick={(event, d) => setItemData(d)} onAxisClick={(event, d) => setAxisData(d)} /> Click on the chart { setItemData(undefined); setAxisData(null); }} > ); } ``` :::info There is a slight difference between the `event` of `onAxisClick` and the others: - For `onAxisClick` it's a native mouse event emitted by the svg component. - For others, it's a React synthetic mouse event emitted by the area, line, or mark component. ::: ### Composition If you're using composition, you can get those click events as follows. Notice that the `onAxisClick` will handle both bar and line series if you mix them. ```jsx {/* ... */} ``` ## Styling ### Grid You can add a grid in the background of the chart with the `grid` prop. See [Axis—Grid](/x/react-charts/axis/#grid) documentation for more information. ```tsx import { LineChart } from '@mui/x-charts/LineChart'; import { XAxis } from '@mui/x-charts/models'; import { dateAxisFormatter, percentageFormatter, usUnemploymentRate, } from '../dataset/usUnemploymentRate'; const xAxis: XAxis<'time'>[] = [ { dataKey: 'date', scaleType: 'time', valueFormatter: dateAxisFormatter, }, ]; const yAxis = [ { valueFormatter: percentageFormatter, }, ]; const series = [ { dataKey: 'rate', showMark: false, valueFormatter: percentageFormatter, }, ]; export default function GridDemo() { return ( ); } ``` ### 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 axes `colorMap` which maps values to colors. The line charts use by priority: 1. The y-axis color 2. The x-axis color 3. The series color Learn more about the `colorMap` properties in the [Styling docs](/x/react-charts/styling/#values-color). ```tsx import * as React from 'react'; import { LineChart } from '@mui/x-charts/LineChart'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; export default function ColorScale() { const [colorX, setColorX] = React.useState< 'None' | 'piecewise' | 'continuous' | 'ordinal' >('None'); const [colorY, setColorY] = React.useState<'None' | 'piecewise' | 'continuous'>( 'piecewise', ); const [colorArea, setColorArea] = React.useState(true); return ( setColorX(event.target.value as 'None' | 'piecewise' | 'continuous') } > None piecewise continuous setColorY(event.target.value as 'None' | 'piecewise' | 'continuous') } > None piecewise continuous setColorArea(event.target.checked)} /> } label="Show chart area" labelPlacement="end" /> value.getFullYear().toString(), colorMap: (colorX === 'continuous' && { type: 'continuous', min: new Date(2019, 1, 1), max: new Date(2024, 1, 1), color: ['green', 'orange'], }) || (colorX === 'piecewise' && { type: 'piecewise', thresholds: [new Date(2021, 1, 1), new Date(2023, 1, 1)], colors: ['blue', 'red', 'blue'], }) || undefined, }, ]} /> `, ].join('\n')} language="jsx" copyButtonHidden /> ); } ``` :::warning For now, ordinal config is not supported for line chart. ::: ### Interpolation The interpolation between data points can be customized by the `curve` property. This property expects one of the following string values, corresponding to the interpolation method: `'catmullRom'`, `'linear'`, `'monotoneX'`, `'monotoneY'`, `'natural'`, `'step'`, `'stepBefore'`, `'stepAfter'`, `'bumpX'` and `'bumpY'`. This series property adds the option to control the interpolation of a series. Different series could even have different interpolations. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import { LineChart } from '@mui/x-charts/LineChart'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { CurveType } from '@mui/x-charts/models'; const curveTypes: CurveType[] = [ 'linear', 'catmullRom', 'monotoneX', 'monotoneY', 'natural', 'step', 'stepBefore', 'stepAfter', 'bumpX', 'bumpY', ]; function getExample(curveType: CurveType) { return ``; } export default function InterpolationDemo() { const [curveType, setCurveType] = React.useState(curveTypes[0]); return ( setCurveType(event.target.value as CurveType)} > {curveTypes.map((curve) => ( {curve} ))} ); } ``` #### Expanding steps To simplify the composition of line and chart, the step interpolations (when `curve` property is `'step'`, `'stepBefore'`, or `'stepAfter'`) expand to cover the full band width. You can disable this behavior with `strictStepCurve` series property. ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import TextField from '@mui/material/TextField'; import MenuItem from '@mui/material/MenuItem'; import { LinePlot, MarkPlot } from '@mui/x-charts/LineChart'; import { ChartContainer } from '@mui/x-charts/ChartContainer'; import { ChartsXAxis } from '@mui/x-charts/ChartsXAxis'; import { ChartsYAxis } from '@mui/x-charts/ChartsYAxis'; import { BarPlot } from '@mui/x-charts/BarChart'; import { ChartsAxisHighlight } from '@mui/x-charts/ChartsAxisHighlight'; const weekDay = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']; const stepCurves = ['step', 'stepBefore', 'stepAfter']; type StepCurve = 'step' | 'stepBefore' | 'stepAfter'; export default function ExpandingStep() { const [strictStepCurve, setStrictStepCurve] = React.useState(false); const [connectNulls, setConnectNulls] = React.useState(false); const [curve, setCurve] = React.useState('step'); return ( setConnectNulls(event.target.checked)} /> } label="connectNulls" labelPlacement="end" /> setStrictStepCurve(event.target.checked)} /> } label="strictStepCurve" labelPlacement="end" /> setCurve(event.target.value as StepCurve)} > {stepCurves.map((curveType) => ( {curveType} ))} ); } ``` ### Baseline The area chart draws a `baseline` on the Y axis `0`. This is useful as a base value, but customized visualizations may require a different baseline. To get the area filling the space above or below the line, set `baseline` to `"min"` or `"max"`. It is also possible to provide a `number` value to fix the baseline at the desired position. :::warning The `baseline` should not be used with stacked areas, as it will not work as expected. ::: ```tsx import { LineChart } from '@mui/x-charts/LineChart'; export default function AreaBaseline() { return ( ); } ``` ### Optimization To show mark elements, use `showMark` series property. It accepts a boolean or a callback. The next example shows how to use it to display only one mark every two data points. When a value is highlighted, a mark is rendered for that given value. If the charts already have some marks (due to `showMark=true`) the highlight one will be on top of others. This behavior can be removed with the `disableHighlight` series property or at the root of the line chart with a `disableLineItemHighlight` prop. In this example, you have one mark for every value with an even index. The highlighted data has a mark regardless if it has an even or odd index. ```tsx import { LineChart } from '@mui/x-charts/LineChart'; export default function MarkOptimization() { return ( index % 2 === 0, }, ]} height={300} /> ); } ``` ### CSS Line plots are made of three elements named `LineElement`, `AreaElement`, and `MarkElement`. Each element can be selected with the CSS class name `.MuiLineElement-root`, `.MuiAreaElement-root`, or `.MuiMarkElement-root`. If you want to select the element of a given series, you can use the `data-series` attribute. In the next example, each line style is customized with dashes, and marks are removed. The area of Germany's GDP also gets a custom gradient color. The definition of `myGradient` is passed as a children of the chart component. ```jsx ``` ```tsx import { areaElementClasses, LineChart, lineElementClasses, } from '@mui/x-charts/LineChart'; import { dataset } from '../dataset/gdpPerCapitaEvolution'; export default function CSSCustomization() { return ( date.getFullYear().toString(), }, ]} yAxis={[ { width: 60, }, ]} series={[ { id: 'France', label: 'France', dataKey: 'fr', stack: 'total', area: true, showMark: false, }, { id: 'Germany', label: 'Germany', dataKey: 'dl', stack: 'total', area: true, showMark: false, }, { id: 'United Kingdom', label: 'United Kingdom', dataKey: 'gb', stack: 'total', area: true, showMark: false, }, ]} experimentalFeatures={{ preferStrictDomainInLineCharts: true }} height={300} > ); } ``` ## 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 `skipAnimation` is enabled, the chart renders without any animations. :::warning If you support interactive ways to add or remove series from your chart, you have to provide the series' id. Otherwise the chart will have no way to know if you are modifying, removing, or adding some series. This will lead to strange behaviors. ::: ```jsx // For a single component chart // For a composed chart ``` ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { LineChart } from '@mui/x-charts/LineChart'; import { mangoFusionPalette } from '@mui/x-charts/colorPalettes'; const defaultSeries = [ { id: '1', data: [4, 5, 1, 2, 3, 3, 2], area: true, stack: '1' }, { id: '2', data: [7, 4, 6, 7, 2, 3, 5], area: true, stack: '1' }, { id: '3', data: [6, 4, 1, 2, 6, 3, 3], area: true, stack: '1' }, { id: '4', data: [4, 7, 6, 1, 2, 7, 7], area: true, stack: '1' }, { id: '5', data: [2, 2, 1, 7, 1, 5, 3], area: true, stack: '1' }, { id: '6', data: [6, 6, 1, 6, 7, 1, 1], area: true, stack: '1' }, { id: '7', data: [7, 6, 1, 6, 4, 4, 6], area: true, stack: '1' }, { id: '8', data: [4, 3, 1, 6, 6, 3, 5], area: true, stack: '1' }, { id: '9', data: [7, 6, 2, 7, 4, 2, 7], area: true, stack: '1' }, ].map((item, index) => ({ ...item, color: mangoFusionPalette('light')[index], })); export default function LineAnimation() { const [series, setSeries] = React.useState(defaultSeries); const [nbSeries, setNbSeries] = React.useState(3); const [skipAnimation, setSkipAnimation] = React.useState(false); return (
setSkipAnimation(event.target.checked)} /> } label="skipAnimation" labelPlacement="end" />
); } ``` ## Composition Use the `` to provide `series`, `xAxis`, and `yAxis` props for composition. In addition to the common chart components available for [composition](/x/react-charts/composition/), you can use the following components: - `` renders the series areas. - `` renders the series lines. - `` renders the series marks. - `` renders larger mark dots on the highlighted values. Here's how the Line Chart is composed: ```jsx {/* Elements clipped inside the drawing area. */} {/* Elements able to overflow the drawing area. */} ``` :::info The `data-drawing-container` indicates that children of this element should be considered part of the drawing area, even if they overflow. See [Composition—clipping](/x/react-charts/composition/#clipping) for more info. ::: --- # Source: https://mui.com/x/react-data-grid/list-view.md --- title: Data Grid - List view --- # Data Grid - List view [](/x/introduction/licensing/#pro-plan 'Pro plan') Display data in a single-column list view for a more compact Data Grid on smaller screens and mobile devices. A typical data grid built for desktop devices can be difficult to use on a mobile device. The Data Grid Pro provides a single-column list view format to give users a better experience on smaller screens. ## Implementing list view To enable list view, pass the `listView` prop to the Data Grid. Unlike the default grid view, list view requires you to explicitly define how columns and cells are displayed by passing the `listViewColumn` prop with [a `renderCell()` function](/x/react-data-grid/cells/#rendercell): ```tsx function ListViewCell(params: GridRenderCellParams) { return <>{params.row.id}; } const listViewColDef: GridListViewColDef = { field: 'listColumn', renderCell: ListViewCell, }; ; ``` ```tsx import * as React from 'react'; import { DataGridPro, GridRenderCellParams, GridListViewColDef, GridColDef, GridRowParams, GridToolbarContainer, GridActionsCell, } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; import Stack from '@mui/material/Stack'; import Avatar from '@mui/material/Avatar'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import MessageIcon from '@mui/icons-material/Message'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import ToggleButton from '@mui/material/ToggleButton'; import GridViewIcon from '@mui/icons-material/ViewModule'; import ListViewIcon from '@mui/icons-material/ViewList'; declare module '@mui/x-data-grid' { interface ToolbarPropsOverrides { view: 'grid' | 'list'; onChangeView: (view: 'grid' | 'list') => void; } } function MessageAction(params: Pick) { const handleMessage = (event: React.MouseEvent) => { event.stopPropagation(); console.log(`send message to ${params.row.phone}`); }; return ( ); } function ListViewCell(params: GridRenderCellParams) { return ( {params.row.name} {params.row.position} ); } const listViewColDef: GridListViewColDef = { field: 'listColumn', renderCell: ListViewCell, }; const VISIBLE_FIELDS = ['avatar', 'name', 'position']; type ToolbarProps = { view: 'grid' | 'list'; onChangeView: (view: 'grid' | 'list') => void; }; function Toolbar({ view, onChangeView }: ToolbarProps) { return ( { if (newView) { onChangeView(newView); } }} > Grid List ); } export default function ListView() { const [view, setView] = React.useState<'grid' | 'list'>('list'); const isListView = view === 'list'; const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 20, visibleFields: VISIBLE_FIELDS, }); const columns: GridColDef[] = React.useMemo(() => { return [ ...data.columns, { type: 'actions', field: 'actions', width: 75, renderCell: (params: GridRenderCellParams) => ( ), }, ]; }, [data.columns]); const rowHeight = isListView ? 64 : 52; return (
); } ``` ## Responsive list view with media query Use the `useMediaQuery` hook from `@mui/material` to enable the list view feature at a specified breakpoint. The demo below automatically switches to a list layout when the viewport width is below the `md` breakpoint. ```tsx import { DataGridPro, GridRenderCellParams, GridListViewColDef, } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; import Stack from '@mui/material/Stack'; import Avatar from '@mui/material/Avatar'; import Typography from '@mui/material/Typography'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useTheme } from '@mui/material/styles'; function ListViewCell(params: GridRenderCellParams) { return ( {params.row.name} {params.row.position} ); } const listViewColDef: GridListViewColDef = { field: 'listColumn', renderCell: ListViewCell, }; const VISIBLE_FIELDS = ['avatar', 'name', 'position']; export default function ListViewMediaQuery() { const theme = useTheme(); const isListView = useMediaQuery(theme.breakpoints.down('md')); const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 5, visibleFields: VISIBLE_FIELDS, }); const rowHeight = isListView ? 64 : 52; return (
); } ``` ## List view with editable rows The [editing feature](/x/react-data-grid/editing/) is not supported while in list view, but it's possible to build an editing experience from within a custom cell renderer, as shown below: ```tsx import * as React from 'react'; import { DataGridPro, GridRenderCellParams, GridListViewColDef, GridColDef, GridRowParams, GridRowsProp, useGridApiContext, } from '@mui/x-data-grid-pro'; import Stack from '@mui/material/Stack'; import Avatar from '@mui/material/Avatar'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import Dialog from '@mui/material/Dialog'; import DialogTitle from '@mui/material/DialogTitle'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import TextField from '@mui/material/TextField'; import Button from '@mui/material/Button'; import DialogActions from '@mui/material/DialogActions'; import FormControl from '@mui/material/FormControl'; import InputLabel from '@mui/material/InputLabel'; import Select from '@mui/material/Select'; import MenuItem from '@mui/material/MenuItem'; import { randomId, randomTraderName, randomArrayItem, } from '@mui/x-data-grid-generator'; const roles = ['Marketing', 'Finance', 'Development']; const randomRole = () => { return randomArrayItem(roles); }; const rows: GridRowsProp = [ { id: randomId(), name: randomTraderName(), position: randomRole(), avatar: '#4caf50', }, { id: randomId(), name: randomTraderName(), position: randomRole(), avatar: '#2196f3', }, { id: randomId(), name: randomTraderName(), position: randomRole(), avatar: '#ff9800', }, { id: randomId(), name: randomTraderName(), position: randomRole(), avatar: '#9c27b0', }, { id: randomId(), name: randomTraderName(), position: randomRole(), avatar: '#f44336', }, ]; const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 180 }, { field: 'position', headerName: 'Department', width: 220, type: 'singleSelect', valueOptions: roles, }, ]; function EditAction(props: Pick) { const { row } = props; const [editing, setEditing] = React.useState(false); const [name, setName] = React.useState(row.name); const [position, setPosition] = React.useState(row.position); const apiRef = useGridApiContext(); const handleEdit = (event: React.MouseEvent) => { event.stopPropagation(); setEditing(true); }; const handleClose = () => { setEditing(false); }; const handleSave = (event: React.FormEvent) => { event.preventDefault(); apiRef.current.updateRows([{ id: row.id, name, position }]); handleClose(); }; React.useEffect(() => { setName(row.name); setPosition(row.position); }, [row]); return ( Edit Employee Make changes to the employee's information. setName(event.target.value)} /> Position ); } function DeleteAction(props: Pick) { const { row } = props; const apiRef = useGridApiContext(); return ( apiRef.current.updateRows([{ id: row.id, _action: 'delete' }])} > ); } function ListViewCell(props: GridRenderCellParams) { const { row } = props; return ( {row.name} {row.position} ); } const listViewColDef: GridListViewColDef = { field: 'listColumn', renderCell: (params) => , }; export default function ListViewEdit() { return (
); } ``` ## Optimizing list view for small screens If your use case calls for first-class mobile UX, you can fully customize the Data Grid's list layout using [custom subcomponents](/x/react-data-grid/components/) as shown in the demo below: ```tsx import * as React from 'react'; import { GridActionsCellItem, GridColDef, useGridApiRef, GridRowParams, DataGridPremium, GridRowId, gridClasses, GridActionsCell, GridRenderCellParams, useGridApiContext, } from '@mui/x-data-grid-premium'; import EditIcon from '@mui/icons-material/Edit'; import DeleteIcon from '@mui/icons-material/Delete'; import Avatar from '@mui/material/Avatar'; import Stack from '@mui/material/Stack'; import OpenIcon from '@mui/icons-material/Visibility'; import useMediaQuery from '@mui/material/useMediaQuery'; import CSSBaseline from '@mui/material/CssBaseline'; import { randomId } from '@mui/x-data-grid-generator'; import { useTheme } from '@mui/material/styles'; import { FileIcon } from './components/FileIcon'; import { DetailsDrawer } from './components/DetailsDrawer'; import { ListCell } from './components/ListCell'; import { Toolbar } from './components/Toolbar'; import { INITIAL_ROWS } from './data'; import { FILE_TYPES } from './constants'; import { RowModel, FileType } from './types'; import { formatDate, formatSize, stringAvatar } from './utils'; import { ActionDrawer } from './components/ActionDrawer'; import { RenameDialog } from './components/RenameDialog'; declare module '@mui/x-data-grid' { interface ToolbarPropsOverrides { listView: boolean; container: HTMLElement; handleDelete: (ids: GridRowId[]) => void; handleUpload: (event: React.ChangeEvent) => void; } } interface Props { // Injected by the documentation to work in an iframe. window?: () => Window; } interface ActionHandlers { setOverlayState: (state: { overlay: 'actions' | 'details' | 'rename' | null; params: Pick, 'row'> | null; }) => void; handleDelete: (ids: GridRowId[]) => void; } const ActionHandlersContext = React.createContext(null); function ActionsCell(props: GridRenderCellParams) { const context = React.useContext(ActionHandlersContext); const apiRef = useGridApiContext(); if (!context) { return null; } const { setOverlayState, handleDelete } = context; return ( } onClick={() => { setOverlayState({ overlay: 'actions', params: props }); }} showInMenu /> } onClick={() => apiRef.current?.startCellEditMode({ id: props.id, field: 'name', }) } showInMenu /> } onClick={() => handleDelete([props.id])} showInMenu /> ); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 350, editable: true, hideable: false, renderCell: (params) => { return ( {params.value} ); }, }, { field: 'createdBy', headerName: 'Owner', width: 200, renderCell: (params) => { const avatarProps = stringAvatar(params.value); return ( {params.value} ); }, }, { field: 'createdAt', headerName: 'Added', type: 'date', width: 200, valueFormatter: formatDate, }, { field: 'updatedAt', headerName: 'Modified', type: 'date', width: 200, valueFormatter: formatDate, }, { field: 'type', headerName: 'Type', width: 150, }, { field: 'size', headerName: 'Size', width: 120, valueFormatter: formatSize, }, { type: 'actions', field: 'actions', resizable: false, width: 50, renderCell: (params) => , }, ]; export default function ListViewAdvanced({ window }: Props) { // This is used only for the example - renders the drawer inside the container const container = window !== undefined ? window().document.body : undefined; const theme = useTheme(); const isBelowMd = useMediaQuery(theme.breakpoints.down('md')); const isDocsDemo = window !== undefined; const isListView = isDocsDemo ? true : isBelowMd; const apiRef = useGridApiRef(); const [loading, setLoading] = React.useState(false); const [overlayState, setOverlayState] = React.useState<{ overlay: 'actions' | 'details' | 'rename' | null; params: Pick, 'row'> | null; }>({ overlay: null, params: null, }); const handleCloseOverlay = () => { setOverlayState({ overlay: null, params: null }); }; const handleDelete = React.useCallback( (ids: GridRowId[]) => { apiRef.current?.updateRows(ids.map((id) => ({ id, _action: 'delete' }))); }, [apiRef], ); const handleUpdate = React.useCallback( ( id: GridRowId, field: GridRowParams['columns'][number]['field'], value: string, ) => { const updatedAt = new Date().toISOString(); apiRef.current?.updateRows([{ id, [field]: value, updatedAt }]); }, [apiRef], ); const handleUpload = React.useCallback( (event: React.ChangeEvent) => { if (!event.target.files) { return; } const file = event.target.files[0]; const createdAt = new Date().toISOString(); const fileType = file.type.split('/')[1]; // validate file type if (!FILE_TYPES.includes(fileType as FileType)) { alert('Invalid file type'); return; } const row: RowModel = { id: randomId(), name: file.name, description: '', type: fileType as FileType, size: file.size, createdBy: 'Kenan Yusuf', createdAt, updatedAt: createdAt, state: 'pending', }; event.target.value = ''; // Add temporary row setLoading(true); apiRef.current?.updateRows([row]); // Simulate server response time const timeout = Math.floor(Math.random() * 3000) + 2000; setTimeout(() => { const uploadedRow: RowModel = { ...row, state: 'uploaded' }; apiRef.current?.updateRows([uploadedRow]); setOverlayState({ overlay: 'actions', params: { row } }); setLoading(false); }, timeout); }, [apiRef], ); const listViewColDef: GridColDef = React.useMemo( () => ({ field: 'listCell', renderCell: (params) => ( { setOverlayState({ overlay: 'actions', params }); }} /> ), }), [], ); const getEstimatedRowHeight = () => { const density = apiRef.current?.state?.density; if (isListView) { switch (density) { case 'compact': return 47; case 'standard': return 67; case 'comfortable': return 97; default: return 67; } } else { switch (density) { case 'compact': return 47; case 'standard': return 55; case 'comfortable': return 63; default: return 55; } } }; const getRowHeight = React.useCallback( () => (isListView ? 'auto' : undefined), [isListView], ); const actionHandlers = React.useMemo( () => ({ setOverlayState, apiRef, handleDelete, }), [apiRef, handleDelete], ); return (
setOverlayState({ overlay: 'actions', params }) } hideFooterSelectedRowCount /> handleUpdate(id, 'description', value)} onClose={handleCloseOverlay} /> setOverlayState({ overlay: 'details', params: overlayState.params }) } onRename={() => setOverlayState({ overlay: 'rename', params: overlayState.params }) } onDelete={(id) => { handleDelete([id]); handleCloseOverlay(); }} onClose={handleCloseOverlay} /> handleUpdate(id, 'name', value)} onClose={handleCloseOverlay} />
); } ``` ## List view feature compatibility List view can be used in combination with the following features: - ✅ [Sorting](/x/react-data-grid/sorting/) - ✅ [Filtering](/x/react-data-grid/filtering/) - ✅ [Pagination](/x/react-data-grid/pagination/) - ✅ [Row selection](/x/react-data-grid/row-selection/) - ✅ [Multi-filters](/x/react-data-grid/filtering/multi-filters/) [](/x/introduction/licensing/#pro-plan 'Pro plan') - ✅ [Row pinning](/x/react-data-grid/row-pinning/) [](/x/introduction/licensing/#pro-plan 'Pro plan') - ✅ [Cell selection](/x/react-data-grid/cell-selection/) [](/x/introduction/licensing/#premium-plan 'Premium plan') :::warning Features not listed here may not work as expected (or at all). If you're using a feature that's listed above and it's not working as expected, please [open a bug report](https://github.com/mui/mui-x/issues/new?assignees=&labels=status%3A+waiting+for+maintainer%2Cbug+%F0%9F%90%9B&projects=&template=1.bug.yml). If you need to use list view with any other features not listed, please [open a feature request](https://github.com/mui/mui-x/issues/new?assignees=&labels=status%3A+waiting+for+maintainer%2Cnew+feature&projects=&template=2.feature.yml). ::: ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) - [GridListViewColDef](/x/api/data-grid/grid-list-view-col-def/) --- # MUI X Documentation This documentation covers all MUI X packages including Data Grid, Date Pickers, Charts, Tree View, and other components. --- ## Date and Time Pickers This is the documentation for the Date and Time Pickers package. It contains comprehensive guides, components, and utilities for building user interfaces. - [Quickstart](/x/react-date-pickers/quickstart.md): Install the MUI X Date and Time Pickers package and set up your date library to start building. - [Base concepts](/x/react-date-pickers/base-concepts.md): The Date and Time Pickers expose a lot of components to fit your every need. ### Components #### Date components - [Date Picker](/x/react-date-pickers/date-picker.md): The Date Picker component lets users select a date. - [Date Field](/x/react-date-pickers/date-field.md): The Date Field component lets users select a date with the keyboard. - [Date Calendar](/x/react-date-pickers/date-calendar.md): The Date Calendar component lets users select a date without any input or popper / modal. #### Time components - [Time Picker](/x/react-date-pickers/time-picker.md): The Time Picker component lets the user select a time. - [Time Field](/x/react-date-pickers/time-field.md): The Time Field component lets the user select a time with the keyboard. - [Time Clock](/x/react-date-pickers/time-clock.md): The Time Clock component lets the user select a time without any input or popper / modal. - [Digital Clock](/x/react-date-pickers/digital-clock.md): The Digital Clock lets the user select a time without any input or popper / modal. #### Date Time components - [Date Time Picker](/x/react-date-pickers/date-time-picker.md): The Date Time Picker component lets users select a date and time. - [Date Time Field](/x/react-date-pickers/date-time-field.md): The Date Time Field component lets users select a date and a time with the keyboard. #### Date Range components - [Date Range Picker](/x/react-date-pickers/date-range-picker.md): The Date Range Picker lets the user select a range of dates. - [Date Range Field](/x/react-date-pickers/date-range-field.md): The Date Range Field lets the user select a date range with the keyboard. - [Date Range Calendar](/x/react-date-pickers/date-range-calendar.md): The Date Range Calendar lets the user select a range of dates without any input or popper / modal. #### Time Range components - [Time Range Picker](/x/react-date-pickers/time-range-picker.md): The Time Range Picker lets users select a range of time values. 🆕 - [Time Range Field](/x/react-date-pickers/time-range-field.md): The Time Range Field lets the user select a range of time with the keyboard. #### Date Time Range components - [Date Time Range Picker](/x/react-date-pickers/date-time-range-picker.md): The Date Time Range Picker lets the user select a range of dates with an explicit starting and ending time. - [Date Time Range Field](/x/react-date-pickers/date-time-range-field.md): The Date Time Range Field lets the user select a range of dates with an explicit starting and ending time with the keyboard. - [Field components](/x/react-date-pickers/fields.md): The field components let the user input date and time values with a keyboard and refined keyboard navigation. ### Main features - [Validation](/x/react-date-pickers/validation.md): Add custom validation to user inputs. - [Components lifecycle](/x/react-date-pickers/lifecycle.md): This page explains when the onChange, onAccept, and onClose callbacks are called. - [Shortcuts](/x/react-date-pickers/shortcuts.md): The date picker lets you add custom shortcuts. - [Accessibility](/x/react-date-pickers/accessibility.md): Learn how the Date and Time Pickers implement accessibility features and guidelines, including keyboard navigation that follows international standards. ### Localization - [Translated components](/x/react-date-pickers/localization.md): Date and Time Pickers support translations between languages. - [Date format and localization](/x/react-date-pickers/adapters-locale.md): Date and Time Pickers support formats from different locales. - [UTC and timezones](/x/react-date-pickers/timezone.md): Date and Time Pickers support UTC and timezones. - [Calendar systems](/x/react-date-pickers/calendar-systems.md): Use the Date and Time Pickers with non-Gregorian calendars. ### Customization - [Custom subcomponents](/x/react-date-pickers/custom-components.md): Learn how to override parts of the Date and Time Pickers. - [Custom layout](/x/react-date-pickers/custom-layout.md): The Date and Time Pickers let you reorganize the layout. - [Custom field](/x/react-date-pickers/custom-field.md): The Date and Time Pickers let you customize the field by passing props or custom components. - [Custom opening button](/x/react-date-pickers/custom-opening-button.md): The date picker lets you customize the button to open the views. - [Customization playground](/x/react-date-pickers/playground.md): Use this playground to experiment with the props that affect the layout of the Date and Time Picker components. ### Resources - [Index](/x/api/date-pickers.md): API documentation for Index - [DateCalendar](/x/api/date-pickers/date-calendar.md): API documentation for DateCalendar - [DateField](/x/api/date-pickers/date-field.md): API documentation for DateField - [DatePicker](/x/api/date-pickers/date-picker.md): API documentation for DatePicker - [DatePickerToolbar](/x/api/date-pickers/date-picker-toolbar.md): API documentation for DatePickerToolbar - [DateRangeCalendar](/x/api/date-pickers/date-range-calendar.md): API documentation for DateRangeCalendar (pro) - [DateRangePicker](/x/api/date-pickers/date-range-picker.md): API documentation for DateRangePicker (pro) - [DateRangePickerDay](/x/api/date-pickers/date-range-picker-day.md): API documentation for DateRangePickerDay (pro) - [DateRangePickerDay2](/x/api/date-pickers/date-range-picker-day-2.md): API documentation for DateRangePickerDay2 (pro) - [DateRangePickerToolbar](/x/api/date-pickers/date-range-picker-toolbar.md): API documentation for DateRangePickerToolbar (pro) - [DateTimeField](/x/api/date-pickers/date-time-field.md): API documentation for DateTimeField - [DateTimePicker](/x/api/date-pickers/date-time-picker.md): API documentation for DateTimePicker - [DateTimePickerTabs](/x/api/date-pickers/date-time-picker-tabs.md): API documentation for DateTimePickerTabs - [DateTimePickerToolbar](/x/api/date-pickers/date-time-picker-toolbar.md): API documentation for DateTimePickerToolbar - [DateTimeRangePicker](/x/api/date-pickers/date-time-range-picker.md): API documentation for DateTimeRangePicker (pro) - [DateTimeRangePickerTabs](/x/api/date-pickers/date-time-range-picker-tabs.md): API documentation for DateTimeRangePickerTabs (pro) - [DateTimeRangePickerToolbar](/x/api/date-pickers/date-time-range-picker-toolbar.md): API documentation for DateTimeRangePickerToolbar (pro) - [DayCalendarSkeleton](/x/api/date-pickers/day-calendar-skeleton.md): API documentation for DayCalendarSkeleton - [DesktopDatePicker](/x/api/date-pickers/desktop-date-picker.md): API documentation for DesktopDatePicker - [DesktopDateRangePicker](/x/api/date-pickers/desktop-date-range-picker.md): API documentation for DesktopDateRangePicker (pro) - [DesktopDateTimePicker](/x/api/date-pickers/desktop-date-time-picker.md): API documentation for DesktopDateTimePicker - [DesktopDateTimeRangePicker](/x/api/date-pickers/desktop-date-time-range-picker.md): API documentation for DesktopDateTimeRangePicker (pro) - [DesktopTimePicker](/x/api/date-pickers/desktop-time-picker.md): API documentation for DesktopTimePicker - [DesktopTimeRangePicker](/x/api/date-pickers/desktop-time-range-picker.md): API documentation for DesktopTimeRangePicker (pro) - [DigitalClock](/x/api/date-pickers/digital-clock.md): API documentation for DigitalClock - [LocalizationProvider](/x/api/date-pickers/localization-provider.md): API documentation for LocalizationProvider - [MobileDatePicker](/x/api/date-pickers/mobile-date-picker.md): API documentation for MobileDatePicker - [MobileDateRangePicker](/x/api/date-pickers/mobile-date-range-picker.md): API documentation for MobileDateRangePicker (pro) - [MobileDateTimePicker](/x/api/date-pickers/mobile-date-time-picker.md): API documentation for MobileDateTimePicker - [MobileDateTimeRangePicker](/x/api/date-pickers/mobile-date-time-range-picker.md): API documentation for MobileDateTimeRangePicker (pro) - [MobileTimePicker](/x/api/date-pickers/mobile-time-picker.md): API documentation for MobileTimePicker - [MobileTimeRangePicker](/x/api/date-pickers/mobile-time-range-picker.md): API documentation for MobileTimeRangePicker (pro) - [MonthCalendar](/x/api/date-pickers/month-calendar.md): API documentation for MonthCalendar - [MultiInputDateRangeField](/x/api/date-pickers/multi-input-date-range-field.md): API documentation for MultiInputDateRangeField (pro) - [MultiInputDateTimeRangeField](/x/api/date-pickers/multi-input-date-time-range-field.md): API documentation for MultiInputDateTimeRangeField (pro) - [MultiInputTimeRangeField](/x/api/date-pickers/multi-input-time-range-field.md): API documentation for MultiInputTimeRangeField (pro) - [MultiSectionDigitalClock](/x/api/date-pickers/multi-section-digital-clock.md): API documentation for MultiSectionDigitalClock - [PickerDay2](/x/api/date-pickers/picker-day-2.md): API documentation for PickerDay2 - [PickersActionBar](/x/api/date-pickers/pickers-action-bar.md): API documentation for PickersActionBar - [PickersCalendarHeader](/x/api/date-pickers/pickers-calendar-header.md): API documentation for PickersCalendarHeader - [PickersDay](/x/api/date-pickers/pickers-day.md): API documentation for PickersDay - [PickersLayout](/x/api/date-pickers/pickers-layout.md): API documentation for PickersLayout - [PickersRangeCalendarHeader](/x/api/date-pickers/pickers-range-calendar-header.md): API documentation for PickersRangeCalendarHeader (pro) - [PickersSectionList](/x/api/date-pickers/pickers-section-list.md): API documentation for PickersSectionList - [PickersShortcuts](/x/api/date-pickers/pickers-shortcuts.md): API documentation for PickersShortcuts - [PickersTextField](/x/api/date-pickers/pickers-text-field.md): API documentation for PickersTextField - [SingleInputDateRangeField](/x/api/date-pickers/single-input-date-range-field.md): API documentation for SingleInputDateRangeField (pro) - [SingleInputDateTimeRangeField](/x/api/date-pickers/single-input-date-time-range-field.md): API documentation for SingleInputDateTimeRangeField (pro) - [SingleInputTimeRangeField](/x/api/date-pickers/single-input-time-range-field.md): API documentation for SingleInputTimeRangeField (pro) - [StaticDatePicker](/x/api/date-pickers/static-date-picker.md): API documentation for StaticDatePicker - [StaticDateRangePicker](/x/api/date-pickers/static-date-range-picker.md): API documentation for StaticDateRangePicker (pro) - [StaticDateTimePicker](/x/api/date-pickers/static-date-time-picker.md): API documentation for StaticDateTimePicker - [StaticTimePicker](/x/api/date-pickers/static-time-picker.md): API documentation for StaticTimePicker - [TimeClock](/x/api/date-pickers/time-clock.md): API documentation for TimeClock - [TimeField](/x/api/date-pickers/time-field.md): API documentation for TimeField - [TimePicker](/x/api/date-pickers/time-picker.md): API documentation for TimePicker - [TimePickerToolbar](/x/api/date-pickers/time-picker-toolbar.md): API documentation for TimePickerToolbar - [TimeRangePicker](/x/api/date-pickers/time-range-picker.md): API documentation for TimeRangePicker (pro) - [TimeRangePickerTabs](/x/api/date-pickers/time-range-picker-tabs.md): API documentation for TimeRangePickerTabs (pro) - [TimeRangePickerToolbar](/x/api/date-pickers/time-range-picker-toolbar.md): API documentation for TimeRangePickerToolbar (pro) - [YearCalendar](/x/api/date-pickers/year-calendar.md): API documentation for YearCalendar --- ## Charts This is the documentation for the Charts package. It contains comprehensive guides, components, and utilities for building user interfaces. - [Quickstart](/x/react-charts/quickstart.md): Install the MUI X Charts package to start building React data visualization components. - [Examples](/x/react-charts/examples.md): Browse through our collection of MUI X Chart demos. ### Components #### Bars - [Bars overview](/x/react-charts/bars.md): Bar charts express quantities through a bar's length, using a common baseline. - [Demos](/x/react-charts/bar-demo.md): This page groups demos using bar charts. #### Lines - [Lines overview](/x/react-charts/lines.md): Line charts can express qualities about data, such as hierarchy, highlights, and comparisons. - [Lines demo](/x/react-charts/line-demo.md): This page groups demos using line charts. - [Area demo](/x/react-charts/areas-demo.md): This page groups demos using area charts. #### Pie - [Pie overview](/x/react-charts/pie.md): Pie charts express portions of a whole, using arcs or angles within a circle. - [Demo](/x/react-charts/pie-demo.md): This page groups demos using pie charts. #### Scatter - [Scatter overview](/x/react-charts/scatter.md): Scatter charts express the relation between two variables, using points in a surface. - [Demo](/x/react-charts/scatter-demo.md): This page groups demos using scatter charts. - [Sparkline](/x/react-charts/sparkline.md): Sparkline chart can provide an overview of data trends. - [Gauge](/x/react-charts/gauge.md): Gauge let the user evaluate metrics. - [Radar](/x/react-charts/radar.md): Radar lets you compare multivariate data in a 2D chart. - [Heatmap](/x/react-charts/heatmap.md): Heatmap charts visually represents data with color variations to highlight patterns and trends across two dimensions. (pro) #### Funnel - [Funnel overview](/x/react-charts/funnel.md): Funnel charts let you express quantity evolution along a process, such as audience engagement, population education levels, or yields of multiple processes. - [Pyramid demo](/x/react-charts/pyramid.md): The pyramid chart is a variation of the funnel chart. - [Sankey](/x/react-charts/sankey.md): Sankey charts are great for visualizing flows between different elements. (pro) #### Main features - [Animation](/x/react-charts/animation.md): Learn how to customize both CSS and JavaScript-based Chart animations. - [Axis](/x/react-charts/axis.md): Define, format, and customize Chart axes. - [Brush](/x/react-charts/brush.md): The brush interaction allows users to select a region on the chart by clicking and dragging. - [Custom components](/x/react-charts/components.md): Create custom chart components using the provided hooks. - [Composition](/x/react-charts/composition.md): Creating advanced custom charts. - [Export](/x/react-charts/export.md): Export charts as a PDF from the print dialog, or as an image. (pro) - [Highlighting](/x/react-charts/highlighting.md): Highlighting data offers quick visual feedback for chart users. - [Label](/x/react-charts/label.md): Label is the text reference of a series or data. - [Legend](/x/react-charts/legend.md): Legend is the UI element mapping symbols and colors to the series' label. - [Localization](/x/react-charts/localization.md): Localization (also referred to as "l10n") is the process of adapting a product or content to a specific locale or market. - [Stacking](/x/react-charts/stacking.md): Stacking lets you display the decomposition of values. - [Styling](/x/react-charts/styling.md): This page groups topics about charts customization. - [Toolbar](/x/react-charts/toolbar.md): Charts can display a toolbar for easier access to certain functionality. - [Tooltip](/x/react-charts/tooltip.md): Tooltip provides extra data on charts item. - [Zoom and pan](/x/react-charts/zoom-and-pan.md): Enables zooming and panning on specific charts or axis. (pro) - [Content Security Policy](/x/react-charts/content-security-policy.md): This section covers the details of setting up a Content Security Policy. #### Resources - [AnimatedArea](/x/api/charts/animated-area.md): API documentation for AnimatedArea - [AnimatedLine](/x/api/charts/animated-line.md): API documentation for AnimatedLine - [AreaElement](/x/api/charts/area-element.md): API documentation for AreaElement - [AreaPlot](/x/api/charts/area-plot.md): API documentation for AreaPlot - [BarChart](/x/api/charts/bar-chart.md): API documentation for BarChart - [BarChartPro](/x/api/charts/bar-chart-pro.md): API documentation for BarChartPro (pro) - [BarElement](/x/api/charts/bar-element.md): API documentation for BarElement - [BarLabel](/x/api/charts/bar-label.md): API documentation for BarLabel - [BarPlot](/x/api/charts/bar-plot.md): API documentation for BarPlot - [ChartContainer](/x/api/charts/chart-container.md): API documentation for ChartContainer - [ChartContainerPro](/x/api/charts/chart-container-pro.md): API documentation for ChartContainerPro (pro) - [ChartDataProvider](/x/api/charts/chart-data-provider.md): API documentation for ChartDataProvider - [ChartDataProviderPro](/x/api/charts/chart-data-provider-pro.md): API documentation for ChartDataProviderPro (pro) - [ChartsAxis](/x/api/charts/charts-axis.md): API documentation for ChartsAxis - [ChartsAxisHighlight](/x/api/charts/charts-axis-highlight.md): API documentation for ChartsAxisHighlight - [ChartsAxisTooltipContent](/x/api/charts/charts-axis-tooltip-content.md): API documentation for ChartsAxisTooltipContent - [ChartsBrushOverlay](/x/api/charts/charts-brush-overlay.md): API documentation for ChartsBrushOverlay - [ChartsClipPath](/x/api/charts/charts-clip-path.md): API documentation for ChartsClipPath - [ChartsGrid](/x/api/charts/charts-grid.md): API documentation for ChartsGrid - [ChartsItemTooltipContent](/x/api/charts/charts-item-tooltip-content.md): API documentation for ChartsItemTooltipContent - [ChartsLegend](/x/api/charts/charts-legend.md): API documentation for ChartsLegend - [ChartsLocalizationProvider](/x/api/charts/charts-localization-provider.md): API documentation for ChartsLocalizationProvider - [ChartsReferenceLine](/x/api/charts/charts-reference-line.md): API documentation for ChartsReferenceLine - [ChartsSurface](/x/api/charts/charts-surface.md): API documentation for ChartsSurface - [ChartsText](/x/api/charts/charts-text.md): API documentation for ChartsText - [ChartsToolbarImageExportTrigger](/x/api/charts/charts-toolbar-image-export-trigger.md): API documentation for ChartsToolbarImageExportTrigger (pro) - [ChartsToolbarPrintExportTrigger](/x/api/charts/charts-toolbar-print-export-trigger.md): API documentation for ChartsToolbarPrintExportTrigger (pro) - [ChartsToolbarPro](/x/api/charts/charts-toolbar-pro.md): API documentation for ChartsToolbarPro (pro) - [ChartsToolbarZoomInTrigger](/x/api/charts/charts-toolbar-zoom-in-trigger.md): API documentation for ChartsToolbarZoomInTrigger (pro) - [ChartsToolbarZoomOutTrigger](/x/api/charts/charts-toolbar-zoom-out-trigger.md): API documentation for ChartsToolbarZoomOutTrigger (pro) - [ChartsTooltip](/x/api/charts/charts-tooltip.md): API documentation for ChartsTooltip - [ChartsTooltipContainer](/x/api/charts/charts-tooltip-container.md): API documentation for ChartsTooltipContainer - [ChartsWrapper](/x/api/charts/charts-wrapper.md): API documentation for ChartsWrapper - [ChartsXAxis](/x/api/charts/charts-x-axis.md): API documentation for ChartsXAxis - [ChartsYAxis](/x/api/charts/charts-y-axis.md): API documentation for ChartsYAxis - [ChartZoomSlider](/x/api/charts/chart-zoom-slider.md): API documentation for ChartZoomSlider (pro) - [ContinuousColorLegend](/x/api/charts/continuous-color-legend.md): API documentation for ContinuousColorLegend - [FunnelChart](/x/api/charts/funnel-chart.md): API documentation for FunnelChart (pro) - [FunnelPlot](/x/api/charts/funnel-plot.md): API documentation for FunnelPlot (pro) - [Gauge](/x/api/charts/gauge.md): API documentation for Gauge - [GaugeContainer](/x/api/charts/gauge-container.md): API documentation for GaugeContainer - [Heatmap](/x/api/charts/heatmap.md): API documentation for Heatmap (pro) - [HeatmapPlot](/x/api/charts/heatmap-plot.md): API documentation for HeatmapPlot (pro) - [HeatmapTooltip](/x/api/charts/heatmap-tooltip.md): API documentation for HeatmapTooltip (pro) - [HeatmapTooltipContent](/x/api/charts/heatmap-tooltip-content.md): API documentation for HeatmapTooltipContent (pro) - [LineChart](/x/api/charts/line-chart.md): API documentation for LineChart - [LineChartPro](/x/api/charts/line-chart-pro.md): API documentation for LineChartPro (pro) - [LineElement](/x/api/charts/line-element.md): API documentation for LineElement - [LineHighlightElement](/x/api/charts/line-highlight-element.md): API documentation for LineHighlightElement - [LineHighlightPlot](/x/api/charts/line-highlight-plot.md): API documentation for LineHighlightPlot - [LinePlot](/x/api/charts/line-plot.md): API documentation for LinePlot - [MarkElement](/x/api/charts/mark-element.md): API documentation for MarkElement - [MarkPlot](/x/api/charts/mark-plot.md): API documentation for MarkPlot - [PieArc](/x/api/charts/pie-arc.md): API documentation for PieArc - [PieArcLabel](/x/api/charts/pie-arc-label.md): API documentation for PieArcLabel - [PieArcLabelPlot](/x/api/charts/pie-arc-label-plot.md): API documentation for PieArcLabelPlot - [PieArcPlot](/x/api/charts/pie-arc-plot.md): API documentation for PieArcPlot - [PiecewiseColorLegend](/x/api/charts/piecewise-color-legend.md): API documentation for PiecewiseColorLegend - [PieChart](/x/api/charts/pie-chart.md): API documentation for PieChart - [PieChartPro](/x/api/charts/pie-chart-pro.md): API documentation for PieChartPro (pro) - [PiePlot](/x/api/charts/pie-plot.md): API documentation for PiePlot - [RadarAxis](/x/api/charts/radar-axis.md): API documentation for RadarAxis - [RadarAxisHighlight](/x/api/charts/radar-axis-highlight.md): API documentation for RadarAxisHighlight - [RadarChart](/x/api/charts/radar-chart.md): API documentation for RadarChart - [RadarChartPro](/x/api/charts/radar-chart-pro.md): API documentation for RadarChartPro (pro) - [RadarGrid](/x/api/charts/radar-grid.md): API documentation for RadarGrid - [RadarMetricLabels](/x/api/charts/radar-metric-labels.md): API documentation for RadarMetricLabels - [RadarSeriesArea](/x/api/charts/radar-series-area.md): API documentation for RadarSeriesArea - [RadarSeriesMarks](/x/api/charts/radar-series-marks.md): API documentation for RadarSeriesMarks - [RadarSeriesPlot](/x/api/charts/radar-series-plot.md): API documentation for RadarSeriesPlot - [SankeyChart](/x/api/charts/sankey-chart.md): API documentation for SankeyChart (pro) - [SankeyPlot](/x/api/charts/sankey-plot.md): API documentation for SankeyPlot (pro) - [SankeyTooltip](/x/api/charts/sankey-tooltip.md): API documentation for SankeyTooltip (pro) - [SankeyTooltipContent](/x/api/charts/sankey-tooltip-content.md): API documentation for SankeyTooltipContent (pro) - [Scatter](/x/api/charts/scatter.md): API documentation for Scatter - [ScatterChart](/x/api/charts/scatter-chart.md): API documentation for ScatterChart - [ScatterChartPro](/x/api/charts/scatter-chart-pro.md): API documentation for ScatterChartPro (pro) - [ScatterPlot](/x/api/charts/scatter-plot.md): API documentation for ScatterPlot - [SparkLineChart](/x/api/charts/spark-line-chart.md): API documentation for SparkLineChart - [Toolbar](/x/api/charts/toolbar.md): API documentation for Toolbar - [ToolbarButton](/x/api/charts/toolbar-button.md): API documentation for ToolbarButton - [AxisConfig](/x/api/charts/axis-config.md): API documentation for AxisConfig - [BarSeries](/x/api/charts/bar-series.md): API documentation for BarSeries - [FunnelSeries](/x/api/charts/funnel-series.md): API documentation for FunnelSeries - [HeatmapSeries](/x/api/charts/heatmap-series.md): API documentation for HeatmapSeries - [LineSeries](/x/api/charts/line-series.md): API documentation for LineSeries - [PieSeries](/x/api/charts/pie-series.md): API documentation for PieSeries - [RadarSeries](/x/api/charts/radar-series.md): API documentation for RadarSeries - [ScatterSeries](/x/api/charts/scatter-series.md): API documentation for ScatterSeries - [LegendItemParams](/x/api/charts/legend-item-params.md): API documentation for LegendItemParams - [ChartImageExportOptions](/x/api/charts/chart-image-export-options.md): API documentation for ChartImageExportOptions - [ChartPrintExportOptions](/x/api/charts/chart-print-export-options.md): API documentation for ChartPrintExportOptions - [Overview](/x/react-charts/hooks.md): The package provides a set of hooks to access chart data and utilities for building custom components. - [useSeries](/x/react-charts/hooks/use-series.md): Access raw series data for all chart types. - [useLegend](/x/react-charts/hooks/use-legend.md): Access formatted legend data for creating custom legend components. - [useDrawingArea](/x/react-charts/hooks/use-drawing-area.md): Access the chart's drawing area dimensions and coordinates. - [useScale](/x/react-charts/hooks/use-scale.md): Access D3 scale functions for coordinate transformations. - [useAxes](/x/react-charts/hooks/use-axes.md): Access axis configuration and properties for cartesian and polar charts. - [useDataset](/x/react-charts/hooks/use-dataset.md): Access the dataset used to populate series and axes data. - [Plugins](/x/react-charts/plugins.md): The library relies on two systems to perform data processing: the plugins and the series config. --- ## Tree View This is the documentation for the Tree View package. It contains comprehensive guides, components, and utilities for building user interfaces. - [Quickstart](/x/react-tree-view/quickstart.md): Install the MUI X Tree View package and start building. ### Simple Tree View - [Items](/x/react-tree-view/simple-tree-view/items.md): Learn how to add simple data to the Tree View component. - [Selection](/x/react-tree-view/simple-tree-view/selection.md): Learn how to enable item selection for the Tree View component. - [Expansion](/x/react-tree-view/simple-tree-view/expansion.md): Learn how to handle expanding and collapsing Tree View items. - [Customization](/x/react-tree-view/simple-tree-view/customization.md): Learn how to customize the Simple Tree View component. - [Focus](/x/react-tree-view/simple-tree-view/focus.md): Learn how to focus Tree View items. ### Rich Tree View - [Items](/x/react-tree-view/rich-tree-view/items.md): Pass data to your Tree View. - [Selection](/x/react-tree-view/rich-tree-view/selection.md): Handle how users can select items. - [Expansion](/x/react-tree-view/rich-tree-view/expansion.md): Handle how users can expand and collapse items. - [Customization](/x/react-tree-view/rich-tree-view/customization.md): Learn how to customize the Rich Tree View component. - [Focus](/x/react-tree-view/rich-tree-view/focus.md): Learn how to focus Tree View items. - [Label editing](/x/react-tree-view/rich-tree-view/editing.md): Learn how to edit Tree View item labels. 🆕 - [Lazy loading](/x/react-tree-view/rich-tree-view/lazy-loading.md): Lazy load the data from your Tree View. (pro) 🆕 - [Ordering](/x/react-tree-view/rich-tree-view/ordering.md): Let users drag and drop items in the Tree View to reorder them. (pro) 🆕 ### Main features - [Accessibility](/x/react-tree-view/accessibility.md): Learn how the Tree View implements accessibility features and guidelines, including keyboard navigation that follows international standards. - [Item customization](/x/react-tree-view/tree-item-customization.md): Learn how to customize the Tree Item component. ### Resources - [RichTreeView](/x/api/tree-view/rich-tree-view.md): API documentation for RichTreeView - [RichTreeViewPro](/x/api/tree-view/rich-tree-view-pro.md): API documentation for RichTreeViewPro (pro) - [SimpleTreeView](/x/api/tree-view/simple-tree-view.md): API documentation for SimpleTreeView - [TreeItem](/x/api/tree-view/tree-item.md): API documentation for TreeItem - [TreeItemDragAndDropOverlay](/x/api/tree-view/tree-item-drag-and-drop-overlay.md): API documentation for TreeItemDragAndDropOverlay - [TreeItemIcon](/x/api/tree-view/tree-item-icon.md): API documentation for TreeItemIcon - [TreeItemProvider](/x/api/tree-view/tree-item-provider.md): API documentation for TreeItemProvider --- ## Data Grid This is the documentation for the Data Grid package. It contains comprehensive guides, components, and utilities for building user interfaces. - [Quickstart](/x/react-data-grid/quickstart.md): Install the MUI X Data Grid package and start building your React data table. - [Features](/x/react-data-grid/features.md): Explore all of the available features in each of the Data Grid packages. ### Demos - [time data](/x/react-data-grid/demos/real-time-data.md): Real-time data updates in the Data Grid, using simulated market data to showcase live changes. - [Time off calendar](/x/react-data-grid/demos/time-off-calendar.md): Date range visualization in the Data Grid, using a calendar UI to display and manage time periods. - [Inventory](/x/react-data-grid/demos/inventory.md): An inventory dashboard for vendors showcasing product availability. ### Main features - [Layout](/x/react-data-grid/layout.md): The Data Grid offers multiple layout modes. #### Columns - [Column definition](/x/react-data-grid/column-definition.md): Define your columns. - [Column dimensions](/x/react-data-grid/column-dimensions.md): Customize the dimensions and resizing behavior of your columns. - [Column visibility](/x/react-data-grid/column-visibility.md): Define which columns are visible. - [Custom columns](/x/react-data-grid/custom-columns.md): Create custom column types. - [Column header](/x/react-data-grid/column-header.md): Customize your columns header. - [Column menu](/x/react-data-grid/column-menu.md): Customize your columns menu. - [Column spanning](/x/react-data-grid/column-spanning.md): Span cells across several columns. - [Column groups](/x/react-data-grid/column-groups.md): Group your columns. - [Column reordering](/x/react-data-grid/column-ordering.md): The Data Grid Pro lets users drag and drop columns to reorder them. (pro) - [Column pinning](/x/react-data-grid/column-pinning.md): Implement pinning to keep columns in the Data Grid visible at all times. (pro) - [Recipes](/x/react-data-grid/column-recipes.md): Advanced column customization recipes. #### Rows - [Row definition](/x/react-data-grid/row-definition.md): Define your rows. - [Row updates](/x/react-data-grid/row-updates.md): Always keep your rows up to date. - [Row height](/x/react-data-grid/row-height.md): Customize the height of your rows. - [Row spanning](/x/react-data-grid/row-spanning.md): Span cells across several rows. 🆕 - [detail row panels](/x/react-data-grid/master-detail.md): Implement master-detail row panels to let users view extended information without leaving the Data Grid. (pro) - [Row reordering](/x/react-data-grid/row-ordering.md): The Data Grid Pro lets users drag and drop rows to reorder them. (pro) - [Row pinning](/x/react-data-grid/row-pinning.md): Implement pinning to keep rows in the Data Grid visible at all times. (pro) - [Recipes](/x/react-data-grid/row-recipes.md): Advanced row customization recipes. - [Cells](/x/react-data-grid/cells.md): Learn how to customize the rendered elements and values of a cell. #### Editing - [Overview](/x/react-data-grid/editing.md): The Data Grid has built-in support for cell and row editing. - [Persistence](/x/react-data-grid/editing/persistence.md): Persisting edited rows. - [Custom edit component](/x/react-data-grid/editing/custom-edit-component.md): Creating custom edit component. - [Editing events](/x/react-data-grid/editing/editing-events.md): Using editing events. - [Recipes editing](/x/react-data-grid/recipes-editing.md): Advanced grid customization recipes. - [Sorting](/x/react-data-grid/sorting.md): Easily sort your rows based on one or several criteria. #### Filtering - [Overview](/x/react-data-grid/filtering.md): Easily filter your rows based on one or several criteria. - [Customization](/x/react-data-grid/filtering/customization.md): Ways to customize your filters. - [Quick filter](/x/react-data-grid/filtering/quick-filter.md): One filter field to quickly filter grid. - [side filtering](/x/react-data-grid/filtering/server-side.md): Filter rows on the server. - [filters](/x/react-data-grid/filtering/multi-filters.md): Let end users apply multiple filters to the Data Grid simultaneously. (pro) - [Header filters](/x/react-data-grid/filtering/header-filters.md): Give users quick-access column filters in the Data Grid header. (pro) - [Recipes](/x/react-data-grid/filtering-recipes.md): Advanced filtering customization recipes. - [Pagination](/x/react-data-grid/pagination.md): Easily paginate your rows and only fetch what you need. #### Selection - [Row selection](/x/react-data-grid/row-selection.md): Row selection lets users select and highlight a single row or multiple rows that they can then take action on. - [Cell selection](/x/react-data-grid/cell-selection.md): Let users select individual cells or a range of cells. (premium) - [Virtualization](/x/react-data-grid/virtualization.md): The grid is high performing thanks to its rows and columns virtualization engine. - [Accessibility](/x/react-data-grid/accessibility.md): Learn how the Data Grid implements accessibility features and guidelines, including keyboard navigation that follows international standards. - [Localization](/x/react-data-grid/localization.md): The Data Grid's localization features provide the appropriate translations and formatting for users around the world. ### Advanced features - [Tree data](/x/react-data-grid/tree-data.md): Use tree data to render rows with parent-child relationships in the Data Grid. (pro) #### Row grouping - [Overview](/x/react-data-grid/row-grouping.md): Group rows together based on column values in the Data Grid. - [Recipes](/x/react-data-grid/recipes-row-grouping.md): Advanced grid customization recipes. - [Aggregation](/x/react-data-grid/aggregation.md): Add aggregation functions to the Data Grid to let users combine row values. (premium) #### Pivoting - [Overview](/x/react-data-grid/pivoting.md): Rearrange rows and columns to view data from multiple perspectives. - [Export](/x/react-data-grid/export.md): Export the rows in CSV or Excel formats, or use the browser's print dialog to print or save as PDF. - [Copy and paste](/x/react-data-grid/clipboard.md): Copy and paste data using clipboard. - [Scrolling](/x/react-data-grid/scrolling.md): This section presents how to programmatically control the scroll. - [List view](/x/react-data-grid/list-view.md): Display data in a single-column list view for a more compact Data Grid on smaller screens and mobile devices. (pro) #### Server-side data - [Overview](/x/react-data-grid/server-side-data.md): Learn how to work with server-side data in the Data Grid using the Data Source layer. - [Tree data](/x/react-data-grid/server-side-data/tree-data.md): Implement lazy-loading server-side tree data in the Data Grid using the Data Source layer. (pro) - [Lazy loading](/x/react-data-grid/server-side-data/lazy-loading.md): Implement lazy-loading rows with server-side data in the Data Grid using the Data Source layer. (pro) - [Row grouping](/x/react-data-grid/server-side-data/row-grouping.md): Implement row grouping with server-side data in the Data Grid using the Data Source layer. (premium) - [Aggregation](/x/react-data-grid/server-side-data/aggregation.md): Implement aggregation with server-side data in the Data Grid using the Data Source layer. (premium) - [Pivoting](/x/react-data-grid/server-side-data/pivoting.md): Implement pivoting with server-side data in the Data Grid using the Data Source layer. (premium) - [Recipes](/x/react-data-grid/server-side-data/recipes.md): Recipes for advanced data source use-cases. - [Charts integration](/x/react-data-grid/charts-integration.md): Use the MUI X Charts to visualize data from the Data Grid. (premium) - [AI Assistant](/x/react-data-grid/ai-assistant.md): Translate natural language into Data Grid views. (premium) 🆕 ### Components - [Toolbar](/x/react-data-grid/components/toolbar.md): Add custom actions and controls to the Data Grid. - [Export](/x/react-data-grid/components/export.md): Let users export the Data Grid for Excel, CSV, or printing. - [Quick Filter](/x/react-data-grid/components/quick-filter.md): Provide users with an expandable search field to filter data in the Data Grid. - [Columns Panel](/x/react-data-grid/components/columns-panel.md): Customize the Data Grid's columns panel. (planned) - [Filter Panel](/x/react-data-grid/components/filter-panel.md): Customize the Data Grid's filter panel. (planned) - [Prompt Field](/x/react-data-grid/components/prompt-field.md): Provide users with a prompt field to interact with the AI assistant. (premium) - [Pivot Panel](/x/react-data-grid/components/pivot-panel.md): Customize the Data Grid's pivot panel. (premium) (planned) - [Charts Panel](/x/react-data-grid/components/charts-panel.md): Customize the Data Grid's Charts panel. (premium) (planned) - [AI Assistant Panel](/x/react-data-grid/components/ai-assistant-panel.md): Customize the Data Grid's AI assistant panel. (premium) (planned) ### Customization - [Styling basics](/x/react-data-grid/style.md): The grid CSS can be easily overwritten. - [Styling recipes](/x/react-data-grid/style-recipes.md): Advanced grid styling recipes. - [Overlays](/x/react-data-grid/overlays.md): The various Data Grid overlays. ### Resources - [API object](/x/react-data-grid/api-object.md): Interact with the Data Grid using its API. - [Events](/x/react-data-grid/events.md): Subscribe to the events emitted by the Data Grid to trigger custom behavior. - [State](/x/react-data-grid/state.md): Initialize and read the state of the Data Grid. - [Performance](/x/react-data-grid/performance.md): Follow these recommendations to improve your Data Grid's performance. ### API reference - [Index](/x/api/data-grid.md): API documentation for Index - [AiAssistantPanelTrigger](/x/api/data-grid/ai-assistant-panel-trigger.md): API documentation for AiAssistantPanelTrigger (premium) - [ChartsPanelTrigger](/x/api/data-grid/charts-panel-trigger.md): API documentation for ChartsPanelTrigger (premium) - [ColumnsPanelTrigger](/x/api/data-grid/columns-panel-trigger.md): API documentation for ColumnsPanelTrigger - [DataGrid](/x/api/data-grid/data-grid.md): API documentation for DataGrid - [DataGridPremium](/x/api/data-grid/data-grid-premium.md): API documentation for DataGridPremium (premium) - [DataGridPro](/x/api/data-grid/data-grid-pro.md): API documentation for DataGridPro (pro) - [ExportCsv](/x/api/data-grid/export-csv.md): API documentation for ExportCsv - [ExportExcel](/x/api/data-grid/export-excel.md): API documentation for ExportExcel (premium) - [ExportPrint](/x/api/data-grid/export-print.md): API documentation for ExportPrint - [FilterPanelTrigger](/x/api/data-grid/filter-panel-trigger.md): API documentation for FilterPanelTrigger - [GridChartsPanel](/x/api/data-grid/grid-charts-panel.md): API documentation for GridChartsPanel (premium) - [GridChartsRendererProxy](/x/api/data-grid/grid-charts-renderer-proxy.md): API documentation for GridChartsRendererProxy (premium) - [GridFilterForm](/x/api/data-grid/grid-filter-form.md): API documentation for GridFilterForm - [GridFilterPanel](/x/api/data-grid/grid-filter-panel.md): API documentation for GridFilterPanel - [GridToolbarQuickFilter](/x/api/data-grid/grid-toolbar-quick-filter.md): API documentation for GridToolbarQuickFilter - [PivotPanelTrigger](/x/api/data-grid/pivot-panel-trigger.md): API documentation for PivotPanelTrigger (premium) - [PromptField](/x/api/data-grid/prompt-field.md): API documentation for PromptField (premium) - [PromptFieldControl](/x/api/data-grid/prompt-field-control.md): API documentation for PromptFieldControl (premium) - [PromptFieldRecord](/x/api/data-grid/prompt-field-record.md): API documentation for PromptFieldRecord (premium) - [PromptFieldSend](/x/api/data-grid/prompt-field-send.md): API documentation for PromptFieldSend (premium) - [QuickFilter](/x/api/data-grid/quick-filter.md): API documentation for QuickFilter - [QuickFilterClear](/x/api/data-grid/quick-filter-clear.md): API documentation for QuickFilterClear - [QuickFilterControl](/x/api/data-grid/quick-filter-control.md): API documentation for QuickFilterControl - [QuickFilterTrigger](/x/api/data-grid/quick-filter-trigger.md): API documentation for QuickFilterTrigger - [Toolbar](/x/api/data-grid/toolbar.md): API documentation for Toolbar - [ToolbarButton](/x/api/data-grid/toolbar-button.md): API documentation for ToolbarButton - [GridApi](/x/api/data-grid/grid-api.md): API documentation for GridApi - [GridCellParams](/x/api/data-grid/grid-cell-params.md): API documentation for GridCellParams - [GridColDef](/x/api/data-grid/grid-col-def.md): API documentation for GridColDef - [GridSingleSelectColDef](/x/api/data-grid/grid-single-select-col-def.md): API documentation for GridSingleSelectColDef - [GridActionsColDef](/x/api/data-grid/grid-actions-col-def.md): API documentation for GridActionsColDef - [GridListViewColDef](/x/api/data-grid/grid-list-view-col-def.md): API documentation for GridListViewColDef - [GridExportStateParams](/x/api/data-grid/grid-export-state-params.md): API documentation for GridExportStateParams - [GridFilterItem](/x/api/data-grid/grid-filter-item.md): API documentation for GridFilterItem - [GridFilterModel](/x/api/data-grid/grid-filter-model.md): API documentation for GridFilterModel - [GridFilterOperator](/x/api/data-grid/grid-filter-operator.md): API documentation for GridFilterOperator - [GridRenderContext](/x/api/data-grid/grid-render-context.md): API documentation for GridRenderContext - [GridRowClassNameParams](/x/api/data-grid/grid-row-class-name-params.md): API documentation for GridRowClassNameParams - [GridRowParams](/x/api/data-grid/grid-row-params.md): API documentation for GridRowParams - [GridRowSpacingParams](/x/api/data-grid/grid-row-spacing-params.md): API documentation for GridRowSpacingParams - [GridRowOrderChangeParams](/x/api/data-grid/grid-row-order-change-params.md): API documentation for GridRowOrderChangeParams - [GridAggregationFunction](/x/api/data-grid/grid-aggregation-function.md): API documentation for GridAggregationFunction - [GridAggregationFunctionDataSource](/x/api/data-grid/grid-aggregation-function-data-source.md): API documentation for GridAggregationFunctionDataSource - [GridCsvExportOptions](/x/api/data-grid/grid-csv-export-options.md): API documentation for GridCsvExportOptions - [GridPrintExportOptions](/x/api/data-grid/grid-print-export-options.md): API documentation for GridPrintExportOptions - [GridExcelExportOptions](/x/api/data-grid/grid-excel-export-options.md): API documentation for GridExcelExportOptions ### Tutorials - [side data](/x/react-data-grid/tutorials/server-side-data.md) --- # Source: https://mui.com/x/api/date-pickers/localization-provider.md # LocalizationProvider API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date format and localization](/x/react-date-pickers/adapters-locale/) - [Calendar systems](/x/react-date-pickers/calendar-systems/) - [Translated components](/x/react-date-pickers/localization/) - [UTC and timezones](/x/react-date-pickers/timezone/) ## Import ```jsx import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; // or import { LocalizationProvider } from '@mui/x-date-pickers'; // or import { LocalizationProvider } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | adapterLocale | `any` | - | No | | | dateAdapter | `func` | - | No | | | dateFormats | `{ dayOfMonth?: string, dayOfMonthFull?: string, fullDate?: string, fullTime12h?: string, fullTime24h?: string, hours12h?: string, hours24h?: string, keyboardDate?: string, keyboardDateTime12h?: string, keyboardDateTime24h?: string, meridiem?: string, minutes?: string, month?: string, monthShort?: string, normalDate?: string, normalDateWithWeekday?: string, seconds?: string, shortDate?: string, weekday?: string, weekdayShort?: string, year?: string }` | - | No | | | dateLibInstance | `any` | - | No | | | localeText | `object` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/LocalizationProvider/LocalizationProvider.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/LocalizationProvider/LocalizationProvider.tsx) --- # Source: https://mui.com/x/react-data-grid/localization.md # Source: https://mui.com/x/react-charts/localization.md # Source: https://mui.com/x/react-date-pickers/localization.md --- productId: x-date-pickers title: Date and Time Pickers - Translated components components: LocalizationProvider githubLabel: 'scope: pickers' packageName: '@mui/x-date-pickers' --- # Translated components Date and Time Pickers support translations between languages. As with all MUI X components, you can modify text and translations inside the Date and Time Pickers. You can find all the translation keys supported in [the source](https://github.com/mui/mui-x/blob/HEAD/packages/x-date-pickers/src/locales/utils/pickersLocaleTextApi.ts) in the GitHub repository. The default locale of MUI X is English (United States). If you want to use other locales, follow the instructions below. :::warning This page focuses on translating the text inside the Date and Time Pickers. If you need to change the formatting of the text to conform to a given locale, visit the [Date format and localization](/x/react-date-pickers/adapters-locale/) page. ::: ## Set translations globally ### Using the theme To translate all your components from `@mui/x-date-pickers` and `@mui/x-date-pickers-pro`, import the locale from `@mui/x-date-pickers` (see the [list of supported locales below](#supported-locales)). ```jsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import { deDE } from '@mui/x-date-pickers/locales'; const theme = createTheme( { palette: { primary: { main: '#1976d2' }, }, }, deDE, // use 'de' locale for UI texts (start, next month, ...) ); function App({ children }) { return {children}; } ``` Note that `createTheme()` accepts any number of arguments. If you are already using the [translations of the core components](/material-ui/guides/localization/#locale-text) or the [translations of the Data Grid](/x/react-data-grid/localization/#locale-text), you can add `deDE` as a new argument. ```jsx import { createTheme, ThemeProvider } from '@mui/material/styles'; import { deDE as dataGridDeDE } from '@mui/x-data-grid'; import { deDE as coreDeDE } from '@mui/material/locale'; import { deDE } from '@mui/x-date-pickers/locales'; const theme = createTheme( { palette: { primary: { main: '#1976d2' }, }, }, deDE, // x-date-pickers translations dataGridDeDE, // x-data-grid translations coreDeDE, // core translations ); function App({ children }) { return {children}; } ``` ### Using LocalizationProvider If you want to pass language translations without using `createTheme()` and `ThemeProvider`, you can directly load the language translations from the `@mui/x-date-pickers` or `@mui/x-date-pickers-pro` package and pass them to the `LocalizationProvider`. ```jsx import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'; import { deDE } from '@mui/x-date-pickers/locales'; import { DatePicker } from '@mui/x-date-pickers/DatePicker'; ; ``` ## Set translations locally You can also customize the translations of a single component. If you want to customize some translations on a specific component, you can use the `localeText` prop exposed by all Picker components. ```jsx ``` :::info This method can be combined with the ones shown above. If you pass a localization through `LocalizationProvider` or the theme, and you provide translation keys through the `localeText` prop of a picker at the same time, then only the latter translation keys will be overridden. ```tsx ``` This will produce the following result: - "Today" button with text **Now** taken from the Localization Provider's `localeText` prop - "Clear" button with text **Vider** overridden by the Date Picker's `localeText` prop ::: ## Supported locales ```jsx import LocalisationTable from 'docsx/src/modules/components/LocalizationTable'; import data from './data.json'; export default function PickersLocalisationTableNoSnap() { return ; } ``` You can [find the source](https://github.com/mui/mui-x/tree/HEAD/packages/x-date-pickers/src/locales) in the GitHub repository. To create your own translation or to customize the English text, copy this file to your project, make any changes needed and import the locale from there. Note that these translations of the date and time picker components depend on the [Localization strategy](/material-ui/guides/localization/) of the whole library. ## Access the translations in slots and subcomponents You can use the `usePickerTranslations` hook to access the translations in your custom components. ```tsx import { usePickerTranslations } from '@mui/x-date-pickers/hooks'; const translations = usePickerTranslations(); ``` :::info See [Custom slots and subcomponents—Action bar](/x/react-date-pickers/custom-components/#component) for more details. ::: --- # Source: https://mui.com/x/api/charts/mark-element.md # MarkElement API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Line demos](/x/react-charts/line-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { MarkElement } from '@mui/x-charts/LineChart'; // or import { MarkElement } from '@mui/x-charts'; // or import { MarkElement } from '@mui/x-charts-pro'; // or import { MarkElement } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | dataIndex | `number` | - | Yes | | | shape | `'circle' \| 'cross' \| 'diamond' \| 'square' \| 'star' \| 'triangle' \| 'wye'` | - | Yes | | | hidden | `bool` | `false` | No | | | isFaded | `bool` | `false` | No | | | isHighlighted | `bool` | `false` | No | | | skipAnimation | `bool` | - | No | | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | animate | Styles applied to the root element when animation is not skipped. | | - | faded | Styles applied to the root element when faded. | | - | highlighted | Styles applied to the root element when highlighted. | | - | root | Styles applied to the root element. | | - | series | Styles applied to the root element for a specified series. Needs to be suffixed with the series ID: `.${markElementClasses.series}-${seriesId}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/MarkElement.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/MarkElement.tsx) --- # Source: https://mui.com/x/api/charts/mark-plot.md # MarkPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Areas demos](/x/react-charts/areas-demo/) - [Charts - Line demos](/x/react-charts/line-demo/) - [Charts - Lines](/x/react-charts/lines/) ## Import ```jsx import { MarkPlot } from '@mui/x-charts/LineChart'; // or import { MarkPlot } from '@mui/x-charts'; // or import { MarkPlot } from '@mui/x-charts-pro'; // or import { MarkPlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | onItemClick | `function(event: React.MouseEvent, lineItemIdentifier: LineItemIdentifier) => void` | - | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | mark | `undefined` | - | | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/LineChart/MarkPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/LineChart/MarkPlot.tsx) --- # Source: https://mui.com/x/react-data-grid/master-detail.md --- title: Data Grid - Master-detail row panels --- # Data Grid - Master-detail row panels [](/x/introduction/licensing/#pro-plan 'Pro plan') Implement master-detail row panels to let users view extended information without leaving the Data Grid. ## What is the master-detail pattern? "Master-detail" is a design pattern for organizing information in which the "master" area lists the data and the "detail" sections provide further information about each item. The Data Grid Pro provides the tools to implement master-detail row panels. These are useful whenever you need to give end users additional information about row items without navigating away from the Grid. A common example of this pattern is found in many email clients—users can click on an email from the master list to see its contents (details) as well as actions they can take such as replying, forwarding, and deleting. To expand a row, click on the **+** icon or press Space when focused on a cell in the detail toggle column: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import ButtonGroup from '@mui/material/ButtonGroup'; import Divider from '@mui/material/Divider'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; import Stack from '@mui/material/Stack'; import DeleteIcon from '@mui/icons-material/Delete'; import ForwardIcon from '@mui/icons-material/Forward'; import ReplyIcon from '@mui/icons-material/Reply'; import { DataGridPro, GridColDef, useGridApiContext, GridRowParams, GRID_DETAIL_PANEL_TOGGLE_FIELD, useGridSelector, gridDimensionsSelector, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomEmail } from '@mui/x-data-grid-generator'; function DetailPanelContent({ row: rowProp }: { row: Email }) { const apiRef = useGridApiContext(); const width = useGridSelector(apiRef, gridDimensionsSelector).viewportInnerSize .width; return ( {`Subject: ${rowProp.subject}`} {`Date: ${rowProp.date.toLocaleString()}`} {`From: ${rowProp.name} <${rowProp.email}>`} {`To: me <${randomEmail()}>`} Artisan bitters street art photo booth you probably have not heard of them slow-carb food truck. Meh narwhal tumeric bodega boys street art Brooklyn venmo. Kinfolk wolf iceland banjo, pitchfork cupping banh mi vexillologist cliche locavore venmo. Yuccie kombucha hashtag, bicycle rights umami truffaut mumblecore Brooklyn neutral milk hotel aesthetic. Wolf plaid leggings butcher solarpunk shabby chic cliche. ); } const columns: GridColDef[] = [ { field: 'name', headerName: 'From' }, { field: 'email', headerName: 'Email', width: 200 }, { field: 'subject', headerName: 'Subject', width: 300 }, { field: 'date', type: 'date', headerName: 'Date' }, ]; const rows = [ { id: 1, name: 'Matheus', email: randomEmail(), subject: 'Readymade asymmetrical organic salad', date: randomCreatedDate(), }, { id: 2, name: 'Olivier', email: randomEmail(), subject: 'Chillwave solarpunk grailed waistcoat ramps', date: randomCreatedDate(), }, { id: 3, name: 'Flavien', email: randomEmail(), subject: 'Williamsburg ugh YOLO', date: randomCreatedDate(), }, { id: 4, name: 'Danail', email: randomEmail(), subject: 'Humblebrag la croix hexagon big mood', date: randomCreatedDate(), }, { id: 5, name: 'Alexandre', email: randomEmail(), subject: 'Vinyl chambray kitsch', date: randomCreatedDate(), }, { id: 6, name: 'José', email: randomEmail(), subject: 'Hella kogi pour-over wolf', date: randomCreatedDate(), }, ]; type Email = (typeof rows)[number]; export default function MasterDetailEmailExample() { const getDetailPanelContent = React.useCallback( ({ row }: GridRowParams) => , [], ); const getDetailPanelHeight = React.useCallback(() => 400, []); return ( ); } ``` ## Implementing master-detail row panels To create master-detail row panels, pass a function to the `getDetailPanelContent` prop that returns the content to be rendered inside the panel. You can use any valid React element—even another Data Grid. ```tsx
Row ID: {row.id}
} /> ``` ### Detail panel height By default, the detail panel height is 500px. You can customize this by passing a function to the `getDetailPanelHeight` prop. This function must return either a number or `"auto"`: - If it returns a number, then the panel will use that value (in pixels) for the height. - If it returns `"auto"`, then the height will be derived from the content. ```tsx // fixed height:
Row ID: {row.id}
} getDetailPanelHeight={({ row }) => 100} /> // height derived from content:
Row ID: {row.id}
} getDetailPanelHeight={({ row }) => 'auto'} /> ``` :::info The `getDetailPanelContent` and `getDetailPanelHeight` props are called with a [`GridRowParams`](/x/api/data-grid/grid-row-params/) object, which lets you return a different value for each row. ::: The demo below shows master-detail panels with heights derived from their contents: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Grid from '@mui/material/Grid'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; import Stack from '@mui/material/Stack'; import DeleteIcon from '@mui/icons-material/Delete'; import { DataGridPro, GridColDef, DataGridProProps, useGridApiContext, GridActionsCellItem, GridActionsCell, GridRenderCellParams, } from '@mui/x-data-grid-pro'; import { randomId, randomCreatedDate, randomPrice, randomCurrency, randomCountry, randomCity, randomEmail, randomInt, randomAddress, randomCommodity, } from '@mui/x-data-grid-generator'; function generateProduct() { return { id: randomId(), name: randomCommodity(), quantity: randomInt(1, 5), unitPrice: randomPrice(1, 1000), }; } const DetailPanelActionHandlersContext = React.createContext< ((productId: string) => void) | undefined >(undefined); function DetailPanelActionsCell(props: GridRenderCellParams) { const deleteProduct = React.useContext(DetailPanelActionHandlersContext); if (!deleteProduct) { throw new Error('DetailPanelActionHandlersContext is empty'); } return ( } label="delete" onClick={() => deleteProduct(props.row.id)} /> ); } function DetailPanelContent({ row: rowProp }: { row: Customer }) { const apiRef = useGridApiContext(); const addProduct = React.useCallback(() => { const newProduct = generateProduct(); apiRef.current.updateRows([ { ...rowProp, products: [...rowProp.products, newProduct] }, ]); }, [apiRef, rowProp]); const deleteProduct = React.useCallback( (productId: string) => () => { const newProducts = rowProp.products.filter( (product) => product.id !== productId, ); apiRef.current.updateRows([{ ...rowProp, products: newProducts }]); }, [apiRef, rowProp], ); const columns = React.useMemo[]>( () => [ { field: 'name', headerName: 'Product', flex: 1, editable: true }, { field: 'quantity', headerName: 'Quantity', align: 'center', headerAlign: 'center', type: 'number', editable: true, }, { field: 'unitPrice', headerName: 'Unit Price', type: 'number' }, { field: 'total', headerName: 'Total', type: 'number', valueGetter: (value, row) => row.quantity * row.unitPrice, }, { field: 'actions', headerName: '', type: 'actions', width: 50, renderCell: (params) => , }, ], [], ); return ( {`Order #${rowProp.id}`} Customer information {rowProp.customer} {rowProp.email} Shipping address {rowProp.address} {`${rowProp.city}, ${rowProp.country.label}`}
); } const columns: GridColDef[] = [ { field: 'id', headerName: 'Order ID' }, { field: 'customer', headerName: 'Customer', width: 200 }, { field: 'date', type: 'date', headerName: 'Placed at' }, { field: 'currency', headerName: 'Currency' }, { field: 'total', type: 'number', headerName: 'Total', valueGetter: (value, row) => { const subtotal = row.products.reduce( (acc: number, product: any) => product.unitPrice * product.quantity, 0, ); const taxes = subtotal * 0.05; return subtotal + taxes; }, }, ]; function generateProducts() { const quantity = randomInt(1, 5); return [...Array(quantity)].map(generateProduct); } const rows = [ { id: 1, customer: 'Matheus', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 2, customer: 'Olivier', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 3, customer: 'Flavien', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 4, customer: 'Danail', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 5, customer: 'Alexandre', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, ]; type Customer = (typeof rows)[number]; export default function DetailPanelAutoHeight() { const getDetailPanelContent = React.useCallback< NonNullable >(({ row }) => , []); const getDetailPanelHeight = React.useCallback< NonNullable >(() => 'auto' as const, []); return ( ); } ``` :::warning Always memoize the function provided to `getDetailPanelContent` and `getDetailPanelHeight`. The Data Grid depends on the referential value of these props to cache their values and optimize the rendering. ```tsx const getDetailPanelContent = React.useCallback(() => { ... }, []); ``` ::: ## Controlling expanded detail panels To control which rows are expanded, pass a set of row IDs to the `detailPanelExpandedRowIds` prop. You can pass a callback function to the `onDetailPanelExpandedRowIds` prop to detect when a row is expanded or collapsed. To initialize the Data Grid with specific row panels expanded, use the `initialState` prop as shown below: ```tsx ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { DataGridPro, GridColDef, GridRowsProp, GridRowId, DataGridProProps, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomCurrency, randomEmail, randomPrice, } from '@mui/x-data-grid-generator'; import Alert from '@mui/material/Alert'; export default function ControlMasterDetail() { const [detailPanelExpandedRowIds, setDetailPanelExpandedRowIds] = React.useState( () => new Set(), ); const handleDetailPanelExpandedRowIdsChange = React.useCallback< NonNullable >((newIds) => { setDetailPanelExpandedRowIds(newIds); }, []); return ( detailPanelExpandedRowIds: {JSON.stringify(detailPanelExpandedRowIds)} ( {`Order #${row.id}`} )} getDetailPanelHeight={() => 50} detailPanelExpandedRowIds={detailPanelExpandedRowIds} onDetailPanelExpandedRowIdsChange={handleDetailPanelExpandedRowIdsChange} /> ); } const columns: GridColDef[] = [ { field: 'id', headerName: 'Order ID' }, { field: 'customer', headerName: 'Customer', width: 200 }, { field: 'date', type: 'date', headerName: 'Placed at' }, { field: 'currency', headerName: 'Currency' }, { field: 'total', type: 'number', headerName: 'Total' }, ]; const rows: GridRowsProp = [ { id: 1, customer: 'Matheus', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 2, customer: 'Olivier', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 3, customer: 'Flavien', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 4, customer: 'Danail', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 5, customer: 'Alexandre', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, ]; ``` ## Lazy-loading detail panel content You don't need to provide the content for detail panels upfront—instead, you can load it lazily when a row is expanded. In the following example, the `` component fetches data on mount. This component is used by the `getDetailPanelContent` prop to render the detail panel content. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; import Stack from '@mui/material/Stack'; import { DataGridPro, DataGridProProps, GridColDef } from '@mui/x-data-grid-pro'; import { randomEmail, randomInt, randomCommodity, randomPrice, randomTraderName, randomId, } from '@mui/x-data-grid-generator'; import { DataGridProps, GridRowId } from '@mui/x-data-grid'; type Products = Awaited>; const DetailPanelDataCache = React.createContext(new Map()); async function getProducts(orderId: Customer['id']) { await new Promise((resolve) => { setTimeout(resolve, 1000); }); const quantity = randomInt(1, 5); return [...Array(quantity)].map((_, index) => ({ id: index, orderId, name: randomCommodity(), quantity: randomInt(1, 5), unitPrice: randomPrice(1, 1000), })); } function DetailPanelContent({ row: rowProp }: { row: Customer }) { const [isLoading, setLoading] = React.useState(true); const [products, setProducts] = React.useState< Awaited> >([]); const detailPanelDataCache = React.useContext(DetailPanelDataCache); React.useEffect(() => { let isMounted = true; (async () => { if (!detailPanelDataCache.has(rowProp.id)) { console.log('fetching detail panel content for row', rowProp.id); const response = await getProducts(rowProp.id); // Store the data in cache so that when detail panel unmounts due to virtualization, the data is not lost detailPanelDataCache.set(rowProp.id, response); } const result = detailPanelDataCache.get(rowProp.id)!; if (!isMounted) { return; } setProducts(result); setLoading(false); })(); return () => { isMounted = false; }; }, [rowProp.id, detailPanelDataCache]); return ( {`Order #${rowProp.id}`} row.quantity * row.unitPrice, }, ]} rows={products} sx={{ flex: 1 }} hideFooter /> ); } const columns: GridColDef[] = [ { field: 'customer', headerName: 'Customer', width: 200 }, { field: 'email', headerName: 'Email', width: 200 }, ]; function getRow() { return { id: randomId(), customer: randomTraderName(), email: randomEmail(), }; } const rows: ReturnType[] = []; for (let i = 0; i < 100; i += 1) { rows.push(getRow()); } type Customer = (typeof rows)[number]; const getDetailPanelContent: DataGridProps['getDetailPanelContent'] = (params) => ( ); const getDetailPanelHeight = () => 240; export default function LazyLoadingDetailPanel() { const detailPanelDataCache = React.useRef(new Map()).current; const handleDetailPanelExpansionChange = React.useCallback< NonNullable >( (newExpandedRowIds) => { // Only keep cached data for detail panels that are still expanded for (const [id] of detailPanelDataCache) { if (!newExpandedRowIds.has(id)) { detailPanelDataCache.delete(id); } } }, [detailPanelDataCache], ); return ( ); } ``` :::warning Lazy loading panels with auto height can lead to scrolling issues. This happens because panels that are re-mounted briefly have a smaller height than they had when they were removed from the DOM by the virtualizer. In that case, cache the last panel heights and provide those values from `getDetailPanelHeight`. Check the [Lazy loading detail panels with auto height](/x/react-data-grid/row-recipes/#lazy-loading-detail-panels-with-auto-height) recipe for implementation details. ::: ## Using a detail panel as a form As an alternative to the built-in [row editing feature](/x/react-data-grid/editing/#row-editing), you can render a form component inside the detail panel so users can edit the row values. The demo below shows how to implement this behavior using [react-hook-form](https://react-hook-form.com/), but other form libraries are also supported. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; import Stack from '@mui/material/Stack'; import TextField from '@mui/material/TextField'; import { useForm, Controller } from 'react-hook-form'; import { DataGridPro, GridColDef, GridRowModelUpdate, useGridApiContext, GridRowParams, } from '@mui/x-data-grid-pro'; import { randomEmail } from '@mui/x-data-grid-generator'; function DetailPanelContent({ row }: { row: Customer }) { const apiRef = useGridApiContext(); const { control, handleSubmit, formState: { isValid }, } = useForm({ defaultValues: row, mode: 'onChange', }); const onSubmit = (data: GridRowModelUpdate) => { apiRef.current.updateRows([data]); apiRef.current.toggleDetailPanel(row.id); }; return ( {`Edit Order #${row.id}`} ( )} /> ( )} />
); } const columns: GridColDef[] = [ { field: 'id', headerName: 'Order ID' }, { field: 'customer', headerName: 'Customer', width: 200 }, { field: 'email', headerName: 'Email', width: 200 }, ]; const rows = [ { id: 1, customer: 'Matheus', email: randomEmail(), }, { id: 2, customer: 'Olivier', email: randomEmail(), }, { id: 3, customer: 'Flavien', email: randomEmail(), }, { id: 4, customer: 'Danail', email: randomEmail(), }, { id: 5, customer: 'Alexandre', email: randomEmail(), }, ]; type Customer = (typeof rows)[number]; export default function FormDetailPanel() { const getDetailPanelContent = React.useCallback( ({ row }: GridRowParams) => , [], ); const getDetailPanelHeight = React.useCallback(() => 240, []); return ( ); } ``` ## Customizing the detail panel toggle To change the icon used for the toggle, you can provide a different component for the [icon slot](/x/react-data-grid/components/#icons) as shown here: ```tsx ``` You can also completely override the toggle component by adding another column to your set with `field: GRID_DETAIL_PANEL_TOGGLE_FIELD`. This prevents the Data Grid from adding the default toggle column. Then you can add a new toggle component using [`renderCell()`](/x/react-data-grid/column-definition/#rendering-cells) as you would for any other column: ```tsx , }, ]} /> ``` Because the `field` is the only property defined, it's up to you to configure any additional options (such as filtering, sorting, or disabling the column menu). If you'd rather set up the toggle with basic options preconfigured, you can spread `GRID_DETAIL_PANEL_TOGGLE_COL_DEF` when defining the column, as shown below: ```tsx , }, ]} /> ``` You can also use this approach to change the location of the toggle column, as shown in the demo below: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import IconButton from '@mui/material/IconButton'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { DataGridPro, GridColDef, GridRowsProp, GridRenderCellParams, GridRowParams, useGridSelector, useGridApiContext, gridDetailPanelExpandedRowsContentCacheSelector, gridDetailPanelExpandedRowIdsSelector, GRID_DETAIL_PANEL_TOGGLE_COL_DEF, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomCurrency, randomEmail, randomPrice, } from '@mui/x-data-grid-generator'; export default function CustomizeDetailPanelToggle() { const getDetailPanelContent = React.useCallback( ({ row }: GridRowParams) => row.id % 2 === 0 ? {`Order #${row.id}`} : null, [], ); const getDetailPanelHeight = React.useCallback(() => 50, []); return (
); } function CustomDetailPanelToggle(props: Pick) { const { id } = props; const apiRef = useGridApiContext(); // To avoid calling ´getDetailPanelContent` all the time, the following selector // gives an object with the detail panel content for each row id. const contentCache = useGridSelector( apiRef, gridDetailPanelExpandedRowsContentCacheSelector, ); const expandedRowIds = useGridSelector( apiRef, gridDetailPanelExpandedRowIdsSelector, ); const isExpanded = expandedRowIds.has(id); // If the value is not a valid React element, it means that the row has no detail panel. const hasDetail = React.isValidElement(contentCache[id]); return ( ({ transform: `rotateZ(${isExpanded ? 180 : 0}deg)`, transition: theme.transitions.create('transform', { duration: theme.transitions.duration.shortest, }), })} fontSize="inherit" /> ); } const columns: GridColDef[] = [ { field: 'id', headerName: 'Order ID' }, { field: 'customer', headerName: 'Customer', width: 200 }, { field: 'date', type: 'date', headerName: 'Placed at' }, { field: 'currency', headerName: 'Currency' }, { field: 'total', type: 'number', headerName: 'Total' }, { ...GRID_DETAIL_PANEL_TOGGLE_COL_DEF, renderCell: (params) => ( ), }, ]; const rows: GridRowsProp = [ { id: 1, customer: 'Matheus', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 2, customer: 'Olivier', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 3, customer: 'Flavien', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 4, customer: 'Danail', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, { id: 5, customer: 'Alexandre', email: randomEmail(), date: randomCreatedDate(), currency: randomCurrency(), total: randomPrice(1, 1000), }, ]; ``` :::info As with any other cell renderer, the `value` prop is also available, and it corresponds to the state of the row: it's set to `true` when expanded and `false` when collapsed. ::: ## Customizing the detail panel column header To render a custom header for the detail panel column, use the [`renderHeader`](/x/react-data-grid/column-header/#custom-header-renderer) property in the column definition. This property receives a `GridRenderHeaderParams` object that contains `colDef` (the column definition) and `field`. The snippet below shows how to do this: ```tsx const columns = [ { ...GRID_DETAIL_PANEL_TOGGLE_COL_DEF, renderHeader: (params) => (
{params.colDef.headerName}
), }, //... other columns ]; ``` :::success For a more complex example of this use case, see the recipe for [expanding or collapsing all detail panels](/x/react-data-grid/row-recipes/#expand-or-collapse-all-detail-panels). ::: ## Disabling detail panel content scroll By default, the detail panel's width is equal to the sum of the widths of all columns. This means that when a horizontal scrollbar is present, scrolling it also scrolls the panel content. To avoid this behavior, set the size of the detail panel to the outer size of the Data Grid. Use `apiRef.current.getRootDimensions()` to get the latest dimension values. And to prevent the panel from scrolling, set `position: sticky` and `left: 0`. The following demo shows how to accomplish this—notice that the toggle column is pinned so it remains visible when the user scrolls horizontally: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Paper from '@mui/material/Paper'; import Stack from '@mui/material/Stack'; import { DataGridPro, GridColDef, useGridApiContext, GridRowParams, GRID_DETAIL_PANEL_TOGGLE_FIELD, useGridSelector, gridDimensionsSelector, } from '@mui/x-data-grid-pro'; import { randomCreatedDate, randomPrice, randomCurrency, randomCountry, randomCity, randomEmail, randomInt, randomAddress, randomCommodity, } from '@mui/x-data-grid-generator'; function DetailPanelContent({ row: rowProp }: { row: Customer }) { const apiRef = useGridApiContext(); const width = useGridSelector(apiRef, gridDimensionsSelector).viewportInnerSize .width; return ( {`Order #${rowProp.id}`} row.quantity * row.unitPrice, }, ]} rows={rowProp.products} sx={{ flex: 1 }} hideFooter /> ); } const columns: GridColDef[] = [ { field: 'id', headerName: 'Order ID' }, { field: 'customer', headerName: 'Customer', width: 200 }, { field: 'email', headerName: 'Email' }, { field: 'date', type: 'date', headerName: 'Placed at' }, { field: 'currency', headerName: 'Currency' }, { field: 'address', headerName: 'Address' }, { field: 'city', headerName: 'City', valueGetter: (value, row) => `${row.city}, ${row.country.label}`, }, { field: 'total', type: 'number', headerName: 'Total', valueGetter: (value, row) => { const subtotal = row.products.reduce( (acc: number, product: any) => product.unitPrice * product.quantity, 0, ); const taxes = subtotal * 0.05; return subtotal + taxes; }, }, ]; function generateProducts() { const quantity = randomInt(1, 5); return [...Array(quantity)].map((_, index) => ({ id: index, name: randomCommodity(), quantity: randomInt(1, 5), unitPrice: randomPrice(1, 1000), })); } const rows = [ { id: 1, customer: 'Matheus', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 2, customer: 'Olivier', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 3, customer: 'Flavien', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 4, customer: 'Danail', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 5, customer: 'Alexandre', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, { id: 6, customer: 'José', email: randomEmail(), date: randomCreatedDate(), address: randomAddress(), country: randomCountry(), city: randomCity(), currency: randomCurrency(), products: generateProducts(), }, ]; type Customer = (typeof rows)[number]; export default function FullWidthDetailPanel() { const getDetailPanelContent = React.useCallback( ({ row }: GridRowParams) => , [], ); const getDetailPanelHeight = React.useCallback(() => 400, []); return ( ); } ``` ## Master-detail row panel recipes For more examples of how to customize master-detail row panels, check out the following recipes: - [One expanded detail panel at a time](/x/react-data-grid/row-recipes/#one-expanded-detail-panel-at-a-time) - [Expand or collapse all detail panels](/x/react-data-grid/row-recipes/#expand-or-collapse-all-detail-panels) - [Toggling detail panels on row click](/x/react-data-grid/row-recipes/#toggling-detail-panels-on-row-click) - [Lazy loading detail panels with auto height](/x/react-data-grid/row-recipes/#lazy-loading-detail-panels-with-auto-height) ## apiRef The Data Grid exposes a set of methods via the `apiRef` object that are used internally in the implementation of master-detail row panels. 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. ::: ```jsx import ApiDocs from 'docsx/src/modules/components/ApiDocs'; import api from 'docsx/pages/x/api/data-grid/grid-detail-panel-api.json'; export default function DetailPanelApiNoSnap() { return ; } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/api/date-pickers/mobile-date-picker.md # MobileDatePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date Picker](/x/react-date-pickers/date-picker/) - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { MobileDatePicker } from '@mui/x-date-pickers/MobileDatePicker'; // or import { MobileDatePicker } from '@mui/x-date-pickers'; // or import { MobileDatePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | minDate | `object` | `1900-01-01` | No | | | monthsPerRow | `3 \| 4` | `3` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | onYearChange | `function(year: PickerValidDate) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'day' \| 'month' \| 'year'` | - | No | | | orientation | `'landscape' \| 'portrait'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => ...` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate) => boolean` | - | No | | | shouldDisableMonth | `function(month: PickerValidDate) => boolean` | - | No | | | shouldDisableYear | `function(year: PickerValidDate) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | | view | `'day' \| 'month' \| 'year'` | - | No | | | viewRenderers | `{ day?: func, month?: func, year?: func }` | - | No | | | views | `Array<'day' \| 'month' \| 'year'>` | - | No | | | yearsOrder | `'asc' \| 'desc'` | `'asc'` | No | | | yearsPerRow | `3 \| 4` | `3` | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `PickersDay` | - | Custom component for day. Check the [PickersDay](https://mui.com/x/api/date-pickers/pickers-day/) component. | | dialog | `PickersModalDialogRoot` | - | Custom component for the dialog inside which the views are rendered on mobile. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | mobilePaper | `Paper from '@mui/material'.` | - | Custom component for the paper rendered inside the mobile picker's Dialog. | | mobileTransition | `Fade from '@mui/material'.` | - | Custom component for the mobile dialog [Transition](https://mui.com/material-ui/transitions/). | | monthButton | `MonthCalendarButton` | - | Button displayed to render a single month in the `month` view. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DatePickerToolbar` | - | Custom component for the toolbar rendered above the views. | | yearButton | `YearCalendarButton` | - | Button displayed to render a single year in the `year` view. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/mobile-date-range-picker.md # MobileDateRangePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Range Picker - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { MobileDateRangePicker } from '@mui/x-date-pickers-pro/MobileDateRangePicker'; // or import { MobileDateRangePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | currentMonthCalendarPosition | `1 \| 2 \| 3` | `1` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultRangePosition | `'end' \| 'start'` | `'start'` | No | | | defaultValue | `Array` | - | No | | | disableAutoMonthSwitching | `bool` | `false` | No | | | disabled | `bool` | `false` | No | | | disableDragEditing | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | minDate | `object` | `1900-01-01` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onRangePositionChange | `function(rangePosition: RangePosition) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | open | `bool` | `false` | No | | | rangePosition | `'end' \| 'start'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `Array \| object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => "..."` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate, position: string) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `Array` | - | No | | | viewRenderers | `{ day?: func }` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `DateRangePickersDay` | - | Custom component for day in range pickers. Check the [DateRangePickersDay](https://mui.com/x/api/date-pickers/date-range-picker-day/) component. | | dialog | `PickersModalDialogRoot` | - | Custom component for the dialog inside which the views are rendered on mobile. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | mobilePaper | `Paper from '@mui/material'.` | - | Custom component for the paper rendered inside the mobile picker's Dialog. | | mobileTransition | `Fade from '@mui/material'.` | - | Custom component for the mobile dialog [Transition](https://mui.com/material-ui/transitions/). | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DateTimePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/mobile-date-time-picker.md # MobileDateTimePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date Time Picker](/x/react-date-pickers/date-time-picker/) - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { MobileDateTimePicker } from '@mui/x-date-pickers/MobileDateTimePicker'; // or import { MobileDateTimePicker } from '@mui/x-date-pickers'; // or import { MobileDateTimePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | ampmInClock | `bool` | `true on desktop, false on mobile` | No | | | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | maxDateTime | `object` | - | No | | | maxTime | `object` | - | No | | | minDate | `object` | `1900-01-01` | No | | | minDateTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | monthsPerRow | `3 \| 4` | `3` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | onYearChange | `function(year: PickerValidDate) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'day' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'year'` | - | No | | | orientation | `'landscape' \| 'portrait'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => ...` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate) => boolean` | - | No | | | shouldDisableMonth | `function(month: PickerValidDate) => boolean` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | shouldDisableYear | `function(year: PickerValidDate) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | skipDisabled | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | thresholdToRenderTimeInASingleColumn | `number` | `24` | No | | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | | view | `'day' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'year'` | - | No | | | viewRenderers | `{ day?: func, hours?: func, meridiem?: func, minutes?: func, month?: func, seconds?: func, year?: func }` | - | No | | | views | `Array<'day' \| 'hours' \| 'minutes' \| 'month' \| 'seconds' \| 'year'>` | - | No | | | yearsOrder | `'asc' \| 'desc'` | `'asc'` | No | | | yearsPerRow | `3 \| 4` | `3` | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `PickersDay` | - | Custom component for day. Check the [PickersDay](https://mui.com/x/api/date-pickers/pickers-day/) component. | | dialog | `PickersModalDialogRoot` | - | Custom component for the dialog inside which the views are rendered on mobile. | | digitalClockItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single digital clock item. | | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | mobilePaper | `Paper from '@mui/material'.` | - | Custom component for the paper rendered inside the mobile picker's Dialog. | | mobileTransition | `Fade from '@mui/material'.` | - | Custom component for the mobile dialog [Transition](https://mui.com/material-ui/transitions/). | | monthButton | `MonthCalendarButton` | - | Button displayed to render a single month in the `month` view. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | tabs | `DateTimePickerTabs` | - | Tabs enabling toggling between date and time pickers. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DateTimePickerToolbar` | - | Custom component for the toolbar rendered above the views. | | yearButton | `YearCalendarButton` | - | Button displayed to render a single year in the `year` view. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/mobile-date-time-range-picker.md # MobileDateTimeRangePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Time Range Picker - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { MobileDateTimeRangePicker } from '@mui/x-date-pickers-pro/MobileDateTimeRangePicker'; // or import { MobileDateTimeRangePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | currentMonthCalendarPosition | `1 \| 2 \| 3` | `1` | No | | | dayOfWeekFormatter | `function(date: PickerValidDate) => string` | `(date: PickerValidDate) => adapter.format(date, 'weekdayShort').charAt(0).toUpperCase()` | No | | | defaultRangePosition | `'end' \| 'start'` | `'start'` | No | | | defaultValue | `Array` | - | No | | | disableAutoMonthSwitching | `bool` | `false` | No | | | disabled | `bool` | `false` | No | | | disableDragEditing | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | displayWeekNumber | `bool` | - | No | | | fixedWeekNumber | `number` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | maxDate | `object` | `2099-12-31` | No | | | maxDateTime | `object` | - | No | | | maxTime | `object` | - | No | | | minDate | `object` | `1900-01-01` | No | | | minDateTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onMonthChange | `function(month: PickerValidDate) => void` | - | No | | | onOpen | `func` | - | No | | | onRangePositionChange | `function(rangePosition: RangePosition) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'day' \| 'hours' \| 'minutes' \| 'seconds'` | - | No | | | rangePosition | `'end' \| 'start'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `Array \| object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | renderLoading | `function() => React.ReactNode` | `() => "..."` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate, position: string) => boolean` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | skipDisabled | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | thresholdToRenderTimeInASingleColumn | `number` | `24` | No | | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `Array` | - | No | | | view | `'day' \| 'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | viewRenderers | `{ day?: func, hours?: func, meridiem?: func, minutes?: func, seconds?: func }` | - | No | | | views | `Array<'day' \| 'hours' \| 'minutes' \| 'seconds'>` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | calendarHeader | `PickersCalendarHeader` | - | Custom component for calendar header. Check the [PickersCalendarHeader](https://mui.com/x/api/date-pickers/pickers-calendar-header/) component. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | day | `DateRangePickersDay` | - | Custom component for day in range pickers. Check the [DateRangePickersDay](https://mui.com/x/api/date-pickers/date-range-picker-day/) component. | | dialog | `PickersModalDialogRoot` | - | Custom component for the dialog inside which the views are rendered on mobile. | | digitalClockItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single digital clock item. | | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | mobilePaper | `Paper from '@mui/material'.` | - | Custom component for the paper rendered inside the mobile picker's Dialog. | | mobileTransition | `Fade from '@mui/material'.` | - | Custom component for the mobile dialog [Transition](https://mui.com/material-ui/transitions/). | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | switchViewButton | `IconButton` | - | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | - | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | | tabs | `DateTimeRangePickerTabs` | - | Tabs enabling toggling between date and time pickers. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `DateTimeRangePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/mobile-time-picker.md # MobileTimePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Time Picker](/x/react-date-pickers/time-picker/) - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { MobileTimePicker } from '@mui/x-date-pickers/MobileTimePicker'; // or import { MobileTimePicker } from '@mui/x-date-pickers'; // or import { MobileTimePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | ampmInClock | `bool` | `true on desktop, false on mobile` | No | | | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | localeText | `object` | - | No | | | maxTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onOpen | `func` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'hours' \| 'minutes' \| 'seconds'` | - | No | | | orientation | `'landscape' \| 'portrait'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | | view | `'hours' \| 'minutes' \| 'seconds'` | - | No | | | viewRenderers | `{ hours?: func, minutes?: func, seconds?: func }` | - | No | | | views | `Array<'hours' \| 'minutes' \| 'seconds'>` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | dialog | `PickersModalDialogRoot` | - | Custom component for the dialog inside which the views are rendered on mobile. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | mobilePaper | `Paper from '@mui/material'.` | - | Custom component for the paper rendered inside the mobile picker's Dialog. | | mobileTransition | `Fade from '@mui/material'.` | - | Custom component for the mobile dialog [Transition](https://mui.com/material-ui/transitions/). | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | toolbar | `TimePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/mobile-time-range-picker.md # MobileTimeRangePicker API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Time Range Picker - [Date and Time Pickers - Validation](/x/react-date-pickers/validation/) ## Import ```jsx import { MobileTimeRangePicker } from '@mui/x-date-pickers-pro/MobileTimeRangePicker'; // or import { MobileTimeRangePicker } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | autoFocus | `bool` | - | No | | | closeOnSelect | `bool` | `false` | No | | | defaultRangePosition | `'end' \| 'start'` | `'start'` | No | | | defaultValue | `Array` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disableOpenPicker (deprecated) | `bool` | `false` | No | ⚠️ Use the [field component](https://mui.com/x/react-date-pickers/fields/) instead. | | disablePast | `bool` | `false` | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | inputRef | `ref` | - | No | | | label | `node` | - | No | | | localeText | `object` | - | No | | | maxTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | name | `string` | - | No | | | onAccept | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onClose | `func` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onOpen | `func` | - | No | | | onRangePositionChange | `function(rangePosition: RangePosition) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | open | `bool` | `false` | No | | | openTo | `'hours' \| 'minutes' \| 'seconds'` | - | No | | | rangePosition | `'end' \| 'start'` | - | No | | | readOnly | `bool` | `false` | No | | | reduceAnimations | `bool` | ``@media(prefers-reduced-motion: reduce)` || `navigator.userAgent` matches Android <10 or iOS <13` | No | | | referenceDate | `Array \| object` | `The closest valid date-time using the validation props, except callbacks like `shouldDisable<...>`.` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | thresholdToRenderTimeInASingleColumn | `number` | `24` | No | | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `Array` | - | No | | | view | `'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | viewRenderers | `{ hours?: func, meridiem?: func, minutes?: func, seconds?: func }` | - | No | | | views | `Array<'hours' \| 'minutes' \| 'seconds'>` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | - | Custom component for the action bar, it is placed below the Picker views. | | clearButton | `IconButton` | - | Button to clear the value. | | clearIcon | `ClearIcon` | - | Icon to display in the button used to clean the value. | | dialog | `PickersModalDialogRoot` | - | Custom component for the dialog inside which the views are rendered on mobile. | | digitalClockItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single digital clock item. | | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | | field | `undefined` | - | Component used to enter the date with the keyboard. | | inputAdornment | `InputAdornment` | - | Component displayed on the start or end input adornment used to open the Picker. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | mobilePaper | `Paper from '@mui/material'.` | - | Custom component for the paper rendered inside the mobile picker's Dialog. | | mobileTransition | `Fade from '@mui/material'.` | - | Custom component for the mobile dialog [Transition](https://mui.com/material-ui/transitions/). | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | openPickerButton | `IconButton` | - | Button to open the Picker. | | openPickerIcon | `undefined` | - | Icon to display in the button used to open the Picker. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | shortcuts | `PickersShortcuts` | - | Custom component for the shortcuts. | | tabs | `TimeRangePickerTabs` | - | Tabs enabling toggling between start and end time. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render the value. | | Toolbar | `TimeRangePickerToolbar` | - | Custom component for the toolbar rendered above the views. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/MobileTimeRangePicker/MobileTimeRangePicker.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/MobileTimeRangePicker/MobileTimeRangePicker.tsx) --- # Source: https://mui.com/x/api/date-pickers/month-calendar.md # MonthCalendar API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) - [Date Calendar](/x/react-date-pickers/date-calendar/) ## Import ```jsx import { MonthCalendar } from '@mui/x-date-pickers/MonthCalendar'; // or import { MonthCalendar } from '@mui/x-date-pickers'; // or import { MonthCalendar } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disablePast | `bool` | `false` | No | | | maxDate | `object` | `2099-12-31` | No | | | minDate | `object` | `1900-01-01` | No | | | monthsPerRow | `3 \| 4` | `3` | No | | | onChange | `function(value: PickerValidDate) => void` | - | No | | | readOnly | `bool` | `false` | No | | | referenceDate | `object` | `The closest valid month using the validation props, except callbacks such as `shouldDisableMonth`.` | No | | | shouldDisableMonth | `function(month: PickerValidDate) => boolean` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiMonthCalendar` to change the default props of this component with the theme. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | monthButton | `MonthCalendarButton` | - | Button displayed to render a single month in the `month` view. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | button | Styles applied to the button element that represents a single month | | `.Mui-disabled` | - | Styles applied to a disabled button element. | | - | root | Styles applied to the root element. | | `.Mui-selected` | - | Styles applied to a selected button element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/MonthCalendar/MonthCalendar.tsx) --- # Source: https://mui.com/x/react-data-grid/filtering/multi-filters.md --- title: Data Grid - Multi-filters --- # Data Grid - Multi-filters [](/x/introduction/licensing/#pro-plan 'Pro plan') Let end users apply multiple filters to the Data Grid simultaneously. By default, it's only possible to apply one filter at a time to the Data Grid. With the Data Grid Pro, users can apply multiple filters based on different criteria for more fine-grained data analysis. They can apply multiple filters to a single column and multiple columns simultaneously. The demo below shows how this feature works. Click the filter icon to open the menu and add the first filter—the Data Grid dynamically responds as you enter a value. Then click **Add Filter** to apply additional criteria. ```tsx import { DataGridPro } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function BasicExampleDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); return (
); } ``` ## Implementing multi-filters The multi-filter feature is available by default with the Data Grid Pro and doesn't require any additional configuration. ### One filter per column To limit the user to only applying one filter to any given column, you can use the [`filterColumns`](/x/api/data-grid/grid-filter-form/) and [`getColumnForNewFilter`](/x/api/data-grid/grid-filter-panel/) props available to `slotProps.filterPanel` as shown in the demo below: ```tsx import { DataGridPro, FilterColumnsArgs, GetColumnForNewFilterArgs, } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function DisableMultiFiltersDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); const filterColumns = ({ field, columns, currentFilters }: FilterColumnsArgs) => { // remove already filtered fields from list of columns const filteredFields = currentFilters?.map((item) => item.field); return columns .filter( (colDef) => colDef.filterable && (colDef.field === field || !filteredFields.includes(colDef.field)), ) .map((column) => column.field); }; const getColumnForNewFilter = ({ currentFilters, columns, }: GetColumnForNewFilterArgs) => { const filteredFields = currentFilters?.map(({ field }) => field); const columnForNewFilter = columns .filter( (colDef) => colDef.filterable && !filteredFields.includes(colDef.field), ) .find((colDef) => colDef.filterOperators?.length); return columnForNewFilter?.field ?? null; }; return (
); } ``` ## Disabling multi-filters To disable multi-filtering, pass the `disableMultipleColumnsFiltering` to the Data Grid Pro. ```tsx ``` ### Remove multi-filter action buttons To disable the **Add Filter** or **Remove All** buttons, pass `disableAddFilterButton` or `disableRemoveAllButton`, respectively, to `componentsProps.filterPanel` as shown below: ```tsx import { DataGridPro } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; const VISIBLE_FIELDS = ['name', 'rating', 'country', 'dateCreated', 'isAdmin']; export default function DisableActionButtonsDataGridPro() { const { data, loading } = useDemoData({ dataSet: 'Employee', visibleFields: VISIBLE_FIELDS, rowLength: 100, }); return (
); } ``` ## API - [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/) --- # Source: https://mui.com/x/api/date-pickers/multi-input-date-range-field.md # MultiInputDateRangeField API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Range Field - [Fields component](/x/react-date-pickers/fields/) ## Import ```jsx import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro/MultiInputDateRangeField'; // or import { MultiInputDateRangeField } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | autoFocus | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | dateSeparator | `string` | `"–"` | No | | | defaultValue | `Array` | - | No | | | direction | `'column-reverse' \| 'column' \| 'row-reverse' \| 'row' \| Array<'column-reverse' \| 'column' \| 'row-reverse' \| 'row'> \| object` | `'column'` | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disablePast | `bool` | `false` | No | | | divider | `node` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | maxDate | `object` | `2099-12-31` | No | | | minDate | `object` | `1900-01-01` | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | readOnly | `bool` | `false` | No | | | referenceDate | `Array \| object` | `The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used.` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate, position: string) => boolean` | - | No | | | shouldRespectLeadingZeros | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | spacing | `Array \| number \| object \| string` | `0` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | useFlexGap | `bool` | `false` | No | | | value | `Array` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiMultiInputDateRangeField` to change the default props of this component with the theme. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | root | `MultiInputRangeFieldRoot` | `.MuiMultiInputDateRangeField-root` | Element rendered at the root. | | separator | `MultiInputRangeFieldSeparator` | `.MuiMultiInputDateRangeField-separator` | Element rendered between the two inputs. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render a date. It is rendered twice: once for the start date and once for the end date. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx) --- # Source: https://mui.com/x/api/date-pickers/multi-input-date-time-range-field.md # MultiInputDateTimeRangeField API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Date Time Range Field - [Fields component](/x/react-date-pickers/fields/) ## Import ```jsx import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField'; // or import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | autoFocus | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | dateSeparator | `string` | `"–"` | No | | | defaultValue | `Array` | - | No | | | direction | `'column-reverse' \| 'column' \| 'row-reverse' \| 'row' \| Array<'column-reverse' \| 'column' \| 'row-reverse' \| 'row'> \| object` | `'column'` | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disablePast | `bool` | `false` | No | | | divider | `node` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | maxDate | `object` | `2099-12-31` | No | | | maxDateTime | `object` | - | No | | | maxTime | `object` | - | No | | | minDate | `object` | `1900-01-01` | No | | | minDateTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | readOnly | `bool` | `false` | No | | | referenceDate | `Array \| object` | `The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used.` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableDate | `function(day: PickerValidDate, position: string) => boolean` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | shouldRespectLeadingZeros | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | spacing | `Array \| number \| object \| string` | `0` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | useFlexGap | `bool` | `false` | No | | | value | `Array` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiMultiInputDateTimeRangeField` to change the default props of this component with the theme. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | root | `MultiInputRangeFieldRoot` | `.MuiMultiInputDateTimeRangeField-root` | Element rendered at the root. | | separator | `MultiInputRangeFieldSeparator` | `.MuiMultiInputDateTimeRangeField-separator` | Element rendered between the two inputs. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render a date. It is rendered twice: once for the start date and once for the end date. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx) --- # Source: https://mui.com/x/api/date-pickers/multi-input-time-range-field.md # MultiInputTimeRangeField API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Fields component](/x/react-date-pickers/fields/) - Time Range Field ## Import ```jsx import { MultiInputTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField'; // or import { MultiInputTimeRangeField } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | autoFocus | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | dateSeparator | `string` | `"–"` | No | | | defaultValue | `Array` | - | No | | | direction | `'column-reverse' \| 'column' \| 'row-reverse' \| 'row' \| Array<'column-reverse' \| 'column' \| 'row-reverse' \| 'row'> \| object` | `'column'` | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disablePast | `bool` | `false` | No | | | divider | `node` | - | No | | | format | `string` | - | No | | | formatDensity | `'dense' \| 'spacious'` | `"dense"` | No | | | maxTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | onChange | `function(value: TValue, context: FieldChangeHandlerContext) => void` | - | No | | | onError | `function(error: TError, value: TValue) => void` | - | No | | | onSelectedSectionsChange | `function(newValue: FieldSelectedSections) => void` | - | No | | | readOnly | `bool` | `false` | No | | | referenceDate | `Array \| object` | `The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used.` | No | | | selectedSections | `'all' \| 'day' \| 'empty' \| 'hours' \| 'meridiem' \| 'minutes' \| 'month' \| 'seconds' \| 'weekDay' \| 'year' \| number` | - | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | shouldRespectLeadingZeros | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | spacing | `Array \| number \| object \| string` | `0` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | useFlexGap | `bool` | `false` | No | | | value | `Array` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiMultiInputTimeRangeField` to change the default props of this component with the theme. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | root | `MultiInputRangeFieldRoot` | `.MuiMultiInputTimeRangeField-root` | Element rendered at the root. | | separator | `MultiInputRangeFieldSeparator` | `.MuiMultiInputTimeRangeField-separator` | Element rendered between the two inputs. | | textField | `, or from '@mui/material' if `enableAccessibleFieldDOMStructure` is `false`.` | - | Form control with an input to render a date. It is rendered twice: once for the start date and once for the end date. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx) --- # Source: https://mui.com/x/api/date-pickers/multi-section-digital-clock.md # MultiSectionDigitalClock API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date Time Picker](/x/react-date-pickers/date-time-picker/) - Date Time Range Picker - [Digital Clock](/x/react-date-pickers/digital-clock/) - [Time Picker](/x/react-date-pickers/time-picker/) - Time Range Picker ## Import ```jsx import { MultiSectionDigitalClock } from '@mui/x-date-pickers/MultiSectionDigitalClock'; // or import { MultiSectionDigitalClock } from '@mui/x-date-pickers'; // or import { MultiSectionDigitalClock } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | ampm | `bool` | `adapter.is12HourCycleInCurrentLocale()` | No | | | autoFocus | `bool` | - | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | defaultValue | `object` | - | No | | | disabled | `bool` | `false` | No | | | disableFuture | `bool` | `false` | No | | | disableIgnoringDatePartForTimeValidation | `bool` | `false` | No | | | disablePast | `bool` | `false` | No | | | focusedView | `'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | maxTime | `object` | - | No | | | minTime | `object` | - | No | | | minutesStep | `number` | `1` | No | | | onChange | `function(value: TValue, selectionState: PickerSelectionState \| undefined, selectedView: TView \| undefined) => void` | - | No | | | onFocusedViewChange | `function(view: TView, hasFocus: boolean) => void` | - | No | | | onViewChange | `function(view: TView) => void` | - | No | | | openTo | `'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | readOnly | `bool` | `false` | No | | | referenceDate | `object` | `The closest valid time using the validation props, except callbacks such as `shouldDisableTime`.` | No | | | shouldDisableTime | `function(value: PickerValidDate, view: TimeView) => boolean` | - | No | | | skipDisabled | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | timeSteps | `{ hours?: number, minutes?: number, seconds?: number }` | `{ hours: 1, minutes: 5, seconds: 5 }` | No | | | timezone | `string` | `The timezone of the `value` or `defaultValue` prop is defined, 'default' otherwise.` | No | | | value | `object` | - | No | | | view | `'hours' \| 'meridiem' \| 'minutes' \| 'seconds'` | - | No | | | views | `Array<'hours' \| 'meridiem' \| 'minutes' \| 'seconds'>` | `['hours', 'minutes']` | No | | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiMultiSectionDigitalClock` to change the default props of this component with the theme. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | digitalClockSectionItem | `MenuItem from '@mui/material'` | - | Component responsible for rendering a single multi section digital clock section item. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/MultiSectionDigitalClock/MultiSectionDigitalClock.tsx) --- # Source: https://mui.com/x/react-tree-view/rich-tree-view/ordering.md --- productId: x-tree-view title: Rich Tree View - Ordering components: TreeItem, RichTreeViewPro, TreeItemDragAndDropOverlay packageName: '@mui/x-tree-view' githubLabel: 'scope: tree view' waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/treeview/ --- # Rich Tree View - Ordering [](/x/introduction/licensing/#pro-plan 'Pro plan') Let users drag and drop items in the Tree View to reorder them. ## Enable drag-and-drop reordering You can enable the drag-and-drop reordering of items by setting the `itemsReordering` prop to `true`: ```tsx import Box from '@mui/material/Box'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; const ITEMS: TreeViewBaseItem[] = [ { id: 'grid', label: 'Data Grid', children: [ { id: 'grid-community', label: '@mui/x-data-grid' }, { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, ], }, { id: 'pickers', label: 'Date and Time Pickers', children: [ { id: 'pickers-community', label: '@mui/x-date-pickers' }, { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, ], }, { id: 'charts', label: 'Charts', children: [{ id: 'charts-community', label: '@mui/x-charts' }], }, { id: 'tree-view', label: 'Tree View', children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], }, ]; export default function DragAndDrop() { return ( ); } ``` ## Limit reordering By default, all items are reorderable. You can prevent reordering of specifc items using the `isItemReorderable` prop. The following example shows how to only let users reorder the leaves using the [`getItemOrderedChildrenIds()`](/x/react-tree-view/rich-tree-view/items/#get-an-items-children-by-id) API method. ```tsx import Box from '@mui/material/Box'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { useRichTreeViewProApiRef } from '@mui/x-tree-view-pro/hooks'; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ { id: 'grid', label: 'Data Grid', children: [ { id: 'grid-community', label: '@mui/x-data-grid' }, { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, ], }, { id: 'pickers', label: 'Date and Time Pickers', children: [ { id: 'pickers-community', label: '@mui/x-date-pickers' }, { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, ], }, { id: 'charts', label: 'Charts', children: [{ id: 'charts-community', label: '@mui/x-charts' }], }, { id: 'tree-view', label: 'Tree View', children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], }, ]; export default function OnlyReorderLeaves() { const apiRef = useRichTreeViewProApiRef(); return ( apiRef.current!.getItemOrderedChildrenIds(itemId).length === 0 } /> ); } ``` You can also limit the items in which an item can be dropped using the `canMoveItemToNewPosition` prop. The following example shows how to only let users reorder inside the same parent: ```tsx import Box from '@mui/material/Box'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ { id: 'grid', label: 'Data Grid', children: [ { id: 'grid-community', label: '@mui/x-data-grid' }, { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, ], }, { id: 'pickers', label: 'Date and Time Pickers', children: [ { id: 'pickers-community', label: '@mui/x-date-pickers' }, { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, ], }, { id: 'charts', label: 'Charts', children: [{ id: 'charts-community', label: '@mui/x-charts' }], }, { id: 'tree-view', label: 'Tree View', children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], }, ]; export default function OnlyReorderInSameParent() { return ( params.oldPosition.parentId === params.newPosition.parentId } /> ); } ``` ## React to an item reordering You can use the `onItemPositionChange` to send the new position of an item to your backend: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { RichTreeViewPro, RichTreeViewProProps, } from '@mui/x-tree-view-pro/RichTreeViewPro'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ { id: 'grid', label: 'Data Grid', children: [ { id: 'grid-community', label: '@mui/x-data-grid' }, { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, ], }, { id: 'pickers', label: 'Date and Time Pickers', children: [ { id: 'pickers-community', label: '@mui/x-date-pickers' }, { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, ], }, { id: 'charts', label: 'Charts', children: [{ id: 'charts-community', label: '@mui/x-charts' }], }, { id: 'tree-view', label: 'Tree View', children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], }, ]; export default function OnItemPositionChange() { const [lastReorder, setLastReorder] = React.useState< | Parameters< NonNullable['onItemPositionChange']> >[0] | null >(null); return ( setLastReorder(params)} /> {lastReorder == null ? ( No reorder registered yet ) : ( Last reordered item: {lastReorder.itemId}
Position before: {lastReorder.oldPosition.parentId ?? 'root'} (index{' '} {lastReorder.oldPosition.index})
F Position after:{' '} {lastReorder.newPosition.parentId ?? 'root'} (index{' '} {lastReorder.newPosition.index})
)}
); } ``` If you want to send the entire dataset to your backend, you can use the [`getItemTree()`](/x/react-tree-view/rich-tree-view/items/#get-the-current-item-tree) API method. The following demo demonstrates it by synchronizing the first `RichTreeView` with the second one whenever you perform a reordering: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { useRichTreeViewProApiRef } from '@mui/x-tree-view-pro/hooks'; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ { id: 'grid', label: 'Data Grid', children: [ { id: 'grid-community', label: '@mui/x-data-grid' }, { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, ], }, { id: 'pickers', label: 'Date and Time Pickers', children: [ { id: 'pickers-community', label: '@mui/x-date-pickers' }, { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, ], }, { id: 'charts', label: 'Charts', children: [{ id: 'charts-community', label: '@mui/x-charts' }], }, { id: 'tree-view', label: 'Tree View', children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], }, ]; const getAllItemsWithChildrenItemIds = (items: TreeViewBaseItem[]) => { const itemIds: string[] = []; const registerItemId = (item: TreeViewBaseItem) => { if (item.children?.length) { itemIds.push(item.id); item.children.forEach(registerItemId); } }; items.forEach(registerItemId); return itemIds; }; export default function SendAllItemsToServer() { const apiRefTreeViewA = useRichTreeViewProApiRef(); const [itemsTreeViewB, setItemsTreeViewB] = React.useState(MUI_X_PRODUCTS); const handleItemPositionChangeTreeViewA = () => { // We need to wait for the new items to be updated in the state setTimeout(() => { const newItemsTreeViewA = apiRefTreeViewA.current!.getItemTree(); setItemsTreeViewB(newItemsTreeViewA); }); }; return ( true} /> ); } ``` ## Customization ### Only trigger reordering from a drag handle You can create a custom `TreeItem` component to render a drag handle icon and only trigger reordering when dragging from it: ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import DragIndicatorIcon from '@mui/icons-material/DragIndicator'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { TreeViewBaseItem } from '@mui/x-tree-view/models'; import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { TreeItemContent, TreeItemIconContainer, TreeItemGroupTransition, TreeItemLabel, TreeItemRoot, TreeItemCheckbox, } from '@mui/x-tree-view/TreeItem'; import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; const MUI_X_PRODUCTS: TreeViewBaseItem[] = [ { id: 'grid', label: 'Data Grid', children: [ { id: 'grid-community', label: '@mui/x-data-grid' }, { id: 'grid-pro', label: '@mui/x-data-grid-pro' }, { id: 'grid-premium', label: '@mui/x-data-grid-premium' }, ], }, { id: 'pickers', label: 'Date and Time Pickers', children: [ { id: 'pickers-community', label: '@mui/x-date-pickers' }, { id: 'pickers-pro', label: '@mui/x-date-pickers-pro' }, ], }, { id: 'charts', label: 'Charts', children: [{ id: 'charts-community', label: '@mui/x-charts' }], }, { id: 'tree-view', label: 'Tree View', children: [{ id: 'tree-view-community', label: '@mui/x-tree-view' }], }, ]; interface CustomTreeItemProps extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: CustomTreeItemProps, ref: React.Ref, ) { const { id, itemId, label, disabled, children, ...other } = props; const { getContextProviderProps, getRootProps, getContentProps, getIconContainerProps, getCheckboxProps, getLabelProps, getGroupTransitionProps, getDragAndDropOverlayProps, status, } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const { draggable, onDragStart, ...otherRootProps } = getRootProps(other); const handleDragStart = (event: React.DragEvent) => { if (!onDragStart) { return; } onDragStart(event); event.dataTransfer.setDragImage( (event.target as HTMLElement).parentElement!, 0, 0, ); }; return ( {children && } ); }); export default function OnlyReorderFromDragHandle() { return ( ); } ``` ## Common examples ### File explorer The example below is a simplified version of the [file explorer](/x/react-tree-view/rich-tree-view/customization/#file-explorer) example with drag-and-drop reordering. You can reorder items but only inside folders (or inside the trash). ```tsx import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import ArticleIcon from '@mui/icons-material/Article'; import DeleteIcon from '@mui/icons-material/Delete'; import FolderRounded from '@mui/icons-material/FolderRounded'; import ImageIcon from '@mui/icons-material/Image'; import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf'; import VideoCameraBackIcon from '@mui/icons-material/VideoCameraBack'; import { RichTreeViewPro } from '@mui/x-tree-view-pro/RichTreeViewPro'; import { useTreeItem, UseTreeItemParameters } from '@mui/x-tree-view/useTreeItem'; import { TreeItemCheckbox, TreeItemIconContainer, TreeItemLabel, TreeItemGroupTransition, } from '@mui/x-tree-view/TreeItem'; import { TreeItemIcon } from '@mui/x-tree-view/TreeItemIcon'; import { TreeItemProvider } from '@mui/x-tree-view/TreeItemProvider'; import { TreeItemDragAndDropOverlay } from '@mui/x-tree-view/TreeItemDragAndDropOverlay'; import { useTreeItemModel } from '@mui/x-tree-view/hooks'; import { useRichTreeViewProApiRef } from '@mui/x-tree-view-pro/hooks'; type FileType = 'image' | 'pdf' | 'doc' | 'video' | 'folder' | 'pinned' | 'trash'; type FileItem = { fileType: FileType; id: string; label: string; children?: FileItem[]; }; const ITEMS: FileItem[] = [ { id: '1', label: 'Documents', fileType: 'folder', children: [ { id: '1.1', label: 'Company', fileType: 'folder', children: [ { id: '1.1.1', label: 'Invoice', fileType: 'pdf' }, { id: '1.1.2', label: 'Meeting notes', fileType: 'doc' }, { id: '1.1.3', label: 'Tasks list', fileType: 'doc' }, { id: '1.1.4', label: 'Equipment', fileType: 'pdf' }, { id: '1.1.5', label: 'Video conference', fileType: 'video' }, ], }, { id: '1.2', label: 'Personal', fileType: 'folder' }, { id: '1.3', label: 'Group photo', fileType: 'image' }, ], }, { id: '2', label: 'Bookmarked', fileType: 'folder', children: [ { id: '2.1', label: 'Learning materials', fileType: 'folder' }, { id: '2.2', label: 'News', fileType: 'folder' }, { id: '2.3', label: 'Forums', fileType: 'folder' }, { id: '2.4', label: 'Travel documents', fileType: 'pdf' }, ], }, { id: '3', label: 'History', fileType: 'folder' }, { id: '4', label: 'Trash', fileType: 'trash' }, ]; function DotIcon() { return ( ); } declare module 'react' { interface CSSProperties { '--tree-view-color'?: string; '--tree-view-bg-color'?: string; } } const TreeItemRoot = styled('li')(({ theme }) => ({ listStyle: 'none', margin: 0, padding: 0, outline: 0, color: theme.palette.grey[400], ...theme.applyStyles('light', { color: theme.palette.grey[800], }), })); const TreeItemContent = styled('div')(({ theme }) => ({ padding: theme.spacing(0.5), paddingRight: theme.spacing(1), paddingLeft: `calc(${theme.spacing(1)} + var(--TreeView-itemChildrenIndentation) * var(--TreeView-itemDepth))`, width: '100%', boxSizing: 'border-box', // prevent width + padding to overflow position: 'relative', display: 'flex', alignItems: 'center', gap: theme.spacing(1), cursor: 'pointer', WebkitTapHighlightColor: 'transparent', flexDirection: 'row-reverse', borderRadius: theme.spacing(0.7), marginBottom: theme.spacing(0.5), marginTop: theme.spacing(0.5), fontWeight: 500, '&[data-expanded]:not([data-focused], [data-selected]) .labelIcon': { color: theme.palette.primary.dark, ...theme.applyStyles('light', { color: theme.palette.primary.main, }), '&::before': { content: '""', display: 'block', position: 'absolute', left: '16px', top: '44px', height: 'calc(100% - 48px)', width: '1.5px', backgroundColor: theme.palette.grey[700], ...theme.applyStyles('light', { backgroundColor: theme.palette.grey[300], }), }, }, [`&[data-focused], &[data-selected]`]: { backgroundColor: theme.palette.primary.dark, color: theme.palette.primary.contrastText, ...theme.applyStyles('light', { backgroundColor: theme.palette.primary.main, }), }, '&:not([data-focused], [data-selected]):hover': { backgroundColor: alpha(theme.palette.primary.main, 0.1), color: 'white', ...theme.applyStyles('light', { color: theme.palette.primary.main, }), }, })); const TreeItemLabelText = styled(Typography)({ color: 'inherit', fontFamily: 'General Sans', fontWeight: 500, }); interface CustomLabelProps { children: React.ReactNode; icon?: React.ElementType; expandable?: boolean; } function CustomLabel({ icon: Icon, expandable, children, ...other }: CustomLabelProps) { return ( {Icon && ( )} {children} {expandable && } ); } const getIconFromFileType = (fileType: FileType) => { switch (fileType) { case 'image': return ImageIcon; case 'pdf': return PictureAsPdfIcon; case 'doc': return ArticleIcon; case 'video': return VideoCameraBackIcon; case 'folder': return FolderRounded; case 'trash': return DeleteIcon; default: return ArticleIcon; } }; interface CustomTreeItemProps extends Omit, Omit, 'onFocus'> {} const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: CustomTreeItemProps, ref: React.Ref, ) { const { id, itemId, label, disabled, children, ...other } = props; const { getContextProviderProps, getRootProps, getContentProps, getIconContainerProps, getCheckboxProps, getLabelProps, getGroupTransitionProps, getDragAndDropOverlayProps, status, } = useTreeItem({ id, itemId, children, label, disabled, rootRef: ref }); const item = useTreeItemModel(itemId)!; let icon; if (status.expandable) { icon = FolderRounded; } else if (item.fileType) { icon = getIconFromFileType(item.fileType); } return ( {children && } ); }); export default function FileExplorer() { const apiRef = useRichTreeViewProApiRef(); return ( { return ( params.newPosition.parentId === null || ['folder', 'trash'].includes( apiRef.current!.getItem(params.newPosition.parentId).fileType, ) ); }} /> ); } ``` --- # Source: https://mui.com/x/react-data-grid/overlays.md # Data Grid - Overlays The various Data Grid overlays. ## Loading overlay To display a loading overlay and signify that the Data Grid is in a loading state, set the `loading` prop to `true`. The Data Grid supports 3 loading overlay variants out of the box: - `skeleton`: an animated placeholder of the Data Grid. - `linear-progress`: an indeterminate linear progress bar. - `circular-progress`: a circular loading spinner. The type of loading overlay to display can be set via `slotProps.loadingOverlay` for the following two props: - `variant` (default: `linear-progress`): when `loading` and there are rows in the table. - `noRowsVariant` (default: `skeleton`): when `loading` and there are not any rows in the table. ```tsx ``` ### Skeleton An animated placeholder of the Data Grid. ```tsx import Box from '@mui/material/Box'; import { useDemoData } from '@mui/x-data-grid-generator'; import { DataGrid } from '@mui/x-data-grid'; export default function LoadingOverlaySkeleton() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 9, }); return ( ); } ``` ### Linear progress An indeterminate linear progress bar. ```tsx import Box from '@mui/material/Box'; import { useDemoData } from '@mui/x-data-grid-generator'; import { DataGrid } from '@mui/x-data-grid'; export default function LoadingOverlayLinearProgress() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return ( ); } ``` ### Circular progress A circular loading spinner. ```tsx import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function LoadingOverlayCircularProgress() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 6, maxColumns: 6, }); return ( ); } ``` ### Custom component If you want to customize the no-rows overlay, a component can be passed to the `loadingOverlay` slot. In the following demo, a labeled determinate [CircularProgress](/material-ui/react-progress/#circular-determinate) component is rendered in place of the default loading overlay, with some additional _Loading rows…_ text. ```tsx import * as React from 'react'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import CircularProgress, { CircularProgressProps, } from '@mui/material/CircularProgress'; const StyledGridOverlay = styled('div')(({ theme }) => ({ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', backgroundColor: 'rgba(18, 18, 18, 0.9)', ...theme.applyStyles('light', { backgroundColor: 'rgba(255, 255, 255, 0.9)', }), })); function CircularProgressWithLabel( props: CircularProgressProps & { value: number }, ) { return ( {`${Math.round(props.value)}%`} ); } function CustomLoadingOverlay() { const [progress, setProgress] = React.useState(10); React.useEffect(() => { const timer = setInterval(() => { setProgress((prevProgress) => (prevProgress >= 100 ? 0 : prevProgress + 10)); }, 800); return () => { clearInterval(timer); }; }, []); return ( Loading rows… ); } export default function LoadingOverlayCustom() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return (
); } ``` ## No columns overlay The no-columns overlay is displayed when the Data Grid has no columns, or when all columns are hidden. The "Manage columns" button is displayed when all columns are hidden and `disableColumnSelector` is `false`. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function NoColumnsOverlay() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 50, maxColumns: 6, }); const initialColumns = React.useMemo( () => data.columns.reduce( (acc, col) => { acc[col.field] = false; return acc; }, {} as Record, ), [data.columns], ); return ( ); } ``` ### Custom component If you want to customize the no-columns overlay, a component can be passed to the `noColumnsOverlay` slot and rendered in place. In the following demo, an illustration is added on top of the default "No columns" message. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Stack from '@mui/material/Stack'; import { DataGrid, GridPreferencePanelsValue, useGridApiContext, } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import { styled } from '@mui/material/styles'; const StyledGridOverlay = styled('div')(({ theme }) => ({ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', textAlign: 'center', height: '100%', '& .no-columns-primary': { fill: '#3D4751', ...theme.applyStyles('light', { fill: '#AEB8C2', }), }, '& .no-columns-secondary': { fill: '#1D2126', ...theme.applyStyles('light', { fill: '#E8EAED', }), }, })); function CustomNoColumnsOverlay() { const apiRef = useGridApiContext(); const handleOpenManageColumns = () => { apiRef.current.showPreferences(GridPreferencePanelsValue.columns); }; return ( No columns ); } export default function NoColumnsOverlayCustom() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 50, maxColumns: 6, }); const initialColumns = React.useMemo( () => data.columns.reduce( (acc, col) => { acc[col.field] = false; return acc; }, {} as Record, ), [data.columns], ); return ( ); } ``` ## No rows overlay The no-rows overlay is displayed when the Data Grid has no rows. ```tsx import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function NoRowsOverlay() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 0, maxColumns: 6, }); return ( ); } ``` ### Custom component If you want to customize the no-rows overlay, a component can be passed to the `noRowsOverlay` slot and rendered in place. In the following demo, an illustration is added on top of the default "No rows" message. ```tsx import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import { styled } from '@mui/material/styles'; const StyledGridOverlay = styled('div')(({ theme }) => ({ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', '& .no-rows-primary': { fill: '#3D4751', ...theme.applyStyles('light', { fill: '#AEB8C2', }), }, '& .no-rows-secondary': { fill: '#1D2126', ...theme.applyStyles('light', { fill: '#E8EAED', }), }, })); function CustomNoRowsOverlay() { return ( No rows ); } export default function NoRowsOverlayCustom() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return (
); } ``` ## No results overlay The no-results overlay is displayed when the Data Grid has no results after filtering. ```tsx import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function NoResultsOverlay() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 6, maxColumns: 6, }); return ( ); } ``` ### Custom component If you want to customize the no results overlay, a component can be passed to the `noResults` slot and rendered in place. In the following demo, an illustration is added on top of the default "No results found" message. ```tsx import Box from '@mui/material/Box'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import { styled } from '@mui/material/styles'; const StyledGridOverlay = styled('div')(({ theme }) => ({ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', '& .no-results-primary': { fill: '#3D4751', ...theme.applyStyles('light', { fill: '#AEB8C2', }), }, '& .no-results-secondary': { fill: '#1D2126', ...theme.applyStyles('light', { fill: '#E8EAED', }), }, })); function CustomNoResultsOverlay() { return ( No results found. ); } export default function NoResultsOverlayCustom() { const { data } = useDemoData({ dataSet: 'Commodity', rowLength: 6, maxColumns: 6, }); return (
); } ``` ## Empty pivot overlay The empty pivot overlay is displayed when pivot mode is enabled but fields have been added to the rows section. ```tsx import { DataGridPremium, GridColDef, GridRowModel, GridPivotModel, GridInitialState, } from '@mui/x-data-grid-premium'; const rows: GridRowModel[] = [ { id: 1, product: 'Apples', region: 'North', quarter: 'Q1', sales: 1000 }, { id: 2, product: 'Apples', region: 'South', quarter: 'Q1', sales: 1200 }, { id: 3, product: 'Oranges', region: 'North', quarter: 'Q1', sales: 800 }, { id: 4, product: 'Oranges', region: 'South', quarter: 'Q1', sales: 900 }, { id: 5, product: 'Apples', region: 'North', quarter: 'Q2', sales: 1100 }, { id: 6, product: 'Apples', region: 'South', quarter: 'Q2', sales: 1300 }, { id: 7, product: 'Oranges', region: 'North', quarter: 'Q2', sales: 850 }, { id: 8, product: 'Oranges', region: 'South', quarter: 'Q2', sales: 950 }, ]; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const columns: GridColDef[] = [ { field: 'product', headerName: 'Product' }, { field: 'region', headerName: 'Region' }, { field: 'quarter', headerName: 'Quarter' }, { field: 'sales', headerName: 'Sales', type: 'number', valueFormatter: (value) => { if (!value) { return ''; } return currencyFormatter.format(value); }, }, ]; const pivotModel: GridPivotModel = { rows: [], columns: [], values: [], }; const initialState: GridInitialState = { pivoting: { model: pivotModel, enabled: true, }, }; export default function EmptyPivotOverlay() { return (
); } ``` ### Custom component To customize the empty pivot overlay, pass a custom component to the `emptyPivotOverlay` slot. - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/pagination.md # Data Grid - Pagination Easily paginate your rows and only fetch what you need. ## Enabling pagination The default pagination behavior depends on your plan: :::info Exported CSV and Excel files include all data and disregard pagination by default. To apply pagination to exported files, review the available [row selectors](/x/react-data-grid/export/#exported-rows). ::: ### Community plan For the Community Data Grid, pagination is enabled by default and cannot be disabled. ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function PaginationCommunityNoSnap() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 500, maxColumns: 6, }); return (
); } ``` ### Pro [](/x/introduction/licensing/#pro-plan 'Pro plan') and Premium [](/x/introduction/licensing/#premium-plan 'Premium plan') For the Pro and Premium Data Grid, pagination is disabled by default; use the `pagination` prop to enable it. ```tsx import { DataGridPremium, GridColDef, GridRowsProp } from '@mui/x-data-grid-premium'; const rows: GridRowsProp = [ { jobTitle: 'Head of Human Resources', recruitmentDate: new Date(2020, 8, 12), contract: 'full time', id: 0, }, { jobTitle: 'Head of Sales', recruitmentDate: new Date(2017, 3, 4), contract: 'full time', id: 1, }, { jobTitle: 'Sales Person', recruitmentDate: new Date(2020, 11, 20), contract: 'full time', id: 2, }, { jobTitle: 'Sales Person', recruitmentDate: new Date(2020, 10, 14), contract: 'part time', id: 3, }, { jobTitle: 'Sales Person', recruitmentDate: new Date(2017, 10, 29), contract: 'part time', id: 4, }, { jobTitle: 'Sales Person', recruitmentDate: new Date(2020, 7, 21), contract: 'full time', id: 5, }, { jobTitle: 'Sales Person', recruitmentDate: new Date(2020, 7, 20), contract: 'intern', id: 6, }, { jobTitle: 'Sales Person', recruitmentDate: new Date(2019, 6, 28), contract: 'full time', id: 7, }, { jobTitle: 'Head of Engineering', recruitmentDate: new Date(2016, 3, 14), contract: 'full time', id: 8, }, { jobTitle: 'Tech lead front', recruitmentDate: new Date(2016, 5, 17), contract: 'full time', id: 9, }, { jobTitle: 'Front-end developer', recruitmentDate: new Date(2019, 11, 7), contract: 'full time', id: 10, }, { jobTitle: 'Tech lead devops', recruitmentDate: new Date(2021, 7, 1), contract: 'full time', id: 11, }, { jobTitle: 'Tech lead back', recruitmentDate: new Date(2017, 0, 12), contract: 'full time', id: 12, }, { jobTitle: 'Back-end developer', recruitmentDate: new Date(2019, 2, 22), contract: 'intern', id: 13, }, { jobTitle: 'Back-end developer', recruitmentDate: new Date(2018, 4, 19), contract: 'part time', id: 14, }, ]; const columns: GridColDef[] = [ { field: 'jobTitle', headerName: 'Job Title', width: 200 }, { field: 'recruitmentDate', headerName: 'Recruitment Date', type: 'date', width: 150, }, { field: 'contract', headerName: 'Contract Type', type: 'singleSelect', valueOptions: ['full time', 'part time', 'intern'], width: 150, }, ]; export default function PageSizeAutoPremium() { return (
); } ``` ## Size of the page The Data Grid (MIT license) is limited to pages of up to 100 rows. If you want larger pages, you will need to upgrade to [Pro plan](/x/introduction/licensing/#pro-plan) or above. By default, each page contains 100 rows. The user can change the size of the page through the selector in the footer. ### Page size options You can customize the options shown in the "Rows per page" select using the `pageSizeOptions` prop. You should provide an array of items, each item should be one of these types: - **number**, each number will be used for the option's label and value. ```jsx ``` - **object**, the `value` and `label` keys will be used respectively for the value and label of the option. Define `value` as `-1` to display all results. ```jsx ``` ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function PageSizeCustomOptions() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); return (
); } ``` ### Automatic page size Use the `autoPageSize` prop to auto-scale the `pageSize` to match the container height and the max number of rows that can be displayed without a vertical scroll bar. :::warning You cannot use both the `autoPageSize` and `autoHeight` props at the same time because `autoHeight` scales the height of the Data Grid according to the `pageSize`. ::: ```tsx import * as React from 'react'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; import Stack from '@mui/material/Stack'; import MenuItem from '@mui/material/MenuItem'; import FormControl from '@mui/material/FormControl'; import InputLabel from '@mui/material/InputLabel'; import Select from '@mui/material/Select'; export default function PageSizeAuto() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, maxColumns: 6, }); const [height, setHeight] = React.useState(400); return ( Height of the container
); } ``` ## Pagination model The pagination model is an object containing the current page and the size of the page. The default value is `{ page: 0, pageSize: 100 }`. To change the default value, make it controlled by `paginationModel` prop or initialize a custom value using `initialState.pagination.paginationModel`. ### Initializing the pagination model To initialize the pagination model without controlling it, provide the `paginationModel` to the `initialState` prop. If you don't provide a value for one of the properties, the default value will be used. ```tsx ``` ```tsx import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function PaginationModelInitialState() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 500, maxColumns: 6, }); return (
); } ``` ### Controlled pagination model Pass the `paginationModel` prop to control the size and current page of the grid. You can use the `onPaginationModelChange` prop to listen to changes to the `paginationModel` and update the prop accordingly. ```tsx const [paginationModel, setPaginationModel] = React.useState({ pageSize: 25, page: 0, }); ; ``` ```tsx import * as React from 'react'; import { DataGrid } from '@mui/x-data-grid'; import { useDemoData } from '@mui/x-data-grid-generator'; export default function PaginationModelControlled() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 500, maxColumns: 6, }); const [paginationModel, setPaginationModel] = React.useState({ pageSize: 25, page: 0, }); return (
); } ``` ## Server-side pagination By default, the pagination is handled on the client. This means you have to give the rows of all pages to the Data Grid. If your dataset is too big, and you want to fetch the pages on demand, you can use server-side pagination. :::warning If you enable server-side pagination with no other server-side features, then the Data Grid will only be provided with partial data for filtering and sorting. To be able to work with the entire dataset, you must also implement [server-side filtering](/x/react-data-grid/filtering/server-side/) and [server-side sorting](/x/react-data-grid/sorting/#server-side-sorting). The demo below does exactly that. ::: ```tsx import * as React from 'react'; import { DataGrid, GridSortModel, GridFilterModel } from '@mui/x-data-grid'; import { createFakeServer } from '@mui/x-data-grid-generator'; const SERVER_OPTIONS = { useCursorPagination: false, }; const { useQuery, ...data } = createFakeServer({}, SERVER_OPTIONS); export default function ServerPaginationFilterSortGrid() { const [paginationModel, setPaginationModel] = React.useState({ page: 0, pageSize: 5, }); const [sortModel, setSortModel] = React.useState([]); const [filterModel, setFilterModel] = React.useState({ items: [], }); const queryOptions = React.useMemo( () => ({ ...paginationModel, sortModel, filterModel }), [paginationModel, sortModel, filterModel], ); const { isLoading, rows, pageInfo } = useQuery(queryOptions); // Some API clients return undefined while loading // Following lines are here to prevent `rowCount` from being undefined during the loading const rowCountRef = React.useRef(pageInfo?.totalRowCount || 0); const rowCount = React.useMemo(() => { if (pageInfo?.totalRowCount !== undefined) { rowCountRef.current = pageInfo.totalRowCount; } return rowCountRef.current; }, [pageInfo?.totalRowCount]); return (
); } ``` In general, the server-side pagination could be categorized into two types: - Index-based pagination - Cursor-based pagination :::info Check out [Selection—Usage with server-side pagination](/x/react-data-grid/row-selection/#usage-with-server-side-pagination) for more details. ::: ### Index-based pagination The index-based pagination uses the `page` and `pageSize` to fetch the data from the server page by page. To enable server-side pagination, you need to: - Set the `paginationMode` prop to `server` - Use the `onPaginationModelChange` prop to react to the page changes and load the data from the server The server-side pagination can be further categorized into sub-types based on the availability of the total number of rows or `rowCount`. The Data Grid uses the `rowCount` to calculate the number of pages and to show the information about the current state of the pagination in the footer. You can provide the `rowCount` in one of the following ways: - **Initialize.** Use the `initialState.pagination.rowCount` prop to initialize the `rowCount`. - **Control.** Use the `rowCount` prop along with `onRowCountChange` to control the `rowCount` and reflect the changes when the row count is updated. - **Set using the API.** Use the `apiRef.current.setRowCount` method to set the `rowCount` after the Grid is initialized. There can be three different possibilities regarding the availability of the `rowCount` on the server-side: 1. Row count is available (known) 2. Row count is not available (unknown) 3. Row count is available but is not accurate and may update later on (estimated) :::warning The `rowCount` prop is used in server-side pagination mode to inform the DataGrid about the total number of rows in your dataset. This prop is ignored when the `paginationMode` is set to `client`, that is when the pagination is handled on the client-side. ::: You can configure `rowCount`, `paginationMeta.hasNextPage`, and `estimatedRowCount` props to handle the above scenarios. | | `rowCount` | `paginationMeta.hasNextPage` | `estimatedRowCount` | | :------------------ | :--------- | :--------------------------- | :------------------ | | Known row count | `number` | — | — | | Unknown row count | `-1` | `boolean` | — | | Estimated row count | `-1` | `boolean` | `number` | #### Known row count Pass the props to the Data Grid as explained in the table above to handle the case when the actual row count is known, as the following example demonstrates. ```tsx import * as React from 'react'; import { DataGrid } from '@mui/x-data-grid'; import { createFakeServer } from '@mui/x-data-grid-generator'; const SERVER_OPTIONS = { useCursorPagination: false, }; const { useQuery, ...data } = createFakeServer({}, SERVER_OPTIONS); export default function ServerPaginationGrid() { const [paginationModel, setPaginationModel] = React.useState({ page: 0, pageSize: 5, }); const { isLoading, rows, pageInfo } = useQuery(paginationModel); // Some API clients return undefined while loading // Following lines are here to prevent `rowCount` from being undefined during the loading const rowCountRef = React.useRef(pageInfo?.totalRowCount || 0); const rowCount = React.useMemo(() => { if (pageInfo?.totalRowCount !== undefined) { rowCountRef.current = pageInfo.totalRowCount; } return rowCountRef.current; }, [pageInfo?.totalRowCount]); return (
); } ``` :::warning If the value `rowCount` becomes `undefined` during loading, it will reset the page to zero. To avoid this issue, you can memoize the `rowCount` value to ensure it doesn't change during loading: ```jsx const rowCountRef = React.useRef(pageInfo?.totalRowCount || 0); const rowCount = React.useMemo(() => { if (pageInfo?.totalRowCount !== undefined) { rowCountRef.current = pageInfo.totalRowCount; } return rowCountRef.current; }, [pageInfo?.totalRowCount]); ; ``` ::: #### Unknown row count Pass the props to the Data Grid as explained in the table above to handle the case when the actual row count is unknown, as the following example demonstrates. ```tsx import * as React from 'react'; import { DataGrid, GridPaginationMeta, useGridApiRef } from '@mui/x-data-grid'; import { createFakeServer } from '@mui/x-data-grid-generator'; const SERVER_OPTIONS = { useCursorPagination: false, }; const rowLength = 98; const { useQuery, ...data } = createFakeServer({ rowLength }, SERVER_OPTIONS); export default function ServerPaginationGridNoRowCount() { const apiRef = useGridApiRef(); const [paginationModel, setPaginationModel] = React.useState({ page: 0, pageSize: 5, }); const { isLoading, rows, pageInfo: { hasNextPage }, } = useQuery(paginationModel); const paginationMetaRef = React.useRef(undefined); // Memoize to avoid flickering when the `hasNextPage` is `undefined` during refetch const paginationMeta = React.useMemo(() => { if ( hasNextPage !== undefined && paginationMetaRef.current?.hasNextPage !== hasNextPage ) { paginationMetaRef.current = { hasNextPage }; } return paginationMetaRef.current; }, [hasNextPage]); return (
); } ``` :::warning The value of the `hasNextPage` variable might become `undefined` during loading if it's handled by some external fetching hook resulting in unwanted computations, one possible solution could be to memoize the `paginationMeta`: ```tsx const paginationMetaRef = React.useRef(); const paginationMeta = React.useMemo(() => { if ( hasNextPage !== undefined && paginationMetaRef.current?.hasNextPage !== hasNextPage ) { paginationMetaRef.current = { hasNextPage }; } return paginationMetaRef.current; }, [hasNextPage]); ``` ::: #### Estimated row count Estimated row count could be considered a hybrid approach that switches between the "Known row count" and "Unknown row count" use cases. Initially, when an `estimatedRowCount` is set and `rowCount={-1}`, the Data Grid behaves as in the "Unknown row count" use case, but with the `estimatedRowCount` value shown in the pagination footer. If the number of rows loaded exceeds the `estimatedRowCount`, the Data Grid ignores the `estimatedRowCount` and the behavior is identical to the "Unknown row count" use case. When the `hasNextPage` returns `false` or `rowCount` is set to a positive number, the Data Grid switches to the "Known row count" behavior. In the following example, the actual row count is `1000` but the Data Grid is initially provided with `estimatedRowCount={100}`. You can set the `rowCount` to the actual row count by pressing the "Set Row Count" button. ```tsx import * as React from 'react'; import Button from '@mui/material/Button'; import { DataGrid, useGridApiRef } from '@mui/x-data-grid'; import type { GridPaginationMeta } from '@mui/x-data-grid'; import { createFakeServer } from '@mui/x-data-grid-generator'; const SERVER_OPTIONS = { useCursorPagination: false, }; const { useQuery, ...data } = createFakeServer({ rowLength: 1000 }, SERVER_OPTIONS); export default function ServerPaginationGridEstimated() { const apiRef = useGridApiRef(); const [paginationModel, setPaginationModel] = React.useState({ page: 0, pageSize: 50, }); const { isLoading, rows, pageInfo: { hasNextPage }, } = useQuery(paginationModel); const paginationMetaRef = React.useRef({}); // Memoize to avoid flickering when the `hasNextPage` is `undefined` during refetch const paginationMeta = React.useMemo(() => { if ( hasNextPage !== undefined && paginationMetaRef.current?.hasNextPage !== hasNextPage ) { paginationMetaRef.current = { hasNextPage }; } return paginationMetaRef.current; }, [hasNextPage]); return (
); } ``` :::warning The `hasNextPage` must not be set to `false` until there are _actually_ no records left to fetch, because when `hasNextPage` becomes `false`, the Grid considers this as the last page and tries to set the `rowCount` value to a finite value. If an external data fetching library sets the values to undefined during loading, you can memoize the `paginationMeta` value to ensure it doesn't change during loading as shown in the "Unknown row count" section. ::: :::info 🌍 **Localization of the estimated row count** The Data Grid uses the [Table Pagination](/material-ui/api/table-pagination/) component from the Material UI library which doesn't support `estimated` row count. Until this is supported natively by the Table Pagination component, a workaround to make the localization work is to provide the `paginationDisplayedRows` function to the `localeText` object as per the locale you are interested in. The Grid injects an additional variable `estimated` to the `paginationDisplayedRows` function which you can use to accommodate the estimated row count. The following example demonstrates how to show the estimated row count in the pagination footer in the Croatian (hr-HR) language. ```jsx const paginationDisplayedRows = ({ from, to, count, estimated }) => { if (!estimated) { return `${from}–${to} od ${count !== -1 ? count : `više nego ${to}`}`; } const estimateLabel = estimated && estimated > to ? `oko ${estimated}` : `više nego ${to}`; return `${from}–${to} od ${count !== -1 ? count : estimateLabel}`; }; ; ``` For more information, see the [Translation keys](/x/react-data-grid/localization/#translation-keys) section of the localization documentation. ::: ### Cursor-based pagination You can also handle servers with cursor-based pagination. To do so, you just have to keep track of the next cursor associated with each page you fetched. ```tsx import * as React from 'react'; import { DataGrid, GridRowId, GridPaginationModel, GridPaginationMeta, } from '@mui/x-data-grid'; import Radio from '@mui/material/Radio'; import RadioGroup from '@mui/material/RadioGroup'; import FormControlLabel from '@mui/material/FormControlLabel'; import FormControl from '@mui/material/FormControl'; import FormLabel from '@mui/material/FormLabel'; import { createFakeServer } from '@mui/x-data-grid-generator'; const PAGE_SIZE = 5; const SERVER_OPTIONS = { useCursorPagination: true, }; const { useQuery, ...data } = createFakeServer({}, SERVER_OPTIONS); type RowCountType = 'known' | 'unknown' | 'estimated'; export default function CursorPaginationGrid() { const [rowCountType, setRowCountType] = React.useState('known'); const mapPageToNextCursor = React.useRef<{ [page: number]: GridRowId }>({}); const [paginationModel, setPaginationModel] = React.useState({ page: 0, pageSize: PAGE_SIZE, }); const queryOptions = React.useMemo( () => ({ cursor: mapPageToNextCursor.current[paginationModel.page - 1], pageSize: paginationModel.pageSize, }), [paginationModel], ); const { isLoading, rows, pageInfo: { hasNextPage, nextCursor, totalRowCount }, } = useQuery(queryOptions); const handlePaginationModelChange = (newPaginationModel: GridPaginationModel) => { // We have the cursor, we can allow the page transition. if ( newPaginationModel.page === 0 || mapPageToNextCursor.current[newPaginationModel.page - 1] ) { setPaginationModel(newPaginationModel); } }; const paginationMetaRef = React.useRef(undefined); // Memoize to avoid flickering when the `hasNextPage` is `undefined` during refetch const paginationMeta = React.useMemo(() => { if ( hasNextPage !== undefined && paginationMetaRef.current?.hasNextPage !== hasNextPage ) { paginationMetaRef.current = { hasNextPage }; } return paginationMetaRef.current; }, [hasNextPage]); React.useEffect(() => { if (!isLoading && nextCursor) { // We add nextCursor when available mapPageToNextCursor.current[paginationModel.page] = nextCursor; } }, [paginationModel.page, isLoading, nextCursor]); // Some API clients return undefined while loading // Following lines are here to prevent `rowCountState` from being undefined during the loading const [rowCountState, setRowCountState] = React.useState(totalRowCount || 0); React.useEffect(() => { if (rowCountType === 'known') { setRowCountState((prevRowCountState) => totalRowCount !== undefined ? totalRowCount : prevRowCountState, ); } if ( (rowCountType === 'unknown' || rowCountType === 'estimated') && paginationMeta?.hasNextPage !== false ) { setRowCountState(-1); } }, [paginationMeta?.hasNextPage, rowCountType, totalRowCount]); const prevEstimatedRowCount = React.useRef(undefined); const estimatedRowCount = React.useMemo(() => { if (rowCountType === 'estimated') { if (totalRowCount !== undefined) { if (prevEstimatedRowCount.current === undefined) { prevEstimatedRowCount.current = totalRowCount / 2; } return totalRowCount / 2; } return prevEstimatedRowCount.current; } return undefined; }, [rowCountType, totalRowCount]); return (
Row count setRowCountType(event.target.value as RowCountType)} > } label="Known" /> } label="Unknown" /> } label="Estimated" />
setRowCountState(newRowCount)} estimatedRowCount={estimatedRowCount} paginationMeta={paginationMeta} paginationMode="server" onPaginationModelChange={handlePaginationModelChange} paginationModel={paginationModel} loading={isLoading} />
); } ``` ## Custom pagination UI You can customize the rendering of the pagination in the footer following [the component section](/x/react-data-grid/components/#pagination) of the documentation. ## apiRef The Data Grid exposes a set of methods via the `apiRef` object that are used internally in the implementation of the pagination 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. ::: ```jsx import ApiDocs from 'docsx/src/modules/components/ApiDocs'; import api from 'docsx/pages/x/api/data-grid/grid-pagination-api.json'; export default function PaginationApiNoSnap() { return ; } ``` ## Selectors {{"component": "modules/components/SelectorsDocs.js", "category": "Pagination"}} More information about the selectors and how to use them on the [dedicated page](/x/react-data-grid/state/#access-the-state) ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/performance.md # Data Grid - Performance Follow these recommendations to improve your Data Grid's performance. The Data Grid is a complex component that renders many elements, and you can inadvertently introduce performance issues by triggering unnecessary re-renders. This guide describes best practices for implementing your Data Grid to avoid common problems. ## Maintain a stable reference when passing props As a general rule, all non-primitive props should maintain a stable reference between renders to avoid unnecessary re-renders. This is especially important for the `columns` prop. Columns are designed to be definitions that never change once the component is mounted; otherwise, you risk losing elements like column width or order. There are two ways to maintain a stable reference: 1. If the columns don't depend on anything within the component scope, you can define them outside of the component and pass them as a prop: ```tsx const columns = [ { field: 'id' }, { field: 'firstName' }, { field: 'lastName' }, { field: 'age' }, { field: 'fullName' }, ]; function App() { return ; } ``` 2. If the columns require something within the component scope, such as a state value or a prop, you can use the `useMemo` hook to keep a stable reference between renders: ```tsx function App(props) { const renderCell = React.useCallback( (params) => { return ( {params.value} {props.someValue} ); }, [props.someValue], ); const columns = React.useMemo( () => [ { field: 'id' }, { field: 'firstName' }, { field: 'lastName' }, { field: 'age' }, { field: 'fullName', renderCell }, ], [renderCell], ); return ; } ``` ## Extract static objects and memoize root props The Data Grid component uses `React.memo` to optimize its performance, which means the Grid and its subcomponents only re-render when their props change. But it's very easy to cause unnecessary re-renders if the root props of your Data Grid aren't memoized. In the example below, the `slots` and `initialState` objects are re-created on every render, which means the Data Grid itself has no choice but to re-render as well. ```tsx function Component(props) { return ( ); } ``` One way to prevent re-renders is to extract any objects that can be static, and to memoize any objects that depend on other objects. This applies to any prop that's an object or a function. ```tsx const slots = { row: CustomRow, }; function Component(props) { const cellModesModel = React.useMemo( () => ({ [props.rows[0].id]: { name: { mode: GridCellModes.Edit } } }), [props.rows], ); return ( ); } ``` ## Visualizing the re-rendering process The Data Grid memoizes some of its subcomponents to avoid re-rendering more than necessary. Below is a visualization that shows you which cells re-render in response to your interactions with the Grid. ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import useForkRef from '@mui/utils/useForkRef'; import { DataGridPro, GridCell } from '@mui/x-data-grid-pro'; import { useDemoData } from '@mui/x-data-grid-generator'; const TraceUpdates = React.forwardRef((props, ref) => { const { Component, ...other } = props; const rootRef = React.useRef(null); const handleRef = useForkRef(rootRef, ref); React.useEffect(() => { const root = rootRef.current; root!.classList.add('updating'); root!.classList.add('updated'); const timer = setTimeout(() => { root!.classList.remove('updating'); }, 360); return () => { clearTimeout(timer); }; }); return ; }); const CellWithTracer = React.forwardRef((props, ref) => { return ; }) as typeof GridCell; const slots = { cell: CellWithTracer, }; export default function GridVisualization() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 100, editable: true, maxColumns: 15, }); return ( ({ height: 400, width: '100%', '&&& .updated': { transition: theme.transitions.create(['background-color', 'outline'], { duration: theme.transitions.duration.standard, }), }, '&&& .updating': { backgroundColor: 'rgb(92 199 68 / 20%)', outline: '1px solid rgb(92 199 68 / 35%)', outlineOffset: '-1px', transition: 'none', }, })} > ); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-data-grid/editing/persistence.md # Data Grid - Editing persistence Persisting edited rows. ## The `processRowUpdate()` callback When the user performs an action to [stop editing](/x/react-data-grid/editing/#stop-editing), the `processRowUpdate()` callback is triggered. Use it to send the new values to the server and save them into a database or other storage method. The callback is called with three arguments: 1. The updated row with the new values returned by the [`valueSetter()`](/x/react-data-grid/editing/#value-parser-and-value-setter). 2. The original values of the row before editing. 3. An object with additional properties such as `rowId`. Please note that the `processRowUpdate()` must return the row object to update the Data Grid internal state. The value returned is used later as an argument on a call to `apiRef.current.updateRows()`. ```tsx mySaveOnServerFunction(updatedRow); } onProcessRowUpdateError={handleProcessRowUpdateError} /> ``` If you want to delete a row from the internal state of the Data Grid, you can return an additional property `_action: 'delete'` in the row object from the `processRowUpdate()` callback. This removes the row from the internal state of the Data Grid. It is a more performant way to delete a row as compared to updating the [`rows` prop](/x/react-data-grid/row-updates/#the-rows-prop) or using `setRows()` API method because `processRowUpdate` uses the [`updateRows()`](/x/react-data-grid/row-updates/#the-updaterows-method) under the hood which doesn't cause a full regeneration of the row tree. ```tsx { if (shouldDeleteRow(updatedRow)) { return { ...updatedRow, _action: 'delete' }; } return updatedRow; }} /> ``` In the example above, `shouldDeleteRow` is a function that determines whether a row should be deleted based on the updated row data. If `shouldDeleteRow` returns `true`, the row will be deleted from the Data Grid's internal state. ## Server-side validation If you need to cancel the save process on `processRowUpdate()`—for instance, when a database validation fails, or the user wants to reject the changes—there are two options: 1. Reject the promise so that the internal state is not updated and the cell remains in edit mode. 2. Resolve the promise with the second argument (original row before editing), so that the internal state is not updated, and the cell exits edit mode. The following demo implements the first option: rejecting the promise. Instead of [validating](/x/react-data-grid/editing/#validation) while typing, it simulates validation on the server. If the new name is empty, the promise responsible for saving the row will be rejected, and the cell will remain in edit mode. The demo also shows that `processRowUpdate()` can pre-process the row model that will be saved into the internal state. Additionally, `onProcessRowUpdateError()` is called to display the error message. To exit edit mode, press Escape or enter a valid name. ```tsx import * as React from 'react'; import { DataGrid, GridRowModel, GridColDef, GridRowId, GridRowsProp, } from '@mui/x-data-grid'; import { randomCreatedDate, randomTraderName, randomUpdatedDate, } from '@mui/x-data-grid-generator'; import Snackbar from '@mui/material/Snackbar'; import Alert, { AlertProps } from '@mui/material/Alert'; interface User { name: string; age: number; id: GridRowId; dateCreated: Date; lastLogin: Date; } const useFakeMutation = () => { return React.useCallback( (user: Partial) => new Promise>((resolve, reject) => { setTimeout(() => { if (user.name?.trim() === '') { reject(new Error('Error while saving user: name cannot be empty.')); } else { resolve({ ...user, name: user.name?.toUpperCase() }); } }, 200); }), [], ); }; export default function ServerSidePersistence() { const mutateRow = useFakeMutation(); const [snackbar, setSnackbar] = React.useState | null>(null); const handleCloseSnackbar = () => setSnackbar(null); const processRowUpdate = React.useCallback( async (newRow: GridRowModel) => { // Make the HTTP request to save in the backend const response = await mutateRow(newRow); setSnackbar({ children: 'User successfully saved', severity: 'success' }); return response; }, [mutateRow], ); const handleProcessRowUpdateError = React.useCallback((error: Error) => { setSnackbar({ children: error.message, severity: 'error' }); }, []); return (
{!!snackbar && ( )}
); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 180, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true, align: 'left', headerAlign: 'left', }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, editable: true, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, editable: true, }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` ## Confirm before saving The second option—resolving the promise with the second argument—lets the user cancel the save process by rejecting the changes and exiting the edit mode. In this case, `processRowUpdate()` is resolved with the original value(s) of the row. The following demo shows how this approach can be used to ask for confirmation before sending the data to the server. If the user accepts the change, the internal state is updated with the values. But if the changes are rejected, the internal state remains unchanged, and the cell is reverted back to its original value. The demo also employs validation to prevent entering an empty name. ```tsx import * as React from 'react'; import { DataGrid, GridRowModel, GridColDef, GridRowId, GridRowsProp, } from '@mui/x-data-grid'; import { randomCreatedDate, randomTraderName, randomUpdatedDate, } from '@mui/x-data-grid-generator'; import Snackbar from '@mui/material/Snackbar'; import Dialog from '@mui/material/Dialog'; import DialogTitle from '@mui/material/DialogTitle'; import DialogContent from '@mui/material/DialogContent'; import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; import Alert, { AlertProps } from '@mui/material/Alert'; interface User { name: string; age: number; id: GridRowId; dateCreated: Date; lastLogin: Date; } const useFakeMutation = () => { return React.useCallback( (user: Partial) => new Promise>((resolve, reject) => { setTimeout(() => { if (user.name?.trim() === '') { reject(); } else { resolve(user); } }, 200); }), [], ); }; function computeMutation(newRow: GridRowModel, oldRow: GridRowModel) { if (newRow.name !== oldRow.name) { return `Name from '${oldRow.name}' to '${newRow.name}'`; } if (newRow.age !== oldRow.age) { return `Age from '${oldRow.age || ''}' to '${newRow.age || ''}'`; } return null; } export default function AskConfirmationBeforeSave() { const mutateRow = useFakeMutation(); const noButtonRef = React.useRef(null); const [promiseArguments, setPromiseArguments] = React.useState(null); const [snackbar, setSnackbar] = React.useState | null>(null); const handleCloseSnackbar = () => setSnackbar(null); const processRowUpdate = React.useCallback( (newRow: GridRowModel, oldRow: GridRowModel) => new Promise((resolve, reject) => { const mutation = computeMutation(newRow, oldRow); if (mutation) { // Save the arguments to resolve or reject the promise later setPromiseArguments({ resolve, reject, newRow, oldRow }); } else { resolve(oldRow); // Nothing was changed } }), [], ); const handleNo = () => { const { oldRow, resolve } = promiseArguments; resolve(oldRow); // Resolve with the old row to not update the internal state setPromiseArguments(null); }; const handleYes = async () => { const { newRow, oldRow, reject, resolve } = promiseArguments; try { // Make the HTTP request to save in the backend const response = await mutateRow(newRow); setSnackbar({ children: 'User successfully saved', severity: 'success' }); resolve(response); setPromiseArguments(null); } catch (error) { setSnackbar({ children: 'Name cannot be empty', severity: 'error' }); reject(oldRow); setPromiseArguments(null); } }; const handleEntered = () => { // The `autoFocus` is not used because, if used, the same Enter that saves // the cell triggers "No". Instead, we manually focus the "No" button once // the dialog is fully open. // noButtonRef.current?.focus(); }; const renderConfirmDialog = () => { if (!promiseArguments) { return null; } const { newRow, oldRow } = promiseArguments; const mutation = computeMutation(newRow, oldRow); return ( Are you sure? {`Pressing 'Yes' will change ${mutation}.`} ); }; return (
{renderConfirmDialog()} {!!snackbar && ( )}
); } const columns: GridColDef[] = [ { field: 'name', headerName: 'Name', width: 180, editable: true }, { field: 'age', headerName: 'Age', type: 'number', editable: true }, { field: 'dateCreated', headerName: 'Date Created', type: 'date', width: 180, }, { field: 'lastLogin', headerName: 'Last Login', type: 'dateTime', width: 220, }, ]; const rows: GridRowsProp = [ { id: 1, name: randomTraderName(), age: 25, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 2, name: randomTraderName(), age: 36, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 3, name: randomTraderName(), age: 19, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 4, name: randomTraderName(), age: 28, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, { id: 5, name: randomTraderName(), age: 23, dateCreated: randomCreatedDate(), lastLogin: randomUpdatedDate(), }, ]; ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/api/date-pickers/picker-day-2.md # PickerDay2 API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) - [Customization playground](/x/react-date-pickers/playground/) ## Import ```jsx import { PickerDay2 } from '@mui/x-date-pickers/PickerDay2'; // or import { PickerDay2 } from '@mui/x-date-pickers'; // or import { PickerDay2 } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | day | `object` | - | Yes | | | isFirstVisibleCell | `bool` | - | Yes | | | isLastVisibleCell | `bool` | - | Yes | | | outsideCurrentMonth | `bool` | - | Yes | | | action | `func \| { current?: { focusVisible: func } }` | - | No | | | centerRipple | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | disabled | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableMargin | `bool` | `false` | No | | | disableRipple | `bool` | `false` | No | | | disableTouchRipple | `bool` | `false` | No | | | focusRipple | `bool` | `false` | No | | | focusVisibleClassName | `string` | - | No | | | isVisuallySelected | `bool` | - | No | | | onFocusVisible | `func` | - | No | | | selected | `bool` | `false` | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | today | `bool` | `false` | No | | | TouchRippleProps | `object` | - | No | | | touchRippleRef | `func \| { current?: { pulsate: func, start: func, stop: func } }` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLButtonElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiPickerDay2` to change the default props of this component with the theme. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | dayOutsideMonth | Styles applied to the root element if `outsideCurrentMonth=true` and `showDaysOutsideCurrentMonth=true`. | | `.Mui-disabled` | - | State class applied to the root element if `disabled=true`. | | - | fillerCell | Styles applied to the root element if `outsideCurrentMonth=true` and `showDaysOutsideCurrentMonth=false`. | | - | root | Styles applied to the root element. | | `.Mui-selected` | - | State class applied to the root element if `selected=true`. | | - | today | Styles applied to the root element if `disableHighlightToday=false` and `today=true`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickerDay2/PickerDay2.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickerDay2/PickerDay2.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-action-bar.md # PickersActionBar API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) - [Custom layout](/x/react-date-pickers/custom-layout/) ## Import ```jsx import { PickersActionBar } from '@mui/x-date-pickers/PickersActionBar'; // or import { PickersActionBar } from '@mui/x-date-pickers'; // or import { PickersActionBar } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | actions | `Array<'accept' \| 'cancel' \| 'clear' \| 'next' \| 'nextOrAccept' \| 'today'>` | ``[]` for Pickers with one selection step which `closeOnSelect`. - `['cancel', 'nextOrAccept']` for all other Pickers.` | No | | | disableSpacing | `bool` | `false` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | > **Note**: The `ref` is forwarded to the root element. > Any other props supplied will be provided to the root element (native element). ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | root | Styles applied to the root element. | | - | spacing | Styles applied to the root element unless `disableSpacing={true}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickersActionBar/PickersActionBar.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickersActionBar/PickersActionBar.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-calendar-header.md # PickersCalendarHeader API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) ## Import ```jsx import { PickersCalendarHeader } from '@mui/x-date-pickers/PickersCalendarHeader'; // or import { PickersCalendarHeader } from '@mui/x-date-pickers'; // or import { PickersCalendarHeader } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | format | `string` | ``${adapter.formats.month} ${adapter.formats.year}`` | No | | | labelId | `string` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiPickersCalendarHeader` to change the default props of this component with the theme. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | leftArrowIcon | `ArrowLeft` | - | Icon displayed in the left view switch button. | | nextIconButton | `IconButton` | - | Button allowing to switch to the right view. | | previousIconButton | `IconButton` | - | Button allowing to switch to the left view. | | rightArrowIcon | `ArrowRight` | - | Icon displayed in the right view switch button. | | switchViewButton | `IconButton` | `.MuiPickersCalendarHeader-switchViewButton` | Button displayed to switch between different calendar views. | | switchViewIcon | `ArrowDropDown` | `.MuiPickersCalendarHeader-switchViewIcon` | Icon displayed in the SwitchViewButton. Rotated by 180° when the open view is `year`. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | label | Styles applied to the label element. | | - | labelContainer | Styles applied to the label container element. | | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickersCalendarHeader/PickersCalendarHeader.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-day.md # PickersDay API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Date Calendar](/x/react-date-pickers/date-calendar/) ## Import ```jsx import { PickersDay } from '@mui/x-date-pickers/PickersDay'; // or import { PickersDay } from '@mui/x-date-pickers'; // or import { PickersDay } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | day | `object` | - | Yes | | | isFirstVisibleCell | `bool` | - | Yes | | | isLastVisibleCell | `bool` | - | Yes | | | outsideCurrentMonth | `bool` | - | Yes | | | action | `func \| { current?: { focusVisible: func } }` | - | No | | | centerRipple | `bool` | `false` | No | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | disabled | `bool` | `false` | No | | | disableHighlightToday | `bool` | `false` | No | | | disableMargin | `bool` | `false` | No | | | disableRipple | `bool` | `false` | No | | | disableTouchRipple | `bool` | `false` | No | | | focusRipple | `bool` | `false` | No | | | focusVisibleClassName | `string` | - | No | | | onFocusVisible | `func` | - | No | | | selected | `bool` | `false` | No | | | showDaysOutsideCurrentMonth | `bool` | `false` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | today | `bool` | `false` | No | | | TouchRippleProps | `object` | - | No | | | touchRippleRef | `func \| { current?: { pulsate: func, start: func, stop: func } }` | - | No | | > **Note**: The `ref` is forwarded to the root element (HTMLButtonElement). > Any other props supplied will be provided to the root element (native element). ## Theme default props You can use `MuiPickersDay` to change the default props of this component with the theme. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | dayOutsideMonth | Styles applied to the root element if `outsideCurrentMonth=true` and `showDaysOutsideCurrentMonth=true`. | | - | dayWithMargin | Styles applied to the root element if `disableMargin=false`. | | `.Mui-disabled` | - | State class applied to the root element if `disabled=true`. | | - | hiddenDaySpacingFiller | Styles applied to the root element if `outsideCurrentMonth=true` and `showDaysOutsideCurrentMonth=false`. | | - | root | Styles applied to the root element. | | `.Mui-selected` | - | State class applied to the root element if `selected=true`. | | - | today | Styles applied to the root element if `disableHighlightToday=false` and `today=true`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickersDay/PickersDay.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickersDay/PickersDay.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-layout.md # PickersLayout API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom layout](/x/react-date-pickers/custom-layout/) ## Import ```jsx import { PickersLayout } from '@mui/x-date-pickers/PickersLayout'; // or import { PickersLayout } from '@mui/x-date-pickers'; // or import { PickersLayout } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | classes | `object` | - | No | Override or extend the styles applied to the component. | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | actionBar | `PickersActionBar` | `.MuiPickersLayout-actionBar` | Custom component for the action bar, it is placed below the Picker views. | | layout | `undefined` | - | Custom component for wrapping the layout. It wraps the toolbar, views, action bar, and shortcuts. | | shortcuts | `PickersShortcuts` | `.MuiPickersLayout-shortcuts` | Custom component for the shortcuts. | | tabs | `undefined` | `.MuiPickersLayout-tabs` | Tabs enabling toggling between views. | | toolbar | `undefined` | `.MuiPickersLayout-toolbar` | Custom component for the toolbar. It is placed above the Picker views. | ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | contentWrapper | Styles applied to the contentWrapper element (which contains the tabs and the view itself). | | - | landscape | Styles applied to the root element in landscape orientation. | | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickersLayout/PickersLayout.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-range-calendar-header.md # PickersRangeCalendarHeader API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) ## Import ```jsx import { PickersRangeCalendarHeader } from '@mui/x-date-pickers-pro/PickersRangeCalendarHeader'; // or import { PickersRangeCalendarHeader } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | calendars | `1 \| 2 \| 3` | - | Yes | | | month | `object` | - | Yes | | | monthIndex | `number` | - | Yes | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | format | `string` | ``${adapter.formats.month} ${adapter.formats.year}`` | No | | | labelId | `string` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | > **Note**: The `ref` is forwarded to the root element (HTMLDivElement). > Any other props supplied will be provided to the root element (native element). ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | label | Styles applied to the label element. | | - | labelContainer | Styles applied to the label container element. | | - | root | Styles applied to the root element. | | - | switchViewButton | Styles applied to the switch view button element. | | - | switchViewIcon | Styles applied to the switch view icon element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers-pro/src/PickersRangeCalendarHeader/PickersRangeCalendarHeader.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers-pro/src/PickersRangeCalendarHeader/PickersRangeCalendarHeader.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-section-list.md # PickersSectionList API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom field](/x/react-date-pickers/custom-field/) ## Import ```jsx import { PickersSectionList } from '@mui/x-date-pickers/PickersSectionList'; // or import { PickersSectionList } from '@mui/x-date-pickers'; // or import { PickersSectionList } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | contentEditable | `bool` | - | Yes | | | elements | `Array<{ after: object, before: object, container: object, content: object }>` | - | Yes | | | classes | `object` | - | No | Override or extend the styles applied to the component. | | slotProps | `object` | - | No | | | slots | `object` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | root | `undefined` | `.MuiPickersSectionList-root` | | | section | `undefined` | `.MuiPickersSectionList-section` | | | sectionContent | `undefined` | `.MuiPickersSectionList-sectionContent` | | | sectionSeparator | `undefined` | - | | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickersSectionList/PickersSectionList.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickersSectionList/PickersSectionList.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-shortcuts.md # PickersShortcuts API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom slots and subcomponents](/x/react-date-pickers/custom-components/) - [Shortcuts](/x/react-date-pickers/shortcuts/) ## Import ```jsx import { PickersShortcuts } from '@mui/x-date-pickers/PickersShortcuts'; // or import { PickersShortcuts } from '@mui/x-date-pickers'; // or import { PickersShortcuts } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | changeImportance | `'accept' \| 'set'` | `"accept"` | No | | | dense | `bool` | `false` | No | | | disablePadding | `bool` | `false` | No | | | items | `Array<{ getValue: func, id?: string, label: string }>` | `[]` | No | | | subheader | `node` | - | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | > **Note**: The `ref` is forwarded to the root element. ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickersShortcuts/PickersShortcuts.tsx) --- # Source: https://mui.com/x/api/date-pickers/pickers-text-field.md # PickersTextField API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Custom field](/x/react-date-pickers/custom-field/) ## Import ```jsx import { PickersTextField } from '@mui/x-date-pickers/PickersTextField'; // or import { PickersTextField } from '@mui/x-date-pickers'; // or import { PickersTextField } from '@mui/x-date-pickers-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | areAllSectionsEmpty | `bool` | - | Yes | | | contentEditable | `bool` | - | Yes | | | elements | `Array<{ after: object, before: object, container: object, content: object }>` | - | Yes | | | color | `'error' \| 'info' \| 'primary' \| 'secondary' \| 'success' \| 'warning'` | `'primary'` | No | | | focused | `bool` | - | No | | | helperText | `node` | - | No | | | hiddenLabel | `bool` | `false` | No | | | InputProps | `object` | - | No | | | margin | `'dense' \| 'none' \| 'normal'` | `'none'` | No | | | required | `bool` | `false` | No | | | size | `'medium' \| 'small'` | `'medium'` | No | | | sx | `Array \| func \| object` | - | No | The system prop that allows defining system overrides as well as additional CSS styles. | | variant | `'filled' \| 'outlined' \| 'standard'` | `'outlined'` | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | fullWidth | Styles applied to the root element if `fullWidth={true}`. | | - | marginDense | Styles applied to the root element if `margin="dense"`. | | - | marginNormal | Styles applied to the root element if `margin="normal"`. | | - | root | Styles applied to the root element. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-date-pickers/src/PickersTextField/PickersTextField.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-date-pickers/src/PickersTextField/PickersTextField.tsx) --- # Source: https://mui.com/x/api/charts/pie-arc-label-plot.md # PieArcLabelPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Pie](/x/react-charts/pie/) - [Charts - Pie demos](/x/react-charts/pie-demo/) ## Import ```jsx import { PieArcLabelPlot } from '@mui/x-charts/PieChart'; // or import { PieArcLabelPlot } from '@mui/x-charts'; // or import { PieArcLabelPlot } from '@mui/x-charts-pro'; // or import { PieArcLabelPlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | id | `number \| string` | - | Yes | | | outerRadius | `number` | - | Yes | | | arcLabel | `'formattedValue' \| 'label' \| 'value' \| func` | - | No | | | arcLabelMinAngle | `number` | `0` | No | | | arcLabelRadius | `number` | `(innerRadius - outerRadius) / 2` | No | | | cornerRadius | `number` | `0` | No | | | faded | `{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }` | `{ additionalRadius: -5 }` | No | | | highlighted | `{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }` | - | No | | | innerRadius | `number` | `0` | No | | | paddingAngle | `number` | `0` | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | pieArcLabel | `undefined` | - | | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/PieChart/PieArcLabelPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/PieChart/PieArcLabelPlot.tsx) --- # Source: https://mui.com/x/api/charts/pie-arc-label.md # PieArcLabel API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Pie](/x/react-charts/pie/) - [Charts - Pie demos](/x/react-charts/pie-demo/) ## Import ```jsx import { PieArcLabel } from '@mui/x-charts/PieChart'; // or import { PieArcLabel } from '@mui/x-charts'; // or import { PieArcLabel } from '@mui/x-charts-pro'; // or import { PieArcLabel } from '@mui/x-charts-premium'; ``` > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | animate | Styles applied to the root element when animation is not skipped. | | - | faded | Styles applied to the root element when faded. | | - | highlighted | Styles applied to the root element when highlighted. | | - | root | Styles applied to the root element. | | - | series | Styles applied to the root element for a specified series. Needs to be suffixed with the series ID: `.${pieArcLabelClasses.series}-${seriesId}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/PieChart/PieArcLabel.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/PieChart/PieArcLabel.tsx) --- # Source: https://mui.com/x/api/charts/pie-arc-plot.md # PieArcPlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Pie](/x/react-charts/pie/) - [Charts - Pie demos](/x/react-charts/pie-demo/) ## Import ```jsx import { PieArcPlot } from '@mui/x-charts/PieChart'; // or import { PieArcPlot } from '@mui/x-charts'; // or import { PieArcPlot } from '@mui/x-charts-pro'; // or import { PieArcPlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | id | `number \| string` | - | Yes | | | outerRadius | `number` | - | Yes | | | arcLabelRadius | `number` | `(innerRadius - outerRadius) / 2` | No | | | cornerRadius | `number` | `0` | No | | | faded | `{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }` | `{ additionalRadius: -5 }` | No | | | highlighted | `{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }` | - | No | | | innerRadius | `number` | `0` | No | | | onItemClick | `function(event: React.MouseEvent, pieItemIdentifier: PieItemIdentifier, item: DefaultizedPieValueType) => void` | - | No | | | paddingAngle | `number` | `0` | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | pieArc | `undefined` | - | | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/PieChart/PieArcPlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/PieChart/PieArcPlot.tsx) --- # Source: https://mui.com/x/api/charts/pie-arc.md # PieArc API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Pie](/x/react-charts/pie/) - [Charts - Pie demos](/x/react-charts/pie-demo/) ## Import ```jsx import { PieArc } from '@mui/x-charts/PieChart'; // or import { PieArc } from '@mui/x-charts'; // or import { PieArc } from '@mui/x-charts-pro'; // or import { PieArc } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | skipAnimation | `bool` | - | No | | | skipInteraction | `bool` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## CSS ### Rule name | Global class | Rule name | Description | |--------------|-----------|-------------| | - | faded | Styles applied to the root element when faded. | | - | focusIndicator | Styles applied to the focus indicator element. | | - | highlighted | Styles applied to the root element when highlighted. | | - | root | Styles applied to the root element. | | - | series | Styles applied to the root element for a specified series. Needs to be suffixed with the series ID: `.${pieArcClasses.series}-${seriesId}`. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/PieChart/PieArc.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/PieChart/PieArc.tsx) --- # Source: https://mui.com/x/api/charts/pie-chart-pro.md # PieChartPro API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Pie](/x/react-charts/pie/) ## Import ```jsx import { PieChartPro } from '@mui/x-charts-pro/PieChartPro'; // or import { PieChartPro } from '@mui/x-charts-pro'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'pie' }>` | - | No | | | hideLegend | `bool` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'pie' }>` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onItemClick | `func` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | showToolbar | `bool` | `false` | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex: number, seriesId: number \| string, type: 'pie' }` | - | No | | | width | `number` | - | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | baseButton | `undefined` | - | | | baseDivider | `undefined` | - | | | baseIconButton | `undefined` | - | | | baseMenuItem | `undefined` | - | | | baseMenuList | `undefined` | - | | | basePopper | `undefined` | - | | | baseTooltip | `undefined` | - | | | exportIcon | `ChartsExportIcon` | - | Icon displayed on the toolbar's export button. | | legend | `ChartsLegend` | - | Custom rendering of the legend. | | loadingOverlay | `ChartsLoadingOverlay` | - | Overlay component rendered when the chart is in a loading state. | | noDataOverlay | `ChartsNoDataOverlay` | - | Overlay component rendered when the chart has no data to display. | | pieArc | `undefined` | - | | | pieArcLabel | `undefined` | - | | | toolbar | `ChartsToolbar` | - | Custom component for the toolbar. | | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | | zoomInIcon | `ChartsZoomInIcon` | - | Icon displayed on the toolbar's zoom in button. | | zoomOutIcon | `ChartsZoomOutIcon` | - | Icon displayed on the toolbar's zoom out button. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts-pro/src/PieChartPro/PieChartPro.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts-pro/src/PieChartPro/PieChartPro.tsx) --- # Source: https://mui.com/x/api/charts/pie-chart.md # PieChart API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Label](/x/react-charts/label/) - [Charts - Pie](/x/react-charts/pie/) - [Charts - Pie demos](/x/react-charts/pie-demo/) ## Import ```jsx import { PieChart } from '@mui/x-charts/PieChart'; // or import { PieChart } from '@mui/x-charts'; // or import { PieChart } from '@mui/x-charts-pro'; // or import { PieChart } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | series | `Array` | - | Yes | | | colors | `Array \| func` | `rainbowSurgePalette` | No | | | dataset | `Array` | - | No | | | height | `number` | - | No | | | hiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'pie' }>` | - | No | | | hideLegend | `bool` | - | No | | | highlightedItem | `{ dataIndex?: number, seriesId: number \| string }` | - | No | | | id | `string` | - | No | | | initialHiddenItems | `Array<{ dataIndex?: number, seriesId?: number \| string, type: 'pie' }>` | - | No | | | loading | `bool` | `false` | No | | | localeText | `object` | - | No | | | margin | `number \| { bottom?: number, left?: number, right?: number, top?: number }` | - | No | | | onHiddenItemsChange | `function(hiddenItems: Array) => void` | - | No | | | onHighlightChange | `function(highlightedItem: HighlightItemData \| null) => void` | - | No | | | onItemClick | `func` | - | No | | | onTooltipItemChange | `function(tooltipItem: SeriesItemIdentifier \| null) => void` | - | No | | | showToolbar | `bool` | `false` | No | | | skipAnimation | `bool` | - | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | | tooltipItem | `{ dataIndex: number, seriesId: number \| string, type: 'pie' }` | - | No | | | width | `number` | - | No | | > **Note**: The `ref` is forwarded to the root element (SVGSVGElement). > Any other props supplied will be provided to the root element (native element). ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | baseButton | `undefined` | - | | | baseIconButton | `undefined` | - | | | legend | `ChartsLegend` | - | Custom rendering of the legend. | | loadingOverlay | `ChartsLoadingOverlay` | - | Overlay component rendered when the chart is in a loading state. | | noDataOverlay | `ChartsNoDataOverlay` | - | Overlay component rendered when the chart has no data to display. | | pieArc | `undefined` | - | | | pieArcLabel | `undefined` | - | | | toolbar | `ChartsToolbar` | - | Custom component for the toolbar. | | tooltip | `ChartsTooltipRoot` | - | Custom component for the tooltip popper. | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/PieChart/PieChart.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/PieChart/PieChart.tsx) --- # Source: https://mui.com/x/react-charts/pie-demo.md --- title: Charts - Pie demos productId: x-charts components: PieArc, PieArcLabel, PieArcLabelPlot, PieArcPlot, PieChart, PiePlot --- # Charts - Pie demos This page groups demos using pie charts. ## TwoLevelPieChart ```tsx import { PieChart } from '@mui/x-charts/PieChart'; import Box from '@mui/material/Box'; const data1 = [ { label: 'Group A', value: 400 }, { label: 'Group B', value: 300 }, { label: 'Group C', value: 300 }, { label: 'Group D', value: 200 }, ]; const data2 = [ { label: 'A1', value: 100 }, { label: 'A2', value: 300 }, { label: 'B1', value: 100 }, { label: 'B2', value: 80 }, { label: 'B3', value: 40 }, { label: 'B4', value: 30 }, { label: 'B5', value: 50 }, { label: 'C1', value: 100 }, { label: 'C2', value: 200 }, { label: 'D1', value: 150 }, { label: 'D2', value: 50 }, ]; export default function TwoLevelPieChart() { return ( ); } ``` ## StraightAnglePieChart ```tsx import { PieChart } from '@mui/x-charts/PieChart'; const data = [ { label: 'Group A', value: 400 }, { label: 'Group B', value: 300 }, { label: 'Group C', value: 300 }, { label: 'Group D', value: 200 }, { label: 'Group E', value: 278 }, { label: 'Group F', value: 189 }, ]; export default function StraightAnglePieChart() { return ( ); } ``` ## PieChartWithCustomizedLabel ```tsx import { DefaultizedPieValueType } from '@mui/x-charts/models'; import { PieChart, pieArcLabelClasses } from '@mui/x-charts/PieChart'; const data = [ { label: 'Group A', value: 400, color: '#0088FE' }, { label: 'Group B', value: 300, color: '#00C49F' }, { label: 'Group C', value: 300, color: '#FFBB28' }, { label: 'Group D', value: 200, color: '#FF8042' }, ]; const sizing = { margin: { right: 5 }, width: 200, height: 200, hideLegend: true, }; const TOTAL = data.map((item) => item.value).reduce((a, b) => a + b, 0); const getArcLabel = (params: DefaultizedPieValueType) => { const percent = params.value / TOTAL; return `${(percent * 100).toFixed(0)}%`; }; export default function PieChartWithCustomizedLabel() { return ( ); } ``` ## PieChartWithPaddingAngle ```tsx import Stack from '@mui/material/Stack'; import { PieChart } from '@mui/x-charts/PieChart'; const data = [ { label: 'Group A', value: 400 }, { label: 'Group B', value: 300 }, { label: 'Group C', value: 300 }, { label: 'Group D', value: 200 }, ]; export default function PieChartWithPaddingAngle() { return ( ); } ``` ## PieChartWithCenterLabel ```tsx import * as React from 'react'; import { PieChart } from '@mui/x-charts/PieChart'; import { useDrawingArea } from '@mui/x-charts/hooks'; import { styled } from '@mui/material/styles'; const data = [ { value: 5, label: 'A' }, { value: 10, label: 'B' }, { value: 15, label: 'C' }, { value: 20, label: 'D' }, ]; const size = { width: 200, height: 200, }; const StyledText = styled('text')(({ theme }) => ({ fill: theme.palette.text.primary, textAnchor: 'middle', dominantBaseline: 'central', fontSize: 20, })); function PieCenterLabel({ children }: { children: React.ReactNode }) { const { width, height, left, top } = useDrawingArea(); return ( {children} ); } export default function PieChartWithCenterLabel() { return ( Center label ); } ``` ## Pie chart with custom mark in legend and tooltip ```tsx import { PieChart } from '@mui/x-charts/PieChart'; import { ChartsLabelCustomMarkProps } from '@mui/x-charts/ChartsLabel'; function HTMLDiamond({ className, color }: ChartsLabelCustomMarkProps) { return (
); } function SVGStar({ className, color }: ChartsLabelCustomMarkProps) { return ( ); } export default function PieChartWithCustomLegendAndTooltip() { return ( ); } ``` --- # Source: https://mui.com/x/api/charts/pie-plot.md # PiePlot API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - [Charts - Pie](/x/react-charts/pie/) - [Charts - Pie demos](/x/react-charts/pie-demo/) ## Import ```jsx import { PiePlot } from '@mui/x-charts/PieChart'; // or import { PiePlot } from '@mui/x-charts'; // or import { PiePlot } from '@mui/x-charts-pro'; // or import { PiePlot } from '@mui/x-charts-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | onItemClick | `function(event: React.MouseEvent, pieItemIdentifier: PieItemIdentifier, item: DefaultizedPieValueType) => void` | - | No | | | skipAnimation | `bool` | `false` | No | | | slotProps | `object` | `{}` | No | | | slots | `object` | `{}` | No | | > **Note**: The `ref` is forwarded to the root element. ## Slots | Name | Default | Class | Description | |------|---------|-------|-------------| | pieArc | `undefined` | - | | | pieArcLabel | `undefined` | - | | ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-charts/src/PieChart/PiePlot.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-charts/src/PieChart/PiePlot.tsx) --- # Source: https://mui.com/x/api/charts/pie-series.md # PieSeries API ## Import ```jsx import { PieSeries } from '@mui/x-charts-premium' // or import { PieSeries } from '@mui/x-charts-pro' // or import { PieSeries } from '@mui/x-charts' ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | data | `Readonly` | - | Yes | | | type | `'pie'` | - | Yes | | | arcLabel | `'formattedValue' \| 'label' \| 'value' \| ((item: Omit & { label?: string }) => string)` | - | No | | | arcLabelMinAngle | `number` | `0` | No | | | arcLabelRadius | `number \| string` | `(innerRadius - outerRadius) / 2` | No | | | color | `string` | - | No | | | colorGetter | `(data: ColorCallbackValue) => string` | - | No | | | cornerRadius | `number` | `0` | No | | | cx | `number \| string` | `'50%'` | No | | | cy | `number \| string` | `'50%'` | No | | | endAngle | `number` | `360` | No | | | faded | `{ /** * Value added to the default `outerRadius`. * Can be negative. It is ignored if you provide a `faded.outerRadius` value. */ additionalRadius?: number innerRadius?: number outerRadius?: number cornerRadius?: number paddingAngle?: number arcLabelRadius?: number color?: string }` | - | No | | | highlighted | `{ /** * Value added to the default `outerRadius`. * Can be negative. It is ignored if you provide a `highlighted.outerRadius` value. */ additionalRadius?: number innerRadius?: number outerRadius?: number cornerRadius?: number paddingAngle?: number arcLabelRadius?: number color?: string }` | - | No | | | highlightScope | `HighlightScope` | - | No | | | id | `SeriesId` | - | No | | | innerRadius | `number \| string` | `0` | No | | | labelMarkType | `ChartsLabelMarkType` | - | No | | | outerRadius | `number \| string` | `'100%'` | No | | | paddingAngle | `number` | `0` | No | | | sortingValues | `ChartsPieSorting` | `'none'` | No | | | startAngle | `number` | `0` | No | | | valueFormatter | `SeriesValueFormatter` | - | No | | > **Note**: The `ref` is forwarded to the root element. --- # Source: https://mui.com/x/react-charts/pie.md --- title: React Pie chart productId: x-charts components: PieArc, PieArcLabel, PieArcLabelPlot, PieArcPlot, PieChart, PiePlot, PieChartPro, ChartsWrapper --- # Charts - Pie Pie charts express portions of a whole, using arcs or angles within a circle. ## Overview Pie charts are ideal for showing proportions of a whole. They excel at visualizing how categories contribute to a total, making relative shares easy to compare at a glance. Here are the basic requirements to create a pie chart: - One categorical dimension (each category represented as a slice) - One numerical metric representing the value or size of each slice (converted into percentage of the whole) The pie chart below compares survival rates of passengers in different classes on the Titanic: ```tsx import * as React from 'react'; import { PieChart, pieArcLabelClasses } from '@mui/x-charts/PieChart'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import ToggleButton from '@mui/material/ToggleButton'; import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'; import { useDrawingArea } from '@mui/x-charts/hooks'; import { styled } from '@mui/material/styles'; import type { Theme } from '@mui/material/styles'; interface TitanicDatum { Class: '1st' | '2nd' | '3rd' | 'Crew'; Survived: 'Yes' | 'No'; Count: number; } interface ChartDatum { id: string; label: string; value: number; percentage: number; color: string; } type ClassType = '1st' | '2nd' | '3rd' | 'Crew'; // Convert hex color to rgba with opacity const hexToRgba = (hex: string, alpha: number): string => { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return `rgba(${r}, ${g}, ${b}, ${alpha})`; }; // https://en.wikipedia.org/wiki/Passengers_of_the_Titanic#/media/File:Titanic_casualties.svg const titanicData: TitanicDatum[] = [ { Class: '1st', Survived: 'No', Count: 123 }, { Class: '1st', Survived: 'Yes', Count: 202 }, { Class: '2nd', Survived: 'No', Count: 167 }, { Class: '2nd', Survived: 'Yes', Count: 118 }, { Class: '3rd', Survived: 'No', Count: 528 }, { Class: '3rd', Survived: 'Yes', Count: 178 }, { Class: 'Crew', Survived: 'No', Count: 696 }, { Class: 'Crew', Survived: 'Yes', Count: 212 }, ]; const classes: ClassType[] = ['1st', '2nd', '3rd', 'Crew']; const totalCount = titanicData.reduce( (acc: number, item: TitanicDatum) => acc + item.Count, 0, ); // Define colors for each class const classColors: Record = { '1st': '#fa938e', '2nd': '#98bf45', '3rd': '#51cbcf', Crew: '#d397ff', }; // Different opacity based on class const opacityMap: Record = { '1st': 0.9, '2nd': 0.7, '3rd': 0.5, Crew: 0.3, }; const classData: ChartDatum[] = classes.map((pClass: ClassType) => { const classTotal = titanicData .filter((item: TitanicDatum) => item.Class === pClass) .reduce((acc: number, item: TitanicDatum) => acc + item.Count, 0); return { id: pClass, label: `${pClass} Class:`, value: classTotal, percentage: (classTotal / totalCount) * 100, color: classColors[pClass], }; }); const classSurvivalData: ChartDatum[] = classes.flatMap((pClass: ClassType) => { const classTotal = classData.find((d: ChartDatum) => d.id === pClass)!.value ?? 0; const baseColor = classColors[pClass]; return titanicData .filter((item: TitanicDatum) => item.Class === pClass) .sort((a: TitanicDatum, b: TitanicDatum) => (a.Survived > b.Survived ? 1 : -1)) .map((item: TitanicDatum) => ({ id: `${pClass}-${item.Survived}`, label: item.Survived, value: item.Count, percentage: (item.Count / classTotal) * 100, color: item.Survived === 'Yes' ? baseColor : `${baseColor}80`, // 80 is 50% opacity for 'No' })); }); // Create a simplified dataset that groups all classes together for Yes/No const survivalData: ChartDatum[] = [ { id: 'Yes', label: 'Survived:', value: titanicData .filter((item: TitanicDatum) => item.Survived === 'Yes') .reduce((sum: number, item: TitanicDatum) => sum + item.Count, 0), percentage: (titanicData .filter((item: TitanicDatum) => item.Survived === 'Yes') .reduce((sum: number, item: TitanicDatum) => sum + item.Count, 0) / totalCount) * 100, color: classColors['3rd'], }, { id: 'No', label: 'Did not survive:', value: titanicData .filter((item: TitanicDatum) => item.Survived === 'No') .reduce((sum: number, item: TitanicDatum) => sum + item.Count, 0), percentage: (titanicData .filter((item: TitanicDatum) => item.Survived === 'No') .reduce((sum: number, item: TitanicDatum) => sum + item.Count, 0) / totalCount) * 100, color: classColors['1st'], }, ]; // Create dataset for class distribution by survival status (Yes first, then No) const survivalClassData: ChartDatum[] = [...titanicData] .sort((a: TitanicDatum) => (a.Survived === 'Yes' ? -1 : 1)) .map((item: TitanicDatum) => { const baseColor = survivalData.find( (d: ChartDatum) => d.id === item.Survived, )!.color; return { id: `${item.Class}-${item.Survived}`, label: `${item.Class} class:`, value: item.Count, percentage: (item.Count / (item.Survived === 'Yes' ? survivalData[0]!.value : survivalData[1]!.value)) * 100, color: hexToRgba(baseColor, opacityMap[item.Class] || 1), }; }); const StyledText = styled('text')(({ theme }: { theme: Theme }) => ({ fill: theme.palette.text.primary, textAnchor: 'middle', dominantBaseline: 'central', fontSize: 20, })); interface PieCenterLabelProps { children: React.ReactNode; } function PieCenterLabel({ children }: PieCenterLabelProps): React.ReactElement { const { width, height, left, top } = useDrawingArea(); return ( {children} ); } type ViewType = 'class' | 'survival'; export default function TitanicPie(): React.ReactElement { const [view, setView] = React.useState('class'); const handleViewChange = ( event: React.MouseEvent, newView: ViewType | null, ) => { if (newView !== null) { setView(newView); } }; const innerRadius = 50; const middleRadius = 120; return ( Titanic survival statistics View by Class View by Survival {view === 'class' ? ( `${item.id} (${(item as any).percentage.toFixed(0)}%)`, valueFormatter: ({ value }) => `${value} out of ${totalCount} (${((value / totalCount) * 100).toFixed(0)}%)`, highlightScope: { fade: 'global', highlight: 'item' }, highlighted: { additionalRadius: 2 }, cornerRadius: 3, }, { innerRadius: middleRadius, outerRadius: middleRadius + 20, data: classSurvivalData, arcLabel: (item) => `${item.label} (${(item as any).percentage.toFixed(0)}%)`, valueFormatter: ({ value }) => `${value} out of ${totalCount} (${((value / totalCount) * 100).toFixed(0)}%)`, arcLabelRadius: 160, highlightScope: { fade: 'global', highlight: 'item' }, highlighted: { additionalRadius: 2 }, cornerRadius: 3, }, ]} sx={{ [`& .${pieArcLabelClasses.root}`]: { fontSize: '12px', }, }} hideLegend > Class ) : ( `${item.id} (${(item as any).percentage.toFixed(0)}%)`, valueFormatter: ({ value }) => `${value} out of ${totalCount} (${((value / totalCount) * 100).toFixed(0)}%)`, highlightScope: { fade: 'global', highlight: 'item' }, highlighted: { additionalRadius: 2 }, cornerRadius: 3, }, { innerRadius: middleRadius, outerRadius: middleRadius + 20, data: survivalClassData, arcLabel: (item) => { const id = (item as any).id || ''; const percentage = (item as any).percentage || 0; return `${id.split('-')[0]} (${percentage.toFixed(0)}%)`; }, arcLabelRadius: 160, valueFormatter: ({ value }) => `${value} out of ${totalCount} (${((value / totalCount) * 100).toFixed(0)}%)`, highlightScope: { fade: 'global', highlight: 'item' }, highlighted: { additionalRadius: 2 }, cornerRadius: 3, }, ]} sx={{ [`& .${pieArcLabelClasses.root}`]: { fontSize: '12px', }, }} hideLegend > Survived )} ); } ``` ## Basics Pie charts series must contain a `data` property containing an array of objects. Each object corresponds to a slice of the pie. It must contain a property `value` and can have other optional properties like `label`. If you plan to update/reorder those data, you should add an `id` property which is used for `key` props. ```tsx import { PieChart } from '@mui/x-charts/PieChart'; export default function BasicPie() { return ( ); } ``` ## Donut chart A donut chart (or doughnut chart) is essentially a pie chart with a hollow center. You can transform any pie chart into a donut chart by setting the `innerRadius` property to a value greater than 0. ```tsx import { PieChart } from '@mui/x-charts/PieChart'; const data = [ { label: 'Group A', value: 400, color: '#0088FE' }, { label: 'Group B', value: 300, color: '#00C49F' }, { label: 'Group C', value: 300, color: '#FFBB28' }, { label: 'Group D', value: 200, color: '#FF8042' }, ]; const settings = { margin: { right: 5 }, width: 200, height: 200, hideLegend: true, }; export default function DonutChart() { return ( ); } ``` ## Colors The pie colors can be customized in two ways. 1. You can provide a [color palette](/x/react-charts/styling/#color-palette). Each arc of the pie will be colored according to this palette. 2. You can provide a `color` property in `data` objects which overrides the palette. ```jsx ``` ```tsx import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { PieChart } from '@mui/x-charts/PieChart'; import { platforms } from './webUsageStats'; const palette = ['lightcoral', 'slateblue']; const colorPerItem = [ { ...platforms[0], color: 'orange' }, { ...platforms[1], color: 'gray' }, ]; export default function PieColor() { return ( Default Palette Item ); } const pieParams = { height: 200, margin: { right: 5 }, hideLegend: true, }; ``` ## Sizing Pie series shape is described by multiple properties: - `innerRadius` The radius between the center and the beginning of the arc. The default is set to 0. - `outerRadius` The radius between the center and the end of the arc. The default is the largest value available in the drawing area. - `arcLabelRadius` The radius between the center and the arc label. - `paddingAngle` The angle (in degrees) between two arcs. - `cornerRadius` Similar to the CSS `border-radius`. - `startAngle`/`endAngle` The angle range of the pie chart. Values are given in degrees. - `cx`/`cy` The center of the pie charts. By default the middle of the drawing area. ```tsx import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo'; import { PieChart } from '@mui/x-charts/PieChart'; import { desktopOS, valueFormatter } from './webUsageStats'; export default function PieShape() { return ( ( )} getCode={({ props }) => { return `import { PieChart } from '@mui/x-charts/PieChart'; `; }} /> ); } ``` The following properties accept percentage string (for example `'50%'`). - `innerRadius`/`outerRadius`/`arcLabelRadius` with `'100%'` equivalent to maximal radius fitting in the drawing area. - `cx`, `cy` with `'100%'` equivalent to the drawing area width/height. ## Labels You can display labels on the arcs. To do so, the series should get `arcLabel` property. It can either get a function that gets the object associated with the arc and returns the label. Or you can pass one of the following values: - `'value'` display the raw value of the arc. - `'formattedValue'` display the returned value of `valueFormatter` for the arc. - `'label'` display the `label` property of the arc if provided. To avoid displaying labels on small arcs, you can provide `arcLabelMinAngle` property. Arcs with angles smaller than the value (in deg) will not have labels. ```tsx import { PieChart, pieArcLabelClasses } from '@mui/x-charts/PieChart'; import { desktopOS, valueFormatter } from './webUsageStats'; export default function PieArcLabel() { return ( `${item.value}%`, arcLabelMinAngle: 35, arcLabelRadius: '60%', ...data, }, ]} sx={{ [`& .${pieArcLabelClasses.root}`]: { fontWeight: 'bold', }, }} {...size} /> ); } const size = { width: 200, height: 200, }; const data = { data: desktopOS, valueFormatter, }; ``` ## Highlight Pie series can get `highlightScope` property to manage element highlighting. Its behavior is described in the [dedicated page](/x/react-charts/highlighting/#highlighting-series). When elements are highlighted or faded they can be customized with dedicated CSS classes: `.MuiPieArc-faded` and `.MuiPieArc-highlighted`. CSS is well suited to modify the `color`, `stroke-width`, or `opacity`. However, to modify the size of a pie arc, you must use the `highlighted` and `faded` properties, with which you can override any of the properties `innerRadius`, `outerRadius`, and `cornerRadius` when an arc is highlighted or faded. If you do not want to provide absolute values, you can use `additionalRadius` which will be added to the `outerRadius`. This value can be negative to reduce arc size. ```tsx import { PieChart } from '@mui/x-charts/PieChart'; import { desktopOS, valueFormatter } from './webUsageStats'; export default function PieActiveArc() { return ( ); } ``` ## Click event Pie Chart provides an `onItemClick` handler for handling clicks on specific pie arcs. It has the following signature. ```js const onItemClick = ( event, // The mouse event. params, // An object that identifies the clicked element. ) => {}; ``` ```tsx import * as React from 'react'; import Stack from '@mui/material/Stack'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import IconButton from '@mui/material/IconButton'; import UndoOutlinedIcon from '@mui/icons-material/UndoOutlined'; import { PieChart } from '@mui/x-charts/PieChart'; import { HighlightedCode } from '@mui/docs/HighlightedCode'; import { PieItemIdentifier } from '@mui/x-charts/models'; import { mobileAndDesktopOS, platforms, valueFormatter } from './webUsageStats'; export default function PieClick() { const [itemData, setItemData] = React.useState(); return ( setItemData(d)} />{' '} Click on the chart setItemData(undefined)} > ); } const series = [ { innerRadius: 0, outerRadius: 80, id: 'platform-series', data: platforms, valueFormatter, }, { innerRadius: 100, outerRadius: 120, id: 'OS-series', data: mobileAndDesktopOS, valueFormatter, }, ]; ``` ## CSS You can customize the different elements rendered by a pie chart using CSS. In the example below, the outer series is selected using the `data-series` attribute to reduce its opacity. ```tsx import { pieArcClasses, PieChart, PieChartProps, pieClasses, } from '@mui/x-charts/PieChart'; import { rainbowSurgePalette } from '@mui/x-charts/colorPalettes'; import { useTheme } from '@mui/material/styles'; export default function PieCSSStyling() { const theme = useTheme(); const palette = rainbowSurgePalette(theme.palette.mode); const data1 = [ { label: 'Group A', value: 400 }, { label: 'Group B', value: 300 }, { label: 'Group C', value: 300 }, { label: 'Group D', value: 200 }, ]; const data2 = [ { label: 'A1', value: 100, color: palette[0] }, { label: 'A2', value: 300, color: palette[0] }, { label: 'B1', value: 100, color: palette[1] }, { label: 'B2', value: 80, color: palette[1] }, { label: 'B3', value: 40, color: palette[1] }, { label: 'B4', value: 30, color: palette[1] }, { label: 'B5', value: 50, color: palette[1] }, { label: 'C1', value: 100, color: palette[2] }, { label: 'C2', value: 200, color: palette[2] }, { label: 'D1', value: 150, color: palette[3] }, { label: 'D2', value: 50, color: palette[3] }, ]; const settings = { series: [ { innerRadius: 0, outerRadius: 80, data: data1, highlightScope: { fade: 'global', highlight: 'item' }, }, { id: 'outer', innerRadius: 100, outerRadius: 120, data: data2, highlightScope: { fade: 'global', highlight: 'item' }, }, ], height: 300, hideLegend: true, } satisfies PieChartProps; return ( ); } ``` ## 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 `skipAnimation` is enabled, the chart renders without any animations. ```jsx // For a single component chart // For a composed chart ``` ```tsx import * as React from 'react'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; import Slider from '@mui/material/Slider'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; import { PieChart } from '@mui/x-charts/PieChart'; import { mobileAndDesktopOS, valueFormatter } from './webUsageStats'; export default function PieAnimation() { const [radius, setRadius] = React.useState(50); const [itemNb, setItemNb] = React.useState(5); const [skipAnimation, setSkipAnimation] = React.useState(false); const handleItemNbChange = (event: Event, newValue: number | number[]) => { if (typeof newValue !== 'number') { return; } setItemNb(newValue); }; const handleRadius = (event: Event, newValue: number | number[]) => { if (typeof newValue !== 'number') { return; } setRadius(newValue); }; return ( params.label ?? '', arcLabelMinAngle: 20, valueFormatter, }, ]} skipAnimation={skipAnimation} /> setSkipAnimation(event.target.checked)} /> } label="skipAnimation" labelPlacement="end" /> Number of items Radius ); } ``` ## Composition Use the `` to provide the `series` prop for composition. In addition to the common chart components available for [composition](/x/react-charts/composition/), you can use the `` component that renders the pie slices and their labels. Here's how the Pie Chart is composed: ```jsx ``` :::info The `` accepts a [`plugins`](/x/react-charts/plugins/) prop. This is done to remove cartesian-axis features which are useless for a pie chart, and interfere with the pie position. For pro users, use the `PIE_CHART_PRO_PLUGINS` instead to activate the export feature. ::: --- # Source: https://mui.com/x/api/data-grid/pivot-panel-trigger.md # PivotPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - Pivot Panel component 🚧 ## Import ```jsx import { PivotPanelTrigger } from '@mui/x-data-grid-premium/components'; // or import { PivotPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/pivotPanel/PivotPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/pivotPanel/PivotPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/components/pivot-panel.md --- title: Data Grid - Pivot Panel component productId: x-data-grid components: PivotPanelTrigger packageName: '@mui/x-data-grid-premium' githubLabel: 'scope: data grid' --- # Data Grid - Pivot Panel component [](/x/introduction/licensing/#premium-plan 'Premium plan') 🚧 Customize the Data Grid's pivot panel. :::warning This component is incomplete. Currently, the Pivot Panel Trigger is the only part of the Pivot Panel component available. Future versions of the Pivot Panel component will make it possible to compose each of its parts to create a custom pivot panel. ::: The pivot panel is part of the [pivoting feature](/x/react-data-grid/pivoting/) and is enabled by default when `showToolbar` is passed to the `` component. You can use the Pivot Panel Trigger and [Toolbar](/x/react-data-grid/components/toolbar/) components when you need to customize the pivot panel trigger, or when implementing a custom toolbar. ## Basic usage The demo below shows how to add a pivot panel trigger to a custom toolbar. ```tsx import { DataGridPremium, Toolbar, ToolbarButton, PivotPanelTrigger, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; import Tooltip from '@mui/material/Tooltip'; import PivotTableChartIcon from '@mui/icons-material/PivotTableChart'; function CustomToolbar() { return ( ( )} > ); } export default function GridPivotPanelTrigger() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 10, maxColumns: 10, }); return (
); } ``` ## Anatomy ```tsx import { PivotPanelTrigger } from '@mui/x-data-grid-premium'; ; ``` ### Pivot Panel Trigger `` is a button that opens and closes the pivot panel. It renders the `baseButton` slot. ## Custom elements Use the `render` prop to replace default elements. See [Components usage—Customization](/x/react-data-grid/components/usage/#customization) for more details. ## Accessibility ### ARIA You must apply a text label or an `aria-label` attribute to the ``. # PivotPanelTrigger API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - Pivot Panel component 🚧 ## Import ```jsx import { PivotPanelTrigger } from '@mui/x-data-grid-premium/components'; // or import { PivotPanelTrigger } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/pivotPanel/PivotPanelTrigger.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/pivotPanel/PivotPanelTrigger.tsx) --- # Source: https://mui.com/x/react-data-grid/server-side-data/pivoting.md # Source: https://mui.com/x/react-data-grid/pivoting.md --- title: Data Grid - Pivoting --- # Data Grid - Pivoting [](/x/introduction/licensing/#premium-plan 'Premium plan') Rearrange rows and columns to view data from multiple perspectives. The Data Grid Premium's pivoting feature lets users transform the data in their grid by reorganizing rows and columns, creating dynamic cross-tabulations of data. This makes it possible to analyze data from different angles and gain insights that would be difficult to see in the default grid view. If you're new to the concept of pivoting, check out the [Understanding pivoting](/x/react-data-grid/pivoting-explained/) page to learn how it works through interactive examples. :::warning Pivoting performs certain computations and uses them to override corresponding props. When pivot mode is active, the following props are ignored: `rows`, `columns`, `rowGroupingModel`, `aggregationModel`, `getAggregationPosition`, `columnVisibilityModel`, `columnGroupingModel`, `groupingColDef`, `headerFilters`, `disableRowGrouping`, and `disableAggregation`. ::: :::info This document covers client-side pivoting. For pivoting on the server side, see [Server-side pivoting](/x/react-data-grid/server-side-data/pivoting/). ::: ## Quick start Pivoting is enabled by default and can be accessed through the icon in the toolbar. In the demo below, the pivot panel is already open and some pivoting parameters have been set. Use the **Pivot** switch at the top of the panel to toggle pivoting off and on. You can drag and drop existing columns in the **Rows**, **Columns**, and **Values** dropdown menus to change how the data is pivoted. ```tsx import { DataGridPremium, GridColDef, GridRowModel, GridPivotModel, GridInitialState, GridSidebarValue, } from '@mui/x-data-grid-premium'; const rows: GridRowModel[] = [ { id: 1, product: 'Apples', region: 'North', quarter: 'Q1', sales: 1000, profit: 100, size: 'L', }, { id: 2, product: 'Apples', region: 'South', quarter: 'Q1', sales: 1200, profit: 120, size: 'M', }, { id: 3, product: 'Oranges', region: 'North', quarter: 'Q1', sales: 800, profit: 80, size: 'M', }, { id: 4, product: 'Oranges', region: 'South', quarter: 'Q1', sales: 900, profit: 90, size: 'S', }, { id: 5, product: 'Apples', region: 'North', quarter: 'Q2', sales: 1100, profit: 110, size: 'L', }, { id: 6, product: 'Apples', region: 'South', quarter: 'Q2', sales: 1300, profit: 130, size: 'L', }, { id: 7, product: 'Oranges', region: 'North', quarter: 'Q2', sales: 850, profit: 85, size: 'M', }, { id: 8, product: 'Oranges', region: 'South', quarter: 'Q2', sales: 950, profit: 95, size: 'S', }, ]; const columns: GridColDef[] = [ { field: 'product', headerName: 'Product' }, { field: 'region', headerName: 'Region' }, { field: 'quarter', headerName: 'Quarter' }, { field: 'sales', headerName: 'Sales', type: 'number', valueFormatter: (value) => { if (!value) { return ''; } return currencyFormatter.format(value); }, }, { field: 'profit', headerName: 'Profit', type: 'number', valueFormatter: (value) => { if (!value) { return ''; } return `${value}%`; }, }, { field: 'size', headerName: 'Size', }, ]; const pivotModel: GridPivotModel = { rows: [{ field: 'product' }, { field: 'size' }], columns: [{ field: 'region' }, { field: 'quarter' }], values: [ { field: 'sales', aggFunc: 'sum' }, { field: 'profit', aggFunc: 'avg' }, ], }; const initialState: GridInitialState = { pivoting: { enabled: true, model: pivotModel, }, sidebar: { open: true, value: GridSidebarValue.Pivot, }, }; export default function GridPivotingQuickStart() { return (
); } const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); ``` ## Pivot model The pivot model is a configuration object that defines rows, columns, and values of the pivot Grid: ```tsx interface GridPivotModel { rows: Array<{ field: string; hidden?: boolean; }>; columns: Array<{ field: string; sort?: 'asc' | 'desc'; hidden?: boolean; }>; values: Array<{ field: string; aggFunc: string; hidden?: boolean; }>; } ``` ## Initialize pivoting Use the `initialState` prop to initialize uncontrolled pivoting. This is the recommended method unless you specifically need to control the state. You can initialize the pivot model, toggle pivot panel visibility, and toggle the pivot mode as shown below: ```tsx ``` ```tsx import { DataGridPremium, GridColDef, GridRowModel, GridPivotModel, GridInitialState, GridSidebarValue, } from '@mui/x-data-grid-premium'; const rows: GridRowModel[] = [ { id: 1, product: 'Apples', region: 'North', quarter: 'Q1', sales: 1000 }, { id: 2, product: 'Apples', region: 'South', quarter: 'Q1', sales: 1200 }, { id: 3, product: 'Oranges', region: 'North', quarter: 'Q1', sales: 800 }, { id: 4, product: 'Oranges', region: 'South', quarter: 'Q1', sales: 900 }, { id: 5, product: 'Apples', region: 'North', quarter: 'Q2', sales: 1100 }, { id: 6, product: 'Apples', region: 'South', quarter: 'Q2', sales: 1300 }, { id: 7, product: 'Oranges', region: 'North', quarter: 'Q2', sales: 850 }, { id: 8, product: 'Oranges', region: 'South', quarter: 'Q2', sales: 950 }, ]; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const columns: GridColDef[] = [ { field: 'product', headerName: 'Product' }, { field: 'region', headerName: 'Region' }, { field: 'quarter', headerName: 'Quarter' }, { field: 'sales', headerName: 'Sales', type: 'number', valueFormatter: (value) => { if (!value) { return ''; } return currencyFormatter.format(value); }, }, ]; const pivotModel: GridPivotModel = { rows: [{ field: 'product' }], columns: [{ field: 'region' }, { field: 'quarter', sort: 'asc' }], values: [{ field: 'sales', aggFunc: 'sum' }], }; const initialState: GridInitialState = { pivoting: { model: pivotModel, enabled: true, }, sidebar: { open: true, value: GridSidebarValue.Pivot, }, }; export default function GridPivotingInitialState() { return (
); } ``` ## Controlled pivoting For fully controlled pivoting state, you can use the following props: - Pivot model: - `pivotModel`: Controls the current pivot configuration. - `onPivotModelChange`: Callback fired when the pivot model changes. - Pivot mode toggle: - `pivotActive`: Controls whether pivot mode is active. - `onPivotActiveChange`: Callback fired when the pivot mode changes between active and inactive. - Pivot panel: - `pivotPanelOpen`: Controls whether the pivot panel is open. - `onPivotPanelOpenChange`: Callback fired when the pivot panel is opened or closed. ```tsx import * as React from 'react'; import { DataGridPremium, GridColDef, GridRowModel, GridPivotModel, GridSidebarValue, } from '@mui/x-data-grid-premium'; const rows: GridRowModel[] = [ { id: 1, product: 'Apples', region: 'North', quarter: 'Q1', sales: 1000 }, { id: 2, product: 'Apples', region: 'South', quarter: 'Q1', sales: 1200 }, { id: 3, product: 'Oranges', region: 'North', quarter: 'Q1', sales: 800 }, { id: 4, product: 'Oranges', region: 'South', quarter: 'Q1', sales: 900 }, { id: 5, product: 'Apples', region: 'North', quarter: 'Q2', sales: 1100 }, { id: 6, product: 'Apples', region: 'South', quarter: 'Q2', sales: 1300 }, { id: 7, product: 'Oranges', region: 'North', quarter: 'Q2', sales: 850 }, { id: 8, product: 'Oranges', region: 'South', quarter: 'Q2', sales: 950 }, ]; const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); const columns: GridColDef[] = [ { field: 'product', headerName: 'Product' }, { field: 'region', headerName: 'Region' }, { field: 'quarter', headerName: 'Quarter' }, { field: 'sales', headerName: 'Sales', type: 'number', valueFormatter: (value) => { if (!value) { return ''; } return currencyFormatter.format(value); }, }, ]; export default function GridPivotingControlled() { // Pivot model state const [pivotModel, setPivotModel] = React.useState({ rows: [{ field: 'product' }], columns: [{ field: 'region' }, { field: 'quarter', sort: 'asc' }], values: [{ field: 'sales', aggFunc: 'sum' }], }); // Pivot mode toggle state const [pivotModeEnabled, setPivotModeEnabled] = React.useState(true); return (
); } ``` ## Using fields in the pivot model multiple times While this is not supported yet, we are working to bring this feature to the Data Grid. Subscribe to [this issue](https://github.com/mui/mui-x/issues/17302) to get notified when it's available. ## Disable pivoting To disable pivoting feature completely, set the `disablePivoting` prop to `true`: ```tsx ``` ### Disable pivoting for specific columns To exclude specific column from pivoting, set the `pivotable: false` on its [column definition](/x/api/data-grid/grid-col-def/#grid-col-def-prop-pivotable): ```tsx const columns: GridColDef[] = [{ field: 'id', pivotable: false }]; ; ``` ```tsx import { DataGridPremium, GridColDef, GridRowModel, GridPivotModel, GridInitialState, GridSidebarValue, } from '@mui/x-data-grid-premium'; const rows: GridRowModel[] = [ { id: 1, product: 'Apples', region: 'North', quarter: 'Q1', sales: 1000 }, { id: 2, product: 'Apples', region: 'South', quarter: 'Q1', sales: 1200 }, { id: 3, product: 'Oranges', region: 'North', quarter: 'Q1', sales: 800 }, { id: 4, product: 'Oranges', region: 'South', quarter: 'Q1', sales: 900 }, { id: 5, product: 'Apples', region: 'North', quarter: 'Q2', sales: 1100 }, { id: 6, product: 'Apples', region: 'South', quarter: 'Q2', sales: 1300 }, { id: 7, product: 'Oranges', region: 'North', quarter: 'Q2', sales: 850 }, { id: 8, product: 'Oranges', region: 'South', quarter: 'Q2', sales: 950 }, ]; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', pivotable: false }, { field: 'product', headerName: 'Product' }, { field: 'region', headerName: 'Region' }, { field: 'quarter', headerName: 'Quarter' }, { field: 'sales', headerName: 'Sales', type: 'number', valueFormatter: (value) => { if (!value) { return ''; } return currencyFormatter.format(value); }, }, ]; const pivotModel: GridPivotModel = { rows: [{ field: 'product' }], columns: [{ field: 'region' }, { field: 'quarter', sort: 'asc' }], values: [{ field: 'sales', aggFunc: 'sum' }], }; const initialState: GridInitialState = { pivoting: { model: pivotModel, enabled: true, }, sidebar: { open: true, value: GridSidebarValue.Pivot, }, }; export default function GridNonPivotableColumns() { return (
); } const currencyFormatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0, }); ``` ## Derived columns in pivot mode In pivot mode, it's often useful to group data by a year or quarter. The Data Grid automatically generates year and quarter columns for each **Date** column for this purpose. :::success Use [pivotingColDef()](/x/api/data-grid/data-grid-premium/#data-grid-premium-prop-pivotingColDef) to customize derived columns definition. ::: For example, the sales dataset used throughout the examples has a **Quarter** column. But in a real-world dataset, each sales record would typically have a precise **Transaction Date** field, as in the following demo. The **Transaction Date** column is represented by additional columns in pivot mode: **Transaction Date (Year)** and **Transaction Date (Quarter)**: ```tsx import { DataGridPremium, GridColDef, GridPivotModel, GridSidebarValue, } from '@mui/x-data-grid-premium'; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 90 }, { field: 'transactionDate', type: 'date', headerName: 'Transaction Date', width: 140, valueGetter: (value) => (value ? new Date(value) : null), }, { field: 'ticker', headerName: 'Ticker' }, { field: 'price', type: 'number', headerName: 'Price', valueFormatter: (value: number | undefined) => value ? `$${value.toFixed(2)}` : null, }, { field: 'volume', type: 'number', headerName: 'Volume' }, { field: 'type', type: 'singleSelect', valueOptions: ['stock', 'bond'], headerName: 'Type', }, ]; const getYearField = (field: string) => `${field}-year`; const getQuarterField = (field: string) => `${field}-quarter`; const pivotModel: GridPivotModel = { rows: [{ field: 'ticker' }], columns: [ { field: getYearField('transactionDate'), sort: 'asc' }, { field: getQuarterField('transactionDate'), sort: 'asc' }, ], values: [ { field: 'price', aggFunc: 'avg' }, { field: 'volume', aggFunc: 'sum' }, ], }; export default function GridPivotingFinancial() { return (
); } const rows = [ { id: 1, transactionDate: '2024-05-15', ticker: 'AAPL', price: 192.45, volume: 5500, type: 'stock', }, { id: 2, transactionDate: '2024-03-16', ticker: 'GOOGL', price: 125.67, volume: 3200, type: 'stock', }, { id: 3, transactionDate: '2024-01-17', ticker: 'MSFT', price: 345.22, volume: 4100, type: 'stock', }, { id: 4, transactionDate: '2023-12-18', ticker: 'AAPL', price: 193.1, volume: 6700, type: 'stock', }, { id: 5, transactionDate: '2024-11-19', ticker: 'AMZN', price: 145.33, volume: 2900, type: 'stock', }, { id: 6, transactionDate: '2024-03-20', ticker: 'GOOGL', price: 126.45, volume: 3600, type: 'stock', }, { id: 7, transactionDate: '2024-08-21', ticker: 'US_TREASURY_2Y', price: 98.75, volume: 1000, type: 'bond', }, { id: 8, transactionDate: '2024-05-22', ticker: 'MSFT', price: 347.89, volume: 4500, type: 'stock', }, { id: 9, transactionDate: '2024-04-23', ticker: 'US_TREASURY_10Y', price: 95.6, volume: 750, type: 'bond', }, { id: 10, transactionDate: '2024-03-24', ticker: 'AMZN', price: 146.22, volume: 3100, type: 'stock', }, ]; ``` ### Custom derived columns Use the `getPivotDerivedColumns()` prop to customize derived columns. This prop is called for each original column and returns an array of derived columns, or `undefined` if no derived columns are needed. :::success To sort the derived columns by a value different than the column header name—for instance, to display months of the year—define both `valueGetter()` and `valueFormatter()` for the derived column. ::: ```tsx import { DataGridPremium, DataGridPremiumProps, GridColDef, GridPivotModel, GridSidebarValue, } from '@mui/x-data-grid-premium'; const getPivotDerivedColumns: DataGridPremiumProps['getPivotDerivedColumns'] = ( column, ) => { if (column.type === 'date') { const field = column.field; return [ { field: `${field}-year`, headerName: `${column.headerName} (Year)`, valueGetter: (_, row) => new Date(row[field]).getFullYear(), }, { field: `${field}-month`, headerName: `${column.headerName} (Month)`, type: 'number', valueGetter: (_, row) => new Date(row[field]).getMonth(), valueFormatter: (month) => new Date(0, month).toLocaleString(undefined, { month: 'long' }), }, ]; } return undefined; }; const getYearField = (field: string) => `${field}-year`; const getMonthField = (field: string) => `${field}-month`; const columns: GridColDef[] = [ { field: 'id', headerName: 'ID', width: 90 }, { field: 'transactionDate', type: 'date', headerName: 'Transaction Date', width: 140, valueGetter: (value) => (value ? new Date(value) : null), }, { field: 'ticker', headerName: 'Ticker' }, { field: 'price', type: 'number', headerName: 'Price', valueFormatter: (value: number | undefined) => value ? `$${value.toFixed(2)}` : null, }, { field: 'volume', type: 'number', headerName: 'Volume' }, { field: 'type', type: 'singleSelect', valueOptions: ['stock', 'bond'], headerName: 'Type', }, ]; const pivotModel: GridPivotModel = { rows: [{ field: 'ticker' }], columns: [ { field: getYearField('transactionDate'), sort: 'asc' }, { field: getMonthField('transactionDate'), sort: 'asc' }, ], values: [ { field: 'price', aggFunc: 'avg' }, { field: 'volume', aggFunc: 'sum' }, ], }; export default function GridGetPivotDerivedColumns() { return (
); } const rows = [ { id: 1, transactionDate: '2024-05-15', ticker: 'AAPL', price: 192.45, volume: 5500, type: 'stock', }, { id: 2, transactionDate: '2024-03-16', ticker: 'GOOGL', price: 125.67, volume: 3200, type: 'stock', }, { id: 3, transactionDate: '2024-01-17', ticker: 'MSFT', price: 345.22, volume: 4100, type: 'stock', }, { id: 4, transactionDate: '2023-12-18', ticker: 'AAPL', price: 193.1, volume: 6700, type: 'stock', }, { id: 5, transactionDate: '2024-11-19', ticker: 'AMZN', price: 145.33, volume: 2900, type: 'stock', }, { id: 6, transactionDate: '2024-03-20', ticker: 'GOOGL', price: 126.45, volume: 3600, type: 'stock', }, { id: 7, transactionDate: '2024-08-21', ticker: 'US_TREASURY_2Y', price: 98.75, volume: 1000, type: 'bond', }, { id: 8, transactionDate: '2024-05-22', ticker: 'MSFT', price: 347.89, volume: 4500, type: 'stock', }, { id: 9, transactionDate: '2024-04-23', ticker: 'US_TREASURY_10Y', price: 95.6, volume: 750, type: 'bond', }, { id: 10, transactionDate: '2024-03-24', ticker: 'AMZN', price: 146.22, volume: 3100, type: 'stock', }, ]; ``` ## Sticky column groups Depending on the pivot mode, some column groups might exceed the width of the Data Grid viewport. To improve the user experience, you can make these column groups "sticky" so that the column group labels remain visible while scrolling horizontally. You can use the `sx` prop to apply the necessary styles: ```tsx ``` ```tsx import * as React from 'react'; import { DataGridPremium, GridColDef, GridPivotModel, } from '@mui/x-data-grid-premium'; import { useMovieData } from '@mui/x-data-grid-generator'; const pivotModel: GridPivotModel = { rows: [{ field: 'company' }], columns: [ { field: 'year', sort: 'desc' }, { field: 'cinematicUniverse', sort: 'asc' }, { field: 'director', sort: 'asc' }, ], values: [ { field: 'gross', aggFunc: 'sum' }, { field: 'imdbRating', aggFunc: 'avg' }, ], }; export default function GridPivotingMovies() { const movieData = useMovieData(); const data = React.useMemo(() => { return { ...movieData, columns: [ ...movieData.columns.map((col) => ({ ...col, editable: true })), { field: 'imdbRating', headerName: 'Rating', type: 'number' }, ] as GridColDef[], }; }, [movieData]); return (
); } ``` ## Advanced demo The following demo showcases pivoting on a larger Commodities dataset with over 30 different columns to choose for pivoting parameters. ```tsx import * as React from 'react'; import { DataGridPremium, GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD, GridPivotModel, DataGridPremiumProps, GridInitialState, GridSidebarValue, } from '@mui/x-data-grid-premium'; import { useDemoData } from '@mui/x-data-grid-generator'; const pivotModel: GridPivotModel = { rows: [{ field: 'commodity' }], columns: [{ field: 'maturityDate-year', sort: 'asc' }, { field: 'status' }], values: [ { field: 'quantity', aggFunc: 'sum' }, { field: 'filledQuantity', aggFunc: 'avg' }, { field: 'totalPrice', aggFunc: 'avg' }, ], }; const initialState: GridInitialState = { pivoting: { model: pivotModel, }, sidebar: { open: true, value: GridSidebarValue.Pivot, }, pinnedColumns: { left: [GRID_ROW_GROUPING_SINGLE_GROUPING_FIELD], }, }; const pivotingColDef: DataGridPremiumProps['pivotingColDef'] = ( originalColumnField, ) => { if (originalColumnField === 'quantity') { return { width: 80 }; } return undefined; }; export default function GridPivotingCommodities() { const { data, loading } = useDemoData({ dataSet: 'Commodity', rowLength: 1_000, editable: true, }); const [pivotActive, setPivotActive] = React.useState(false); return (
); } ``` ## API - [DataGrid](/x/api/data-grid/data-grid/) - [DataGridPro](/x/api/data-grid/data-grid-pro/) - [DataGridPremium](/x/api/data-grid/data-grid-premium/) --- # Source: https://mui.com/x/react-date-pickers/playground.md --- productId: x-date-pickers title: Date and Time Pickers - Customization playground packageName: '@mui/x-date-pickers' githubLabel: 'scope: pickers' components: PickerDay2, DateRangePickerDay2 materialDesign: https://m2.material.io/components/date-pickers waiAria: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/ --- # Customization playground Use this playground to experiment with the props that affect the layout of the Date and Time Picker components. ```jsx import PickersPlayground from 'docsx/src/modules/components/PickersPlayground'; export default function PickersPlaygroundWrapper() { return ; } ``` --- # Source: https://mui.com/x/react-charts/plugins.md --- title: Charts - Plugins productId: x-charts components: ChartContainer, ChartDataProvider --- # Charts - Plugins The library relies on two systems to perform data processing: the plugins and the series config. :::warning This information is for advanced use-cases. Most charts should not require changes to either the plugins or the series configuration. ::: ## Plugins Plugins are functions that add features to the chart. They can process data, add internal state, or listen to events. Plugins can be passed to the `` or the `` with the `plugins` props. :::info Notice that `myChartPlugins` is defined outside of the component. That's because plugins contain hooks and so their order should not be modified. ::: ```jsx const myChartPlugins = [useChartInteraction, useChartHighlight]; function MyChart() { return {/* ... */}; } ``` ### Plugins per chart The default array of plugins can be imported from the corresponding chart folder. This allows you to get the exact same feature as the component while using composition. ```ts // Community package import { PIE_CHART_PLUGINS, PieChartPluginSignatures } from '@mui/x-charts/PieChart'; // Pro package import { PIE_CHART_PLUGINS, PieChartPluginSignatures } from '@mui/x-charts-pro/PieChart'; import { PIE_CHART_PRO_PLUGINS, PieChartProPluginSignatures } from '@mui/x-charts-pro/PieChartPro'; function MyPieChart() { return {/* ... */} } ``` ### Plugins list You can import plugins individually from `@mui/x-charts/plugins`. When creating your custom array of plugins, be aware that some plugins have dependencies. - dependencies: plugins that need to be set before for them to work. - optional dependencies: plugins that need to be set before to enable some features. For example, the `useChartClosestPoint` has the `useChartCartesianAxis` as a dependency and the `useChartHighlight` as an optional dependency. Then - `[useChartClosestPoint, useChartCartesianAxis]` does not work because the closest point plugin is before the cartesian one. - `[useChartCartesianAxis, useChartClosestPoint]` works because the cartesian plugin is set before the one for closest point. - `[useChartCartesianAxis, useChartClosestPoint, useChartHighlight]` works with limited feature. The highlight plugin being after the closest point one, you get the highlight feature, but not highlight based on closest point. | Plugin | Dependencies | Optional dependency | | :------------------------------------------------- | :---------------------- | :--------------------------------------------- | | `useChartCartesianAxis` | | `useChartInteraction` | | `useChartPolarAxis` | | `useChartInteraction` | | `useChartHighlight` | | | | `useChartTooltip` | | | | `useChartInteraction` | | `useChartTooltip` | | `useChartClosestPoint` | `useChartCartesianAxis` | `useChartInteraction`,
`useChartHighlight` | | `useChartZAxis` | | | | `useChartBrush` | | | | `useChartProExport` | | | | `useChartProZoom` | `useChartCartesianAxis` | | ### Custom plugins :::warning Creating custom plugins is not encouraged. ::: The plugin's internal implementation is not considered stable. It can break at any time, including patch and minor versions. --- # Source: https://mui.com/x/api/data-grid/prompt-field-control.md # PromptFieldControl API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - Prompt Field component ## Import ```jsx import { PromptFieldControl } from '@mui/x-data-grid-premium/components'; // or import { PromptFieldControl } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/promptField/PromptFieldControl.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/promptField/PromptFieldControl.tsx) --- # Source: https://mui.com/x/api/data-grid/prompt-field-record.md # PromptFieldRecord API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - Prompt Field component ## Import ```jsx import { PromptFieldRecord } from '@mui/x-data-grid-premium/components'; // or import { PromptFieldRecord } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/promptField/PromptFieldRecord.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/promptField/PromptFieldRecord.tsx) --- # Source: https://mui.com/x/api/data-grid/prompt-field-send.md # PromptFieldSend API ## Demos For examples and details on the usage of this React component, visit the component demo pages: - Data Grid - Prompt Field component ## Import ```jsx import { PromptFieldSend } from '@mui/x-data-grid-premium/components'; // or import { PromptFieldSend } from '@mui/x-data-grid-premium'; ``` ## Props | Name | Type | Default | Required | Description | |------|------|---------|----------|-------------| | className | `func \| string` | - | No | | | render | `element \| func` | - | No | | > **Note**: The `ref` is forwarded to the root element (GridRoot). ## Source code If you did not find the information on this page, consider having a look at the implementation of the component for more detail. - [/packages/x-data-grid-premium/src/components/promptField/PromptFieldSend.tsx](https://github.com/mui/material-ui/tree/HEAD/packages/x-data-grid-premium/src/components/promptField/PromptFieldSend.tsx) --- # Source: https://mui.com/x/api/data-grid/prompt-field.md # Source: https://mui.com/x/react-data-grid/components/prompt-field.md --- title: Data Grid - Prompt Field component productId: x-data-grid components: PromptField, PromptFieldRecord, PromptFieldControl, PromptFieldSend packageName: '@mui/x-data-grid-premium' githubLabel: 'scope: data grid' --- # Data Grid - Prompt Field component [](/x/introduction/licensing/#premium-plan 'Premium plan') Provide users with a prompt field to interact with the AI assistant. The prompt field is part of the [AI Assistant feature](/x/react-data-grid/ai-assistant/). You can use the Prompt Field component directly if you want to build your own UI for the AI Assistant. ## Basic usage The demo below shows how to add a prompt field to a custom toolbar. ```tsx import * as React from 'react'; import { DataGridPremium, Toolbar, PromptField, PromptFieldRecord, PromptFieldControl, PromptFieldSend, IS_SPEECH_RECOGNITION_SUPPORTED, useGridApiContext, } from '@mui/x-data-grid-premium'; import { styled } from '@mui/material/styles'; import { mockPromptResolver, useDemoData } from '@mui/x-data-grid-generator'; import InputAdornment from '@mui/material/InputAdornment'; import TextField from '@mui/material/TextField'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import MicIcon from '@mui/icons-material/Mic'; import MicOffIcon from '@mui/icons-material/MicOff'; import SendIcon from '@mui/icons-material/Send'; import Snackbar from '@mui/material/Snackbar'; import Alert from '@mui/material/Alert'; const StyledToolbar = styled(Toolbar)({ minHeight: 'auto', justifyContent: 'center', }); const SUCCESS_STATUS_TEXT = 'Prompt applied'; function CustomToolbar() { const apiRef = useGridApiContext(); const [statusText, setStatusText] = React.useState(null); const [snackbarOpen, setSnackbarOpen] = React.useState(false); const placeholder = IS_SPEECH_RECOGNITION_SUPPORTED ? 'Type or record a prompt…' : 'Type a prompt…'; const handlePromptSubmit = async (prompt: string) => { setStatusText(null); const response = await apiRef.current.aiAssistant.processPrompt(prompt); if (response instanceof Error) { setStatusText(response.message); setSnackbarOpen(true); } else { setStatusText(SUCCESS_STATUS_TEXT); setSnackbarOpen(true); } }; return ( ( } > ) : ( ), endAdornment: ( } > ), }, }} /> )} /> setSnackbarOpen(false)} anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} > {statusText} ); } export default function GridPromptField() { const { data, loading } = useDemoData({ dataSet: 'Employee', rowLength: 10, maxColumns: 10, }); return (
); } ``` ## Anatomy ```tsx import { PromptField, PromptFieldRecord, PromptFieldControl, PromptFieldSend, } from '@mui/x-data-grid-premium'; ; ``` ### Prompt Field `` is the top level component that provides context to child components. It renders a `
` element. ### Prompt Field Record `` is a button that records the user's voice when clicked. It renders the `baseIconButton` slot. ### Prompt Field Control `` is a component that takes user input. It renders the `baseTextField` slot. ### Prompt Field Send `` is a button that processes the prompt when clicked. It renders the `baseIconButton` slot. ## Custom elements Use the `render` prop to replace default elements. See [Components usage—Customization](/x/react-data-grid/components/usage/#customization) for more details. ## Accessibility ### ARIA - You must render a `