# Version v7.2.0

## Community templates

You are welcome to share your GitHub templates with the community. Community templates are
featured on the [getting started](https://mantine.dev/llms/getting-started.md) page. You can find a guide on how to
create and submit a template [here](https://help.mantine.dev/q/submit-template).

Examples of templates that you can submit:

* Next.js pages router + MDX + Mantine blog template
* Next.js app router + Mantine + styled-components template
* Vite + Mantine + Emotion template

## NumberFormatter component

New [NumberFormatter](https://mantine.dev/llms/core-number-formatter.md) component allows to format numbers
with thousands separators, decimal separators, and custom number of decimal places.
It supports the same formatting related props as [NumberInput](https://mantine.dev/llms/core-number-input.md) component.

```tsx
import { NumberFormatter } from '@mantine/core';

function Demo() {
  return <NumberFormatter prefix="$ " value={1000000} thousandSeparator />;
}
```


## Form actions

`@mantine/form` package now exports `createFormActions` function that
can be used to [change form state](https://mantine.dev/llms/form-actions.md) from anywhere in your application.
The mechanism of form actions is similar to [notifications system](https://mantine.dev/llms/x-notifications.md),
[modals manager](https://mantine.dev/llms/x-modals.md) and other similar packages.

To use form actions, set `name` property in [use-form](https://mantine.dev/llms/form-use-form.md) settings:

```tsx
import { useForm } from '@mantine/form';

export interface DemoFormValues {
  name: string;
  age: number;
}

function Demo() {
  const form = useForm<DemoFormValues>({
    name: 'demo-form',
    initialValues: {
      name: '',
      age: 0,
    },
  });
}
```

Then call `createFormActions` function with the same form name as specified in `useForm` settings:

```tsx
// Import type of form values from the file where you defined useForm
import { createFormActions } from '@mantine/form';
import type { DemoFormValues } from './DemoForm';

export const demoFormActions =
  createFormActions<DemoFormValues>('demo-form');
```

After that, you can use `demoFormActions` to change form state from anywhere in your application.
For example, after a fetch request or after a user interaction with a component that does not have access
to the form state:

```tsx
import { useEffect } from 'react';
import { Button } from '@mantine/core';
import { demoFormActions } from './demoFormActions';

function ExternalComponent() {
  useEffect(() => {
    fetch('/api/user')
      .then((res) => res.json())
      .then((res) =>
        demoFormActions.setValues({
          name: res.name,
          age: res.age,
        })
      );
  }, []);

  return (
    <Button onClick={() => demoFormActions.reset()}>
      Reset demo form
    </Button>
  );
}
```

## Table data prop

[Table](https://mantine.dev/llms/core-table.md) component now supports `data` prop which can be used to generate table rows
from given data:

```tsx
import { Table, TableData } from '@mantine/core';

const tableData: TableData = {
  caption: 'Some elements from periodic table',
  head: ['Element position', 'Atomic mass', 'Symbol', 'Element name'],
  body: [
    [6, 12.011, 'C', 'Carbon'],
    [7, 14.007, 'N', 'Nitrogen'],
    [39, 88.906, 'Y', 'Yttrium'],
    [56, 137.33, 'Ba', 'Barium'],
    [58, 140.12, 'Ce', 'Cerium'],
  ],
};

function Demo() {
  return <Table data={tableData} />;
}
```


## Table sticky header

[Table](https://mantine.dev/llms/core-table.md) component now supports `stickyHeader` prop, which can be used to make the table header
stick to the top of the table:

```tsx
import { Table } from '@mantine/core';

const elements = [
  { position: 6, mass: 12.011, symbol: 'C', name: 'Carbon' },
  { position: 7, mass: 14.007, symbol: 'N', name: 'Nitrogen' },
  { position: 39, mass: 88.906, symbol: 'Y', name: 'Yttrium' },
  { position: 56, mass: 137.33, symbol: 'Ba', name: 'Barium' },
  { position: 58, mass: 140.12, symbol: 'Ce', name: 'Cerium' },
];

function Demo() {
  const rows = elements.map((element) => (
    <Table.Tr key={element.name}>
      <Table.Td>{element.position}</Table.Td>
      <Table.Td>{element.name}</Table.Td>
      <Table.Td>{element.symbol}</Table.Td>
      <Table.Td>{element.mass}</Table.Td>
    </Table.Tr>
  ));

  return (
    <Table stickyHeader stickyHeaderOffset={60}>
      <Table.Thead>
        <Table.Tr>
          <Table.Th>Element position</Table.Th>
          <Table.Th>Element name</Table.Th>
          <Table.Th>Symbol</Table.Th>
          <Table.Th>Atomic mass</Table.Th>
        </Table.Tr>
      </Table.Thead>
      <Table.Tbody>{rows}</Table.Tbody>
      <Table.Caption>Scroll page to see sticky thead</Table.Caption>
    </Table>
  );
}
```


## Usage with Sass

It is now possible to use Mantine with [Sass](https://sass-lang.com/). You can find documentation
on [this page](https://mantine.dev/llms/styles-sass.md). Note that it is still required to set up [postcss-preset-mantine](https://mantine.dev/llms/styles-postcss-preset.md)
in order for all functions to work properly. Sass can be used as a replacement for [CSS modules](https://mantine.dev/llms/styles-css-modules.md)
– it supports all features that CSS modules support.

You can find examples of Mantine + Sass usage in separate branches of templates:

* [Next.js app router + Sass example](https://github.com/mantinedev/next-app-template/tree/sass)
* [Vite + Sass example](https://github.com/mantinedev/vite-template/tree/sass)

## Inline loaders

[Loader](https://mantine.dev/llms/core-loader.md) component now supports `children` prop. The prop allows overriding the default
loader with any React node. It is useful in components that support `loaderProps` ([Button](https://mantine.dev/llms/core-button.md), [LoadingOverlay](https://mantine.dev/llms/core-loading-overlay.md), [Dropzone](https://mantine.dev/llms/x-dropzone.md), etc.)
– with `loaderProps.children` you can now display any React node instead of the loader.

```tsx
import { useDisclosure } from '@mantine/hooks';
import { LoadingOverlay, Button, Group, Box } from '@mantine/core';

function Demo() {
  const [visible, { toggle }] = useDisclosure(false);

  return (
    <>
      <Box pos="relative">
        <LoadingOverlay visible={visible} loaderProps={{ children: 'Loading...' }} />
        {/* ...other content */}
      </Box>

      <Group justify="center">
        <Button onClick={toggle}>Toggle overlay</Button>
      </Group>
    </>
  );
}
```


## lightHidden and darkHidden props

All Mantine components now support `lightHidden` and `darkHidden` props that can be used to hide
components in a specific color scheme:

```tsx
import { Button } from '@mantine/core';

function Demo() {
  return (
    <>
      <Button color="cyan" lightHidden>
        Visible in dark color scheme only
      </Button>

      <Button color="pink" darkHidden>
        Visible in light color scheme only
      </Button>
    </>
  );
}
```


## light-root and dark-root mixins

New `light-root` and `dark-root` mixins were added to [postcss-preset-mantine](https://mantine.dev/llms/styles-postcss-preset.md).
These mixins can be used to add color scheme specific styles to the `:root`/`html` element.
Note that to use these mixins, you need to update `postcss-preset-mantine` to `1.9.0` or higher.

```scss
:root {
  @mixin light-root {
    --color: red;
  }

  @mixin dark-root {
    --color: blue;
  }
}
```

## Documentation updates

* New [Styles overview](https://mantine.dev/llms/styles-styles-overview.md) guide
* New [Usage with Sass](https://mantine.dev/llms/styles-sass.md) guide
* [Storybook guide](https://mantine.dev/llms/guides-storybook.md) was updated to use new [@storybook/addon-styling-webpack](https://storybook.js.org/addons/@storybook/addon-styling-webpack) with separate instructions for Vite and other frameworks
* [CSS modules](https://mantine.dev/llms/styles-css-modules.md) guide now includes new section about global class names reference with `:global` selector
* [Getting started](https://mantine.dev/llms/getting-started.md#set-up-vs-code) guide now includes new section about setting up VS Code with [PostCSS Language Support](https://marketplace.visualstudio.com/items?itemName=csstools.postcss) and [CSS Variable Autocomplete](https://marketplace.visualstudio.com/items?itemName=vunguyentuan.vscode-css-variables) extensions
* [Popover](https://mantine.dev/llms/core-popover.md#nested-popovers) documentation now includes a guide on how to use nested popovers
* [AspectRatio](https://mantine.dev/llms/core-aspect-ratio.md) documentation now includes a guide on how to use it in flexbox containers
* Additional [AppShell.Section](https://mantine.dev/llms/core-app-shell.md) documentation was added
* 8 new [Checkbox](https://mantine.dev/llms/core-checkbox.md) examples and demos were added

## Other changes

* [Dropzone](https://mantine.dev/llms/x-dropzone.md) now supports `loaderProps` prop to pass props down to the [Loader](https://mantine.dev/llms/core-loader.md) component
* [theme.variantColorResolver](https://mantine.dev/llms/theming-colors.md#colors-variant-resolver) now supports `hoverColor` prop, which allows controlling `color` property when the component is hovered. New property is supported in [Button](https://mantine.dev/llms/core-button.md) and [ActionIcon](https://mantine.dev/llms/core-action-icon.md) components.
* [Flex](https://mantine.dev/llms/core-flex.md) is now a [polymorphic](https://mantine.dev/llms/guides-polymorphic.md) component – it accepts `renderRoot` and `component` props
* [Checkbox](https://mantine.dev/llms/core-checkbox.md) root element now has `data-checked` attribute when the checkbox is checked
* [Checkbox](https://mantine.dev/llms/core-checkbox.md) and [Radio](https://mantine.dev/llms/core-radio.md) components now support changing icon color with `iconColor` prop
* [use-form](https://mantine.dev/llms/form-use-form.md) now supports `onValuesChange` option which can be used to sync form values with external state
