7.9.0

mantinedev/mantine7.9.0May 2, 2024by rtivital

AI Summary

Major release introducing the `@mantine/emotion` package for easier v6 to v7 migration, React 18.3 support, and new hooks like `use-field` and `use-matches`.

Key Highlights

  • New `@mantine/emotion` package for simplified migration from v6
  • Updated all components to support React 18.3
  • New `use-field` hook for simpler single-field state management
  • New `use-matches` hook for matching multiple media queries
  • BarChart now supports `withBarValueLabel` prop

New Features

  • @mantine/emotion package
  • use-field hook
  • use-matches hook
  • withBarValueLabel prop
  • Custom PostCSS mixins support

Full Release Notes

[View changelog with demos on mantine.dev website](https://mantine.dev/changelog/7-9-0)

## @mantine/emotion package

New [@mantine/emotion](https://mantine.dev/styles/emotion) package is now available to simplify migration
from [6.x to 7.x](https://mantine.dev/guides/6x-to-7x/). It includes `createStyles` function and additional
functionality for `sx` and `styles` props for all components similar to what was available
in `@mantine/core` package in v6.

If you still haven't migrated to 7.x because of the change in styling approach, you can now
have a smoother transition by using `@mantine/emotion` package. To learn more about the package,
visit the [documentation page](https://mantine.dev/styles/emotion) and updated [6.x to 7.x migration guide](https://mantine.dev/guides/6x-to-7x/).

```tsx
import { rem } from '@mantine/core';
import { createStyles } from '@mantine/emotion';

const useStyles = createStyles((theme, _, u) => ({
  wrapper: {
    maxWidth: rem(400),
    width: '100%',
    height: rem(180),
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    marginLeft: 'auto',
    marginRight: 'auto',
    borderRadius: theme.radius.sm,

    // Use light and dark selectors to change styles based on color scheme
    [u.light]: {
      backgroundColor: theme.colors.gray[1],
    },

    [u.dark]: {
      backgroundColor: theme.colors.dark[5],
    },

    // Reference theme.breakpoints in smallerThan and largerThan functions
    [u.smallerThan('sm')]: {
      // Child reference in nested selectors via ref
      [`& .${u.ref('child')}`]: {
        fontSize: theme.fontSizes.xs,
      },
    },
  },

  child: {
    // Assign selector to a ref to reference it in other styles
    ref: u.ref('child'),
    padding: theme.spacing.md,
    borderRadius: theme.radius.sm,
    boxShadow: theme.shadows.md,

    [u.light]: {
      backgroundColor: theme.white,
      color: theme.black,
    },

    [u.dark]: {
      backgroundColor: theme.colors.dark[8],
      color: theme.white,
    },
  },
}));

function Demo() {
  const { classes } = useStyles();

  return (
    <div className={classes.wrapper}>
      <div className={classes.child}>createStyles demo</div>
    </div>
  );
}
```

## React 18.3 support

All `@mantine/*` components and hooks have been updated to support React 18.3. It is
recommended to update your application as well to prepare for the upcoming [React 19 release](https://react.dev/blog/2024/04/25/react-19).

## use-field hook

New [use-field](https://mantine.dev/form/use-field) hook is now available in `@mantine/form` package.
It can be used as a simpler alternative to [use-form](https://mantine.dev/form/use-form) hook to manage state of a single input without the need to create a form.
The hook supports most of `use-form` hook features: validation with function, touched and
dirty state, error message, validation on change/blur and more.

```tsx
import { TextInput } from '@mantine/core';
import { isEmail, useField } from '@mantine/form';

function Demo() {
  const field = useField({
    initialValue: '',
    validateOnChange: true,
    validate: isEmail('Invalid email'),
  });

  return <TextInput {...field.getInputProps()} label="Email" placeholder="Enter your email" />;
}
```

`use-field` hook also supports async validation:

```tsx
import { Button, Loader, TextInput } from '@mantine/core';
import { useField } from '@mantine/form';

function validateAsync(value: string): Promise<string | null> {
  return new Promise((resolve) => {
    window.setTimeout(() => {
      resolve(value === 'mantine' ? null : 'Value must be "mantine"');
    }, 800);
  });
}

function Demo() {
  const field = useField({
    initialValue: '',
    validate: validateAsync,
  });

  return (
    <>
      <TextInput
        {...field.getInputProps()}
        label="Enter 'mantine'"
        placeholder="Enter 'mantine'"
        rightSection={field.isValidating ? <Loader size={18} /> : null}
        mb="md"
      />
      <Button onClick={field.validate}>Validate async</Button>
    </>
  );
}
```

## Custom PostCSS mixins

You can now define custom mixins that are not included in [mantine-postcss-preset](https://mantine.dev/styles/postcss-preset) by specifying them
in the `mixins` option. To learn about mixins syntax, follow [postcss-mixins documentation](https://github.com/postcss/postcss-mixins#readme).
Note that this feature is available in `postcss-preset-mantine` starting from version 1.15.0.

Example of adding `clearfix` and `circle` mixins:

```tsx
module.exports = {
  plugins: {
    'postcss-preset-mantine': {
      autoRem: true,
      mixins: {
        clearfix: {
          '&::after': {
            content: '""',
            display: 'table',
            clear: 'both',
          },
        },
        circle: (_mixin, size) => ({
          borderRadius: '50%',
          width: size,
          height: size,
        }),
      },
    },
    // ... Other plugins
  },
};
```

Then you can use these mixins in your styles:

```scss
.demo {
  @mixin clearfix;
  @mixin circle 100px;
}
```

## use-matches hook

New `use-matches` hook exported from `@mantine/core` is an alternative to [use-media-query](https://mantine.dev/hooks/use-media-query/)
if you need to match multiple media queries and values. It accepts an object with media queries as keys and
values at given breakpoint as values.

Note that `use-matches` hook uses the same logic as [use-media-query](https://mantine.dev/hooks/use-media-query/) under the hood,
it is not recommended to be used as a primary source of responsive styles, especially if you have ssr in your application.

In the following example:

- Starting from `theme.breakpoints.lg`, color will be `red.9`
- Between `theme.breakpoints.sm` and `theme.breakpoints.lg`, color will be `orange.9`
- Below `theme.breakpoints.sm`, color will be `blue.9`

```tsx
import { Box, useMatches } from '@mantine/core';

function Demo() {
  const color = useMatches({
    base: 'blue.9',
    sm: 'orange.9',
    lg: 'red.9',
  });

  return (
    <Box bg={color} c="white" p="xl">
      Box with color that changes based on screen size
    </Box>
  );
}
```

## BarChart value label

[BarChart](https://mantine.dev/charts/bar-chart) now supports `withBarValueLabel` prop that allows
displaying value label on top of each bar:

```tsx
import { BarChart } from '@mantine/charts';
import { data } from './data';

function Demo() {
  return (
    <BarChart
      h={300}
      data={data}
      dataKey="month"
      valueFormatter={(value) => new Intl.NumberFormat('en-US').format(value)}
      withBarValueLabel
      series={[
        { name: 'Smartphones', color: 'violet.6' },
        { name: 'Laptops', color: 'blue.6' },
        { name: 'Tablets', color: 'teal.6' },
      ]}
    />
  );
}
```

## Documentation updates

- New [usage with emotion](https://mantine.dev/styles/emotion) guide
- [6.x -> 7.x](https://mantine.dev//guides/6x-to-7x/) guide has been updated to include migration to [@mantine/emotion](https://mantine.dev/styles/emotion) package
- [use-field](https://mantine.dev/form/use-field) hook documentation
- [Uncontrolled form mode](https://mantine.dev/form/uncontrolled) examples now include usage of `form.key()` function
- [Custom PostCSS mixins](https://mantine.dev/styles/postcss-preset/#custom-mixins) documentation
- [use-matches](https://mantine.dev/styles/responsive/#use-matches-hook) hook documentation has been added to the responsive guide

## Other changes

- Advanced templates now include GitHub workflows to run tests on CI
- [AspectRatio](https://mantine.dev/core/aspect-ratio) component has been migrated to [aspect-ratio](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) CSS property