Libraries / Dialog Fields

Dialog Fields

A react-final-form wrapper that provides some useful high-level components for building forms.

Short description

The purpose of DFDialog component is to ease of creating of forms, it is used react-final-form internally. It supports several predefined types of fields but user can extend it by registering new ones by using registerDialogControl.

Controls

  • Base controls
    • plain - static text
    • text - editable text
    • multi-text - user defined array of string
    • checkbox - checkbox
    • tumbler - tumbler
    • radio - radio button
    • editable-list - list of removable strings
    • multi-editable-list - multi list of removable strings
    • text area - text area
    • select - select
    • block - allows to add ReactNode
  • Custom control registration

Features

Install

$ npm install @gravity-ui/dialog-fields

Depending on your package manager you may need to install peerDependencies manually.

Vertical tabs use UIKit's drag-and-drop and virtualization entry points, and Select controls virtualize lists of 50 or more options. Wrap your application in UIKit's Provider and import @gravity-ui/uikit/styles/styles.css.

Migrating to UIKit 8

Replace the application's root ThemeProvider and MobileProvider with Provider. Move their props to Provider, except for the removed __experimentalMobileModals prop:

-import {ThemeProvider, MobileProvider} from '@gravity-ui/uikit';
+import {Provider} from '@gravity-ui/uikit';

-<ThemeProvider theme="light">
-  <MobileProvider>
-    <App />
-  </MobileProvider>
-</ThemeProvider>
+<Provider theme="light">
+  <App />
+</Provider>

If your application already uses Provider, no additional wrapper around DFDialog is needed. DFDialog keeps its visible, size, and onClose props; UIKit's changes to Dialog.open, maxWidth, and onOpenChange are handled inside the library.

Review custom styles and visual snapshots:

  • Dialog header, body, and footer spacing has changed, affecting both modal and inline forms.
  • Desktop footer buttons now fit their content instead of having a minimum width of 128px. To restore the previous width, pass {width: 'max', className: 'form-action'} through both footerProps.propsButtonApply and footerProps.propsButtonCancel, and set .form-action { min-width: 128px; } in your stylesheet.
  • Checkbox controls of size l now use a 13px label instead of 15px and an 18px indicator instead of 17px. Theme colors have also changed slightly.
  • Vertical tabs use the new List without legacy components. Custom selectors targeting the old .g-list__item markup must be revised. The onOrderChanged({oldIndex, newIndex}) callback is preserved.

Custom controls and UIKit props passed through field definitions must follow the UIKit migration guide. In particular, Select no longer accepts virtualizationThreshold; the built-in select control uses ListVirtualizer with a threshold of 50 options.

Usage

This example includes the application provider. If your application already has a root Provider, omit the wrapper shown here.

import {DFDialog} from '@gravity-ui/dialog-fields';
import {Provider} from '@gravity-ui/uikit';
import '@gravity-ui/uikit/styles/styles.css';

interface FormValues {
  firstName: string;
  lastName: string;
}

function MyForm() {
  return (
    <Provider theme="light">
      <DFDialog<FormValues>
        visible={true}
        headerProps={{
          title: 'My form',
        }}
        onAdd={(form) => {
          console.log(form.getState().values);
          return Promise.resolve();
        }}
        fields={[
          {
            name: 'firstName',
            type: 'text',
            caption: 'First name',
            tooltip: 'Description for first name field',
          },
          {
            name: 'lastName',
            type: 'text',
            caption: 'LastName',
            tooltip: 'Description for last name field',
          },
        ]}
      />
    </Provider>
  );
}

Conditional visibility

Fields and tabs support visibilityCondition. With a string when, isActive receives the value of that field:

visibilityCondition: {
  when: 'register',
  isActive: (value) => Boolean(value),
}

Use an array of field names to depend on multiple values. isActive receives the values as separate arguments in the same order as when:

visibilityCondition: {
  when: ['multiConsumer', 'register'],
  isActive: (multiConsumer, register) => Boolean(multiConsumer && register),
}

Names are paths from the form root, including tab prefixes such as general.register. Visibility updates when any referenced field changes. A field hidden by its condition is unmounted, not just visually hidden.

See more examples in storybook.

About library
Support the library with a star
Version
7.0.0
Last update
13.11.2026
Repository
github.com/gravity-ui/dialog-fields
License
MIT License
Maintainers
Contributors