Mantine Editor Plugins

Connect Mantine Select, DatePicker, ColorPicker, and TimePicker controls to BeautifulGrid columns with @beautifuljs/grid-mantine.

#editor-plugin#mantine#portal#date-picker#color-picker#time-picker
Last reviewed: 2026-09-24
LIVE DEMOMantine Editor Plugins interactive example
Loading the interactive demo…
GitHub
import { t } from './i18n';
import * as React from 'react';
import { BGrid, type BGridColumn, type BGridDataItem } from 'beautiful-grid';
import {
  createMantineColorPickerEditorPlugin,
  createMantineDatePickerEditorPlugin,
  createMantineSelectEditorPlugin,
  createMantineTimePickerEditorPlugin,
} from '@beautifuljs/grid-mantine';
import '@beautifuljs/grid-mantine/style.css';
import DataGridContainer from '../components/DataGridContainer';
import { useContainerSize } from '../hooks/useContainerSize';
import { CalendarIcon, ChevronDownIcon, ClockIcon } from './editing/editorIcons';
import {
  applyEditingDataChange,
  cloneEditingOrders,
  type EditingOrder,
  withEditingCellClasses,
} from './editing/shared';

type MantineEditorOrder = EditingOrder & {
  labelColor: string;
  deliveryTime: string;
};

const statusEditor = createMantineSelectEditorPlugin<MantineEditorOrder, EditingOrder['status']>({
  id: 'mantine-status',
  ariaLabel: t('Mantine 주문 상태 선택', 'Mantine Select Order Status'),
  searchable: true,
  options: [
    { value: t('접수', 'Receipt'), label: t('접수', 'Receipt') },
    { value: t('진행', 'In Progress'), label: t('진행', 'In Progress') },
    { value: t('완료', 'Completed'), label: t('완료', 'Completed') },
  ],
});

const deliveryDateEditor = createMantineDatePickerEditorPlugin<MantineEditorOrder>({
  id: 'mantine-delivery-date',
  ariaLabel: t('Mantine 납기일 선택', 'Mantine Select Delivery Date'),
});

const labelColorEditor = createMantineColorPickerEditorPlugin<MantineEditorOrder>({
  id: 'mantine-label-color',
  ariaLabel: t('Mantine 라벨 색상 선택', 'Mantine Select Label Color'),
  colors: ['#228BE6', '#12B886', '#7950F2', '#FD7E14'],
});

const deliveryTimeEditor = createMantineTimePickerEditorPlugin<MantineEditorOrder>({
  id: 'mantine-delivery-time',
  ariaLabel: t('Mantine 배송 시간 선택', 'Mantine Select Delivery Time'),
  minuteStep: 5,
});

const initialColors = ['#228BE6', '#12B886', '#7950F2', '#FD7E14'];
const initialDeliveryTimes = ['09:30', '11:00', '14:30', '16:00'];

const cloneMantineEditorOrders = (): BGridDataItem<MantineEditorOrder>[] =>
  cloneEditingOrders().map((item, index) => ({
    ...item,
    values: {
      ...item.values,
      labelColor: initialColors[index % initialColors.length],
      deliveryTime: initialDeliveryTimes[index % initialDeliveryTimes.length],
    },
  }));

export default function ExternalMantineEditorPluginExample() {
  const [data, setData] = React.useState(cloneMantineEditorOrders);
  const containerRef = React.useRef<HTMLDivElement>(null);
  const { width, height } = useContainerSize(containerRef);

  const columns = React.useMemo<BGridColumn<MantineEditorOrder>[]>(
    () =>
      withEditingCellClasses<MantineEditorOrder>([
        { key: 'orderCode', label: t('주문 코드', 'Order Code'), width: 140, editable: false },
        {
          key: 'status',
          label: 'Mantine Select',
          width: 165,
          editable: true,
          editor: statusEditor,
          editorIcon: { render: <ChevronDownIcon />, ariaLabel: t('Mantine 상태 선택', 'Mantine Select Status') },
        },
        {
          key: 'deliveryDate',
          label: 'Mantine DatePicker',
          width: 175,
          editable: true,
          editor: deliveryDateEditor,
          editorIcon: { render: <CalendarIcon />, ariaLabel: t('Mantine 납기일 선택', 'Mantine Select Delivery Date') },
        },
        {
          key: 'labelColor',
          label: 'Mantine ColorPicker',
          width: 175,
          editable: true,
          editor: labelColorEditor,
          editorIcon: {
            render: ({ value }) => (
              <span
                className='bgrid-color-swatch'
                style={{ backgroundColor: typeof value === 'string' ? value : 'transparent' }}
                aria-hidden='true'
              />
            ),
            ariaLabel: t('Mantine 라벨 색상 선택', 'Mantine Select Label Color'),
          },
        },
        {
          key: 'deliveryTime',
          label: 'Mantine TimePicker',
          width: 175,
          editable: true,
          editor: deliveryTimeEditor,
          editorIcon: { render: <ClockIcon />, ariaLabel: t('Mantine 배송 시간 선택', 'Mantine Select Delivery Time') },
        },
      ]),
    [],
  );

  return (
    <div className='flex min-h-0 flex-col gap-3'>
      <p className='m-0 rounded-lg border border-slate-200 bg-slate-50 p-3 text-sm leading-6 text-slate-700 dark:border-slate-800 dark:bg-slate-900 dark:text-slate-300'>
        <code>@beautifuljs/grid-mantine</code>
        {t(
          '의 Select, DatePicker, ColorPicker, TimePicker를 사용합니다. Cascader와 TreeSelect는 이 통합의 지원 범위에 포함되지 않습니다.',
          ' provides Select, DatePicker, ColorPicker, and TimePicker. Cascader and TreeSelect are outside this integration scope.',
        )}
      </p>
      <DataGridContainer ref={containerRef} style={{ height: 340 }}>
        <BGrid<MantineEditorOrder>
          width={width}
          height={height}
          data={data}
          columns={columns}
          rowKey='id'
          editable
          variant='vertical-bordered'
          onChangeData={(sourceIndex, _columnIndex, values, _column, meta) => {
            setData(current => applyEditingDataChange(current, sourceIndex, values, meta));
          }}
        />
      </DataGridContainer>
    </div>
  );
}

@beautifuljs/grid-mantine is the official package that connects Mantine components to the BeautifulGrid plugin-editor lifecycle. It provides Select, DatePicker, ColorPicker, and TimePicker and renders every dropdown and popover inside the Grid portal.

Install

npm install @beautifuljs/grid-mantine @mantine/core @mantine/dates dayjs

Import Mantine’s base styles and the plugin stylesheet once from the application entry point, and place MantineProvider above the application.

import { MantineProvider } from '@mantine/core';
import '@mantine/core/styles.css';
import '@mantine/dates/styles.css';
import 'beautiful-grid/style.css';
import '@beautifuljs/grid-mantine/style.css';

root.render(
  <MantineProvider>
    <App />
  </MantineProvider>,
);

Connect editor factories

import {
  createMantineColorPickerEditorPlugin,
  createMantineDatePickerEditorPlugin,
  createMantineSelectEditorPlugin,
  createMantineTimePickerEditorPlugin,
} from '@beautifuljs/grid-mantine';

const statusEditor = createMantineSelectEditorPlugin<Order, Order['status']>({
  id: 'order-status',
  ariaLabel: 'Select order status',
  searchable: true,
  options: [
    { value: 'ready', label: 'Ready' },
    { value: 'done', label: 'Done' },
  ],
});

const dateEditor = createMantineDatePickerEditorPlugin<Order>({
  id: 'order-date',
  ariaLabel: 'Select delivery date',
});

const colorEditor = createMantineColorPickerEditorPlugin<Order>({
  id: 'order-color',
  ariaLabel: 'Select label color',
  colors: ['#228BE6', '#12B886', '#FD7E14'],
});

const timeEditor = createMantineTimePickerEditorPlugin<Order>({
  id: 'order-time',
  ariaLabel: 'Select delivery time',
  minuteStep: 5,
});
const columns: BGridColumn<Order>[] = [
  { key: 'status', label: 'Status', editable: true, editor: statusEditor },
  { key: 'deliveryDate', label: 'Delivery date', editable: true, editor: dateEditor },
  { key: 'labelColor', label: 'Color', editable: true, editor: colorEditor },
  { key: 'deliveryTime', label: 'Time', editable: true, editor: timeEditor },
];

Supported values

  • Select supports string and number options plus searchable mode.
  • DatePicker stores an ISO-style YYYY-MM-DD string.
  • ColorPicker stores #RRGGBB by default and can optionally enable alpha.
  • TimePicker stores HH:mm, or HH:mm:ss when seconds are enabled.
  • Cascader and TreeSelect are not part of the official Mantine integration scope.

Closing a popup before a value is saved cancels the editing session. After Apply or a value selection commits, the following close event cannot overwrite the saved result.

See the @beautifuljs/grid-mantine npm page for package APIs and license information.