Bibliotecas / DashKit

DashKit

Un componente de cuadrícula para crear dashboards interactivos.

@gravity-ui/dashkit · npm package CI storybook

DashKit

Una librería para renderizar un grid de dashboards.

Instalación

npm i @gravity-ui/dashkit @gravity-ui/uikit

Descripción

La librería se utiliza para alinear widgets en una cuadrícula, redimensionarlos, añadir nuevos y eliminarlos. Un widget es un componente de React. Por ejemplo, texto, gráficos e imágenes.

Los nuevos widgets se añaden a través de un sistema de plugins.

Plugins

Los plugins son necesarios para crear widgets personalizados.

Props

type ItemManipulationCallback = (eventData: {
    layout: Layouts;
    oldItem: Layout;
    newItem: Layout;
    placeholder: Layout;
    e: MouseEvent;
    element: HTMLElement;
}) => void;

interface DashKitProps {
  config: Config;
  editMode: boolean;
  onItemEdit: ({id}: {id: string}) => void;
  onChange: (data: {config: Config; itemsStateAndParams: ItemsStateAndParams}) => void;
  onDrop: (dropProps: ItemDropProps) => void;
  onItemMountChange: (item: ConfigItem, state: {isAsync: boolead; isMounted: boolean}) => void;
  onItemRender: (item: ConfigItem) => void;

  onDragStart?: ItemManipulationCallback;
  onDrag?: ItemManipulationCallback;
  onDragStop?: ItemManipulationCallback;
  onResizeStart?: ItemManipulationCallback;
  onResize?: ItemManipulationCallback;
  onResizeStop?: ItemManipulationCallback;

  defaultGlobalParams: GlobalParams;
  globalParams: GlobalParams;
  itemsStateAndParams: ItemsStateAndParams;
  settings: SettingsProps;
  context: ContextProps;
  overlayControls?: Record<string, OverlayControlItem[]> | null;
  overlayMenuItems?: MenuItems[] | null;
  noOverlay?: boolean;

  focusable?: boolean;
  onItemFocus: (item: ConfigItem) => void;
  onItemBlur: (item: ConfigItem) => void;

  draggableHandleClassName?: string;
  getPreparedCopyItemOptions?: (options: PreparedCopyItemOptions) => PreparedCopyItemOptions;
  onCopyFulfill?: (error: null | Error, data?: PreparedCopyItemOptions) => void;
}
  • config: Config.
  • editMode: Indica si el modo de edición está activado.
  • onItemEdit: Se llama al hacer clic para editar un widget.
  • onChange: Se llama cuando cambian la configuración o itemsStateAndParams.
  • onDrop: Se llama cuando un elemento se suelta desde ActionPanel usando (#DashKitDnDWrapper).
  • onItemMountChange: Se llama cuando cambia el estado de montaje de un elemento.
  • onItemRender: Se llama cuando finaliza el renderizado de un elemento.
  • defaultGlobalParams, globalParams: Parámetros que afectan a todos los widgets. En DataLens, defaultGlobalParams son parámetros globales establecidos en la configuración del dashboard. globalParams son parámetros globales que se pueden establecer en la URL.
  • itemsStateAndParams: itemsStateAndParams.
  • settings: Configuración de DashKit.
  • context: Objeto que se pasará a todos los widgets.
  • overlayControls: Objeto que reemplaza los controles del widget durante la edición. Si no se proporciona, se mostrarán los controles básicos. Si se pasa null, solo se mostrará el botón de cierre o un menú personalizado.
  • overlayMenuItems: Elementos de menú desplegable personalizados.
  • noOverlay: Si es true, la superposición y los controles no se mostrarán durante la edición.
  • focusable: Si es true, los elementos de la cuadrícula serán enfocables.
  • onItemFocus: Se llama cuando focusable es true y un elemento recibe el foco.
  • onItemBlur: Se llama cuando focusable es true y un elemento pierde el foco.
  • draggableHandleClassName: Nombre de la clase CSS del elemento que hace que el widget sea arrastrable.
  • onDragStart: Llamado por ReactGridLayout cuando comienza a arrastrar un elemento.
  • onDrag: Llamado por ReactGridLayout mientras se arrastra un elemento.
  • onDragStop: Llamado por ReactGridLayout cuando se detiene el arrastre de un elemento.
  • onResizeStart: Llamado por ReactGridLayout cuando comienza a redimensionar un elemento.
  • onResize: Llamado por ReactGridLayout mientras se redimensiona un elemento.
  • onResizeStop: Llamado por ReactGridLayout cuando se detiene el redimensionamiento de un elemento.
  • getPreparedCopyItemOptions: Se llama para convertir un elemento copiado en un objeto serializable antes de guardarlo en el localStorage. Debe usarse en lugar de la prop obsoleta context.getPreparedCopyItemOptions.
  • onCopyFulfill: Se llama cuando la copia de un elemento finaliza con error=null y data definidos en caso de éxito, y con error: Error sin data en caso contrario.

Uso

Configuración de DashKit

Antes de usar DashKit como un componente de React, debe configurarse.

  • Establecer el idioma

    import {configure, Lang} from '@gravity-ui/uikit';
    
    configure({lang: Lang.En});
    
  • DashKit.setSettings

    Se utiliza para la configuración global de DashKit (como márgenes entre widgets, tamaños predeterminados de widgets y menú de superposición de widgets).

    import {DashKit} from '@gravity-ui/dashkit';
    
    DashKit.setSettings({
      gridLayout: {margin: [8, 8]},
      isMobile: true,
      // menu: [] as Array<MenuItem>,
    });
    
  • DashKit.registerPlugins

    Registro y configuración de plugins.

    import {DashKit} from '@gravity-ui/dashkit';
    import {pluginTitle, pluginText} from '@gravity-ui/dashkit';
    
    DashKit.registerPlugins(
      pluginTitle,
      pluginText.setSettings({
        apiHandler({text}) {
          return api.getMarkdown(text);
        },
      }),
    );
    
    DashKit.registerPlugins({
      type: 'custom',
      defaultLayout: {
        w: 10,
        h: 8,
      },
      renderer: function CustomPlugin() {
        return <div>Widget personalizado con controles personalizados</div>;
      },
    });
    

Config

export interface Config {
  salt: string; // para formar un ID único
  counter: number; // para formar un ID único, solo aumenta
  items: ConfigItem[]; // estados iniciales de los widgets
  layout: ConfigLayout[]; // posición del widget en la cuadrícula https://github.com/react-grid-layout
  aliases: ConfigAliases; // alias para parámetros ver #Params
  connections: ConfigConnection[]; // enlaces entre widgets ver #Params
}

Ejemplo de configuración:

import {DashKitProps} from '@gravity-ui/dashkit';
<ul>
  <li><a href="#es">Español</a></li>
</ul>
const config: DashKitProps['config'] = {
  salt: '0.46703554571365613',
  counter: 4,
  items: [
    {
      id: 'tT',
      data: {
        size: 'm',
        text: 'Título',
        showInTOC: true,
      },
      type: 'title',
      namespace: 'default',
      orderId: 1,
    },
    {
      id: 'Ea',
      data: {
        text: 'modo _editActive',
        _editActive: true,
      },
      type: 'text',
      namespace: 'default',
    },
    {
      id: 'zR',
      data: {
        text: '### Texto',
      },
      type: 'text',
      namespace: 'default',
      orderId: 0,
    },
    {
      id: 'Dk',
      data: {
        foo: 'bar',
      },
      type: 'custom',
      namespace: 'default',
      orderId: 5,
    },
  ],
  layout: [
    {
      h: 2,
      i: 'tT',
      w: 36,
      x: 0,
      y: 0,
    },
    {
      h: 6,
      i: 'Ea',
      w: 12,
      x: 0,
      y: 2,
    },
    {
      h: 6,
      i: 'zR',
      w: 12,
      x: 12,
      y: 2,
    },
    {
      h: 4,
      i: 'Dk',
      w: 8,
      x: 0,
      y: 8,
    },
  ],
  aliases: {},
  connections: [],
};

Añadir un nuevo elemento a la configuración:

const newLayout = updateLayout: [
  {
    h: 6,
    i: 'Ea',
    w: 12,
    x: 0,
    y: 6,
  },
  {
    h: 4,
    i: 'Dk',
    w: 8,
    x: 0,
    y: 12,
  },
];

const newConfig = DashKit.setItem({
  item: {
    data: {
      text: `Algún texto`,
    },
    namespace: 'default',
    type: 'text',
    // Opcional. Si se necesita insertar un nuevo elemento en el diseño actual con dimensiones predefinidas
    layout: { // El nuevo elemento se inserta antes de 'Ea'
      h: 6,
      w: 12,
      x: 0,
      y: 2,
    },,
  },
  config: config,
  options: {
    // Opcional. Nuevos valores de diseño para elementos existentes cuando se suelta un nuevo elemento desde ActionPanel
    updateLayout: newLayout,
  },
});

Modificar un elemento existente en la configuración:

const newConfig = DashKit.setItem({
  item: {
    id: 'tT', // id del elemento
    data: {
      size: 'm',
      text: `Nuevo título`,
    },
    namespace: 'default',
    type: 'title',
  },
  config: config,
});

Eliminar un elemento de la configuración:

import {DashKitProps} from '@gravity-ui/dashkit';

const oldItemsStateAndParams: DashKitProps['itemsStateAndParams'] = {};

const {config: newConfig, itemsStateAndParams} = DashKit.removeItem({
  id: 'tT', // id del elemento
  config: config,
  itemsStateAndParams: this.state.itemsStateAndParams,
});

Parámetros

type Params = Record<string, string | string[]>;

DashKit genera parámetros según los parámetros predeterminados para widgets, enlaces y alias. Estos parámetros son necesarios para la biblioteca ChartKit.

Orden de generación:

  1. defaultGlobalParams
  2. Parámetros predeterminados del widget item.default
  3. globalParams
  4. Parámetros de itemsStateAndParams según la cola.

itemsStateAndParams

Objeto que almacena los parámetros y estados de los widgets, así como una cola de cambios de parámetros. Tiene un campo __meta__ para almacenar información de la cola y metadatos.

interface StateAndParamsMeta = {
    __meta__: {
        queue: {id: string}[]; // cola
        version: number; // versión actual de itemsStateAndParams
    };
}

Y también estados y parámetros de los widgets:

interface ItemsStateAndParamsBase {
  [itemId: string]: {
    state?: Record<string, any>;
    params?: Params;
  };
}
type ItemsStateAndParams = StateAndParamsMeta & ItemsStateAndParamsBase;

Menú

Puedes especificar un menú superpuesto personalizado para los widgets de DashKit en modo de edición.

type MenuItem = {
  id: string; // id único
  title?: string; // título de cadena
  icon?: ReactNode; // nodo de icono
  iconSize?: number | string; // tamaño del icono en px como número o como cadena con unidades
  handler?: (item: ConfigItem) => void; // manejador de acción personalizado del elemento
  visible?: (item: ConfigItem) => boolean; // manejador de visibilidad opcional para filtrar elementos del menú
  className?: string; // propiedad de clase personalizada
};

// usar un array de elementos de menú en la configuración
<Dashkit overlayMenuItems={[] as Array<MenuItem> | null} />

[obsoleto]
// la propiedad overlayMenuItems tiene mayor prioridad que el menú setSettings
DashKit.setSettings({menu: [] as Array<MenuItem>});

Elementos arrastrables desde ActionPanel

DashKitDnDWrapper

type DraggedOverItem = {
  h: number;
  w: number;
  type: string;
  parent: string;
  i?: number;
};

interface DashKitDnDWrapperProps {
  dragImageSrc?: string;
  onDragStart?: (dragProps: ItemDragProps) => void;
  onDragEnd?: () => void;
  onDropDragOver?: (draggedItem: DraggedOverItem, sharedItem: DraggedOverItem | null) => void | boolean;
}
  • dragImageSrc: Vista previa de la imagen de arrastre, por defecto se utiliza un png transparente de 1px en base64.
  • onDragStart: Función de devolución de llamada que se llama cuando un elemento se arrastra desde ActionPanel.
  • onDragEnd: Función de devolución de llamada que se llama cuando se suelta un elemento o se cancela el arrastre.
type ItemDragProps = {
    type: string; // Tipo de plugin
    layout?: { // Opcional. Tamaño del elemento de diseño para vista previa e inicialización
        w?: number;
        h?: number;
    };
    extra?: any; // Contexto personalizado del usuario
};
type ItemDropProps = {
    commit: () => void; // La función de devolución de llamada debe ser llamada después de que se realicen todas las operaciones de configuración
    dragProps: ItemDragProps; // Propiedades de arrastre del elemento
    itemLayout: ConfigLayout; // Dimensiones del diseño del elemento calculadas
    newLayout: ConfigLayout[]; // Nuevo diseño después de soltar el elemento
};

Ejemplo:

const overlayMenuItems = [
  {
    id: 'chart',
    icon: <Icon data={ChartColumn} />,
    title: 'Gráfico',
    qa: 'chart',
    dragProps: { // ItemDragProps
        type: 'custom', // Tipo de plugin registrado
    },
  }
]

const onDrop = (dropProps: ItemDropProps) => {
  // ... añadir elemento a tu configuración
  dropProps.commit();
}

<DashKitDnDWrapper>
  <DashKit editMode={true} config={config} onChange={onChange} onDrop={onDrop} />
  <ActionPanel items={overlayMenuItems} />
</DashKitDnDWrapper>

API de CSS

NombreDescripción
Variables del panel de acciones
--dashkit-action-panel-colorColor de fondo
--dashkit-action-panel-border-colorColor del borde
--dashkit-action-panel-border-radiusRadio del borde
Variables de elementos del panel de acciones
--dashkit-action-panel-item-colorColor de fondo
--dashkit-action-panel-item-text-colorColor del texto
--dashkit-action-panel-item-color-hoverColor de fondo al pasar el ratón
--dashkit-action-panel-item-text-color-hoverColor del texto al pasar el ratón
Variables de superposición
--dashkit-overlay-border-colorColor del borde
--dashkit-overlay-colorColor de fondo
--dashkit-overlay-opacityOpacidad
Variables de elementos de la cuadrícula
--dashkit-grid-item-edit-opacityOpacidad
--dashkit-grid-item-border-radiusRadio del borde
Variables de marcador de posición
--dashkit-placeholder-colorColor de fondo
--dashkit-placeholder-opacityOpacidad

Ejemplo de uso

.custom-theme-wrapper {
  --dashkit-grid-item-edit-opacit: 1;
  --dashkit-overlay-color: var(--g-color-base-float);
  --dashkit-overlay-border-color: var(--g-color-base-float);
  --dashkit-overlay-opacity: 0.5;

  --dashkit-action-panel-border-color: var(--g-color-line-info);
  --dashkit-action-panel-color: var(--g-color-base-float-accent);
  --dashkit-action-panel-border-radius: var(--g-border-radius-xxl);
}
// ....

const CustomThemeWrapper = (props: {
  dashkitProps: DashkitProps;
  actionPanelProps: ActionPanelProps;
}) => {
  return (
    <div className="custom-theme-wrapper">
      <Dashkit {...props.dashkitProps} />
      <ActionPanel {...props.actionPanelProps} />
    </div>
  );
};

Desarrollo

Compilar y observar

  • Compilar dependencias npm ci
  • Compilar proyecto npm run build
  • Compilar storybook npm run start

Por defecto, storybook se ejecuta en http://localhost:7120/. Los nuevos cambios en un proyecto no siempre se detectan cuando storybook está en ejecución, por lo que es mejor recompilar el proyecto manualmente y reiniciar storybook.

Ejemplo de configuración de nginx para desarrollo en una máquina de desarrollo

server {
    server_name dashkit.username.ru;

    include common/ssl;

    access_log /home/username/logs/common.access.log;
    error_log /home/username/logs/common.error.log;

    root /home/username/projects/dashkit;

    location / {
        try_files $uri @node;
    }

    location @node {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:7120;
        proxy_redirect off;
    }
}

Acerca de la biblioteca
Estrellas
16
Versión
9.1.1
Última actualización
17.06.2025
Repositorio
github.com/gravity-ui/dashkit
Licencia
MIT License
Mantenedores
Colaboradores