7.12.0

mantinedev/mantine7.12.0Aug 5, 2024by rtivital

AI Summary

A feature-rich release introducing notifications at any position, a new SemiCircleProgress component, and checked state support for the Tree component.

Key Highlights

  • Notifications can now be displayed at any position on the screen
  • New SemiCircleProgress component added to core
  • Tree component now supports checked state
  • PostCSS preset-mantine allows disabling specific features via configuration

New Features

  • Notifications positioning and `useNotifications` hook
  • SemiCircleProgress component
  • Tree checked state support
  • `autoInvoke` option for `use-interval` hook
  • `onTopReached` and `onBottomReached` props for ScrollArea
  • `onTransitionEnd` prop for Accordion.Panel
  • Pagination `hideWithOnePage` prop
  • Spoiler controlled state props
  • Burger `lineSize` prop
  • Calendar `highlightToday` prop

Full Release Notes

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

## Notifications at any position

It is now possible to display notifications at any position on the screen
with [@mantine/notifications package](https://mantine.dev/x/notifications):

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

const positions = [
  'top-left',
  'top-right',
  'bottom-left',
  'bottom-right',
  'top-center',
  'bottom-center',
] as const;

function Demo() {
  const buttons = positions.map((position) => (
    <Button
      key={position}
      onClick={() =>
        notifications.show({
          title: `Notification at ${position}`,
          message: `Notification at ${position} message`,
          position,
        })
      }
    >
      {position}
    </Button>
  ));

  return <Group>{buttons}</Group>;
}
```

## Subscribe to notifications state

You can now subscribe to notifications state changes with `useNotifications` hook:

```tsx
function Demo() {
  const [counter, { increment }] = useCounter();
  const notificationsStore = useNotifications();

  const showNotification = () => {
    notifications.show({
      title: `Notification ${counter}`,
      message: 'Most notifications are added to queue',
    });

    increment();
  };

  return (
    <>
      <Button onClick={showNotification} mb="md">
        Show notification
      </Button>

      <Text>Notifications state</Text>
      <Code block>{JSON.stringify(notificationsStore.notifications, null, 2)}</Code>

      <Text mt="md">Notifications queue</Text>
      <Code block>{JSON.stringify(notificationsStore.queue, null, 2)}</Code>
    </>
  );
}
```

## SemiCircleProgress component

New [SemiCircleProgress](https://mantine.dev/core/semi-circle-progress) component:

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

function Demo() {
  return (
    <SemiCircleProgress
      fillDirection="left-to-right"
      orientation="up"
      filledSegmentColor="blue"
      size={200}
      thickness={12}
      value={40}
      label="Label"
    />
  );
}
```

## Tree checked state

[Tree](https://mantine.dev/core/tree) component now supports checked state:

```tsx
import { IconChevronDown } from '@tabler/icons-react';
import { Checkbox, Group, RenderTreeNodePayload, Tree } from '@mantine/core';
import { data } from './data';

const renderTreeNode = ({
  node,
  expanded,
  hasChildren,
  elementProps,
  tree,
}: RenderTreeNodePayload) => {
  const checked = tree.isNodeChecked(node.value);
  const indeterminate = tree.isNodeIndeterminate(node.value);

  return (
    <Group gap="xs" {...elementProps}>
      <Checkbox.Indicator
        checked={checked}
        indeterminate={indeterminate}
        onClick={() => (!checked ? tree.checkNode(node.value) : tree.uncheckNode(node.value))}
      />

      <Group gap={5} onClick={() => tree.toggleExpanded(node.value)}>
        <span>{node.label}</span>

        {hasChildren && (
          <IconChevronDown
            size={14}
            style={{ transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)' }}
          />
        )}
      </Group>
    </Group>
  );
};

function Demo() {
  return <Tree data={data} levelOffset={23} expandOnClick={false} renderNode={renderTreeNode} />;
}
```

## Disable specific features in postcss-preset-mantine

You can now disable specific features of the [postcss-preset-mantine](https://mantine.dev/styles/postcss-preset)
by setting them to `false` in the configuration object. This feature is available starting from
`postcss-preset-mantine@1.17.0`.

```tsx
module.exports = {
  'postcss-preset-mantine': {
    features: {
      // Turn off `light-dark` function
      lightDarkFunction: false,

      // Turn off `postcss-nested` plugin
      nested: false,

      // Turn off `lighten`, `darken` and `alpha` functions
      colorMixAlpha: false,

      // Turn off `rem` and `em` functions
      remEmFunctions: false,

      // Turn off `postcss-mixins` plugin
      mixins: false,
    },
  },
};
```

## Help Center updates

- [Server components guide](https://help.mantine.dev/q/server-components) has been updated to include `Component.extend` usage in server components.
- [A guide on applying input focus styles](https://help.mantine.dev/q/input-focus-styles) has been updated to work correctly with [PasswordInput](https://mantine.dev/core/password-input) and other components in which the `input` selector is not used for actual input element.
- The guide on [how to disable all inputs in the form](https://help.mantine.dev/q/disable-all-inputs-in-form) now includes additional instructions for [use-form](https://mantine.dev/form/use-form).
- New [Can I have color schemes other than light and dark?](https://help.mantine.dev/q/light-dark-is-not-enough) guide explains the difference between color scheme and theme and why Mantine does not support custom color schemes.
- New [Why VSCode cannot autoimport Text component?](https://help.mantine.dev/q/why-vscode-cannot-autoimport-text) guide explains why VSCode cannot automatically import `Text` component.
- New [Are Mantine components accessible?](https://help.mantine.dev/q/are-mantine-components-accessible) question
- New [How can I focus the first input with error with use-form?](https://help.mantine.dev/q/focus-first-input-with-error) question
- New [How to scroll to the top of the form if the form is submitted with errors?](https://help.mantine.dev/q/scroll-to-the-top-of-the-form) question
- New [Why my notifications are displayed at a wrong position?](https://help.mantine.dev/q/notifications-missing-styles) question
- New [Why my screen is completely empty after I've added notifications package?](https://help.mantine.dev/q/notifications-empty-screen) question
- New [Why can I not use value/label data structure with Autocomplete/TagsInput?](https://help.mantine.dev/q/autocomplete-value-label) question
- New [Why FileButton does not work in Menu?](https://help.mantine.dev/q/file-button-in-menu) question
- New [How can I display different elements in light and dark color schemes?](https://help.mantine.dev/q/light-dark-elements) question

## Other changes

- [use-interval](https://mantine.dev/hooks/use-interval) hook now supports `autoInvoke` option to start the interval automatically when the component mounts.
- [use-form](https://mantine.dev/form/use-form) with `mode="uncontrolled"` now triggers additional rerender when dirty state changes to allow subscribing to form state changes.
- [ScrollArea](https://mantine.dev/core/scroll-area) component now supports `onTopReached` and `onBottomReached` props. The functions are called when the user scrolls to the top or bottom of the scroll area.
- [Accordion.Panel](https://mantine.dev/core/accordion) component now supports `onTransitionEnd` prop that is called when the panel animation completes.