diff --git a/src/components/Table/__stand__/Table.dev.stand.mdx b/src/components/Table/__stand__/Table.dev.stand.mdx
index 2ba9b96..8ad09b2 100644
--- a/src/components/Table/__stand__/Table.dev.stand.mdx
+++ b/src/components/Table/__stand__/Table.dev.stand.mdx
@@ -17,6 +17,11 @@ import { TableExampleActiveRow } from './examples/TableExampleActiveRow/TableExa
import { TableExampleActiveRowWithNumbering } from './examples/TableExampleActiveRowWithNumbering/TableExampleActiveRowWithNumbering';
import { TableExampleRowHoverEffect } from './examples/TableExampleRowHoverEffect/TableExampleRowHoverEffect';
import { TableExampleHoveredControlled } from './examples/TableExampleHoveredControlled/TableExampleHoveredControlled';
+import { TableExampleLoadingDataWithLoader } from './examples/TableExampleLoadingDataWithLoader/TableExampleLoadingDataWithLoader';
+import { TableExampleLoadingDataWithSkeleton } from './examples/TableExampleLoadingDataWithSkeleton/TableExampleLoadingDataWithSkeleton';
+import { TableExampleLoadingRowWithLoader } from './examples/TableExampleLoadingRowWithLoader/TableExampleLoadingRowWithLoader';
+import { TableExampleLoadingRowWithSkeleton } from './examples/TableExampleLoadingRowWithSkeleton/TableExampleLoadingRowWithSkeleton';
+import { TableExampleLoadingNestedRowWithLoader } from './examples/TableExampleLoadingNestedRowWithLoader/TableExampleLoadingNestedRowWithLoader';
import {
TableExampleResizableInside,
TableExampleResizableOutside,
@@ -1030,9 +1035,9 @@ import { action, atom, AtomMut } from '@reatom/core';
import { useAction, useAtom } from '@reatom/npm-react';
import React from 'react';
-import { DataCell } from '##/components/DataCell';
-import { DataNumberingCell } from '##/components/DataNumberingCell';
-import { Table, TableColumn, TableRenderCell } from '##/components/Table';
+import { DataCell } from '@consta/table/DataCell';
+import { DataNumberingCell } from '@consta/table/DataNumberingCell';
+import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
// Types
@@ -1173,7 +1178,7 @@ export const TableExampleActiveRowWithNumbering = () => {
import React from 'react';
import { Table, TableColumn } from '@consta/table/Table';
-import rows from '##/components/Table/__mocks__/olympic-winners.json';
+import rows from '@consta/table/Table/__mocks__/olympic-winners.json';
type ROW = {
athlete: string;
@@ -1351,8 +1356,8 @@ import { atom, AtomMut } from '@reatom/core';
import { useAction, useAtom } from '@reatom/npm-react';
import React from 'react';
-import { DataCell } from '##/components/DataCell';
-import { Table, TableColumn, TableRenderCell } from '##/components/Table';
+import { DataCell } from '@consta/table/DataCell';
+import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
type ROW = {
id: number;
@@ -1459,7 +1464,7 @@ import { Example } from '@consta/stand';
import React from 'react';
import { Table, TableColumn } from '@consta/table/Table';
-import rows from '##/components/Table/__mocks__/olympic-winners.json';
+import rows from '@consta/table/Table/__mocks__/olympic-winners.json';
type ROW = {
athlete: string;
@@ -1515,7 +1520,7 @@ import { Example } from '@consta/stand';
import React from 'react';
import { Table, TableColumn } from '@consta/table/Table';
-import rows from '##/components/Table/__mocks__/olympic-winners.json';
+import rows from '@consta/table/Table/__mocks__/olympic-winners.json';
type ROW = {
athlete: string;
@@ -1793,7 +1798,7 @@ import { Text } from '@consta/uikit/Text';
import { useMutableRef } from '@consta/uikit/useMutableRef';
import React, { useCallback, useMemo, useState } from 'react';
-import { DataCell } from '##/components/DataCell';
+import { DataCell } from '@consta/table/DataCell';
import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
const IconArrow = withAnimateSwitcherHOC({
@@ -2034,6 +2039,385 @@ export const TableExampleRenderRow = () => {
+## Состояние загрузки
+
+Загрузку можно отобразить двумя видами с помощью `Loader` или `Skeleton`.
+
+**Пример загрузки данных всей таблицы с помощью `Loader`:**
+
+
+
+
+
+```tsx
+import { Loader } from '@consta/uikit/Loader';
+import React from 'react';
+
+import { DataCell } from '@consta/table/DataCell';
+import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [{ isLoader: true }];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingDataWithLoader = () => {
+ return (
+
+ );
+};
+```
+
+
+
+**Пример загрузки данных всей таблицы с помощью `Skeleton`:**
+
+
+
+
+
+```tsx
+import { Loader } from '@consta/uikit/Loader';
+import { cnMixSpace } from '@consta/uikit/MixSpace';
+import { SkeletonBrick } from '@consta/uikit/Skeleton';
+import React from 'react';
+
+import { DataCell } from '@consta/table/DataCell';
+import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [
+ { isLoader: true },
+ { isLoader: true },
+ { isLoader: true },
+];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingDataWithSkeleton = () => {
+ return (
+
+ );
+};
+```
+
+
+
+**Пример подгрузки строки с помощью `Loader`:**
+
+
+
+
+
+```tsx
+import { Loader } from '@consta/uikit/Loader';
+import React from 'react';
+
+import { DataCell } from '@consta/table/DataCell';
+import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [
+ { id: 1, label: 'Item 1' },
+ { id: 2, label: 'Item 2' },
+ { id: 3, label: 'Item 3' },
+ { isLoader: true },
+];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingRowWithLoader = () => {
+ return (
+ (isLoader(row) ? `loader` : `${row.id}`)}
+ />
+ );
+};
+```
+
+
+
+**Пример подгрузки строки с помощью `Skeleton`:**
+
+
+
+
+
+```tsx
+import { Loader } from '@consta/uikit/Loader';
+import { cnMixSpace } from '@consta/uikit/MixSpace';
+import { SkeletonBrick } from '@consta/uikit/Skeleton';
+import React from 'react';
+
+import { DataCell } from '@consta/table/DataCell';
+import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [
+ { id: 1, label: 'Item 1' },
+ { id: 2, label: 'Item 2' },
+ { id: 3, label: 'Item 3' },
+ { isLoader: true },
+];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingRowWithSkeleton = () => {
+ return (
+ (isLoader(row) ? `loader` : `${row.id}`)}
+ />
+ );
+};
+```
+
+
+
+В состоянии загрузки вы можете показывать не только единую строку-заглушку на всю ширину таблицы. При необходимости `Skeleton` можно отрисовывать отдельно в каждой ячейке.
+
+**Пример подгрузки вложенной строки с помощью `Loader`:**
+
+
+
+
+
+```tsx
+import { IconArrowRight } from '@consta/icons/IconArrowRight';
+
+import { Button } from '@consta/uikit/Button';
+import React from 'react';
+
+import { DataCell } from '@consta/table/DataCell';
+import { Table, TableColumn, TableRenderCell } from '@consta/table/Table';
+
+type Item = {
+ id: number;
+ label: string;
+ loading?: boolean;
+};
+
+type Row = Item;
+
+const data: Row[] = [
+ { id: 1, label: 'Item 1' },
+ { id: 2, label: 'Item 2' },
+ { id: 3, label: 'Item 3' },
+ { id: 4, label: 'Item 4', loading: true },
+ { id: 5, label: 'Item 5' },
+ { id: 6, label: 'Item 6' },
+ { id: 7, label: 'Item 7' },
+];
+
+const renderIdCell: TableRenderCell = ({ row }) => (
+
+ }
+ >
+ {row.id}
+
+);
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingNestedRowWithLoader = () => {
+ return (
+ row.id}
+ />
+ );
+};
+```
+
+
+
## Индикатор ячейки и подсказки
Для отображения индикатора используйте свойство `indicator` у компонента `DataCell`. Для вывода подсказок используйте компонент `Popover`. В примере ниже реализована логика показа подсказок по наведению курсора.
diff --git a/src/components/Table/__stand__/examples/TableExampleLoadingDataWithLoader/TableExampleLoadingDataWithLoader.tsx b/src/components/Table/__stand__/examples/TableExampleLoadingDataWithLoader/TableExampleLoadingDataWithLoader.tsx
new file mode 100644
index 0000000..07699a1
--- /dev/null
+++ b/src/components/Table/__stand__/examples/TableExampleLoadingDataWithLoader/TableExampleLoadingDataWithLoader.tsx
@@ -0,0 +1,61 @@
+import { Example } from '@consta/stand';
+import { Loader } from '@consta/uikit/Loader';
+import React from 'react';
+
+import { DataCell } from '##/components/DataCell';
+import { Table, TableColumn, TableRenderCell } from '##/components/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [{ isLoader: true }];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingDataWithLoader = () => {
+ return (
+
+
+
+ );
+};
diff --git a/src/components/Table/__stand__/examples/TableExampleLoadingDataWithSkeleton/TableExampleLoadingDataWithSkeleton.tsx b/src/components/Table/__stand__/examples/TableExampleLoadingDataWithSkeleton/TableExampleLoadingDataWithSkeleton.tsx
new file mode 100644
index 0000000..16b9bc2
--- /dev/null
+++ b/src/components/Table/__stand__/examples/TableExampleLoadingDataWithSkeleton/TableExampleLoadingDataWithSkeleton.tsx
@@ -0,0 +1,67 @@
+import { Example } from '@consta/stand';
+import { Loader } from '@consta/uikit/Loader';
+import { cnMixSpace } from '@consta/uikit/MixSpace';
+import { SkeletonBrick } from '@consta/uikit/Skeleton';
+import React from 'react';
+
+import { DataCell } from '##/components/DataCell';
+import { Table, TableColumn, TableRenderCell } from '##/components/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [
+ { isLoader: true },
+ { isLoader: true },
+ { isLoader: true },
+];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingDataWithSkeleton = () => {
+ return (
+
+
+
+ );
+};
diff --git a/src/components/Table/__stand__/examples/TableExampleLoadingNestedRowWithLoader/TableExampleLoadingNestedRowWithLoader.tsx b/src/components/Table/__stand__/examples/TableExampleLoadingNestedRowWithLoader/TableExampleLoadingNestedRowWithLoader.tsx
new file mode 100644
index 0000000..623df41
--- /dev/null
+++ b/src/components/Table/__stand__/examples/TableExampleLoadingNestedRowWithLoader/TableExampleLoadingNestedRowWithLoader.tsx
@@ -0,0 +1,68 @@
+import { IconArrowRight } from '@consta/icons/IconArrowRight';
+import { Example } from '@consta/stand';
+import { Button } from '@consta/uikit/Button';
+import React from 'react';
+
+import { DataCell } from '##/components/DataCell';
+import { Table, TableColumn, TableRenderCell } from '##/components/Table';
+
+type Item = {
+ id: number;
+ label: string;
+ loading?: boolean;
+};
+
+type Row = Item;
+
+const data: Row[] = [
+ { id: 1, label: 'Item 1' },
+ { id: 2, label: 'Item 2' },
+ { id: 3, label: 'Item 3' },
+ { id: 4, label: 'Item 4', loading: true },
+ { id: 5, label: 'Item 5' },
+ { id: 6, label: 'Item 6' },
+ { id: 7, label: 'Item 7' },
+];
+
+const renderIdCell: TableRenderCell = ({ row }) => (
+
+ }
+ >
+ {row.id}
+
+);
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingNestedRowWithLoader = () => {
+ return (
+
+ row.id}
+ />
+
+ );
+};
diff --git a/src/components/Table/__stand__/examples/TableExampleLoadingRowWithLoader/TableExampleLoadingRowWithLoader.tsx b/src/components/Table/__stand__/examples/TableExampleLoadingRowWithLoader/TableExampleLoadingRowWithLoader.tsx
new file mode 100644
index 0000000..fa49b35
--- /dev/null
+++ b/src/components/Table/__stand__/examples/TableExampleLoadingRowWithLoader/TableExampleLoadingRowWithLoader.tsx
@@ -0,0 +1,67 @@
+import { Example } from '@consta/stand';
+import { Loader } from '@consta/uikit/Loader';
+import React from 'react';
+
+import { DataCell } from '##/components/DataCell';
+import { Table, TableColumn, TableRenderCell } from '##/components/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [
+ { id: 1, label: 'Item 1' },
+ { id: 2, label: 'Item 2' },
+ { id: 3, label: 'Item 3' },
+ { isLoader: true },
+];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingRowWithLoader = () => {
+ return (
+
+ (isLoader(row) ? `loader` : `${row.id}`)}
+ />
+
+ );
+};
diff --git a/src/components/Table/__stand__/examples/TableExampleLoadingRowWithSkeleton/TableExampleLoadingRowWithSkeleton.tsx b/src/components/Table/__stand__/examples/TableExampleLoadingRowWithSkeleton/TableExampleLoadingRowWithSkeleton.tsx
new file mode 100644
index 0000000..2920aad
--- /dev/null
+++ b/src/components/Table/__stand__/examples/TableExampleLoadingRowWithSkeleton/TableExampleLoadingRowWithSkeleton.tsx
@@ -0,0 +1,69 @@
+import { Example } from '@consta/stand';
+import { Loader } from '@consta/uikit/Loader';
+import { cnMixSpace } from '@consta/uikit/MixSpace';
+import { SkeletonBrick } from '@consta/uikit/Skeleton';
+import React from 'react';
+
+import { DataCell } from '##/components/DataCell';
+import { Table, TableColumn, TableRenderCell } from '##/components/Table';
+
+type Item = {
+ id: number;
+ label: string;
+};
+
+type Loader = {
+ isLoader: true;
+};
+
+type Row = Item | Loader;
+
+const data: Row[] = [
+ { id: 1, label: 'Item 1' },
+ { id: 2, label: 'Item 2' },
+ { id: 3, label: 'Item 3' },
+ { isLoader: true },
+];
+
+const isLoader = (arg: Row): arg is Loader =>
+ Object.prototype.hasOwnProperty.call(arg, 'isLoader');
+
+const renderIdCell: TableRenderCell = ({ row }) => {
+ if (isLoader(row)) {
+ return (
+
+
+
+ );
+ }
+ return {row.id};
+};
+
+const columns: TableColumn[] = [
+ {
+ title: 'Номер',
+ accessor: 'id',
+ renderCell: renderIdCell,
+ colSpan: ({ row }) => (isLoader(row) ? 'end' : 1),
+ minWidth: 300,
+ },
+ {
+ title: 'Наименование',
+ accessor: 'label',
+ minWidth: 300,
+ },
+];
+
+export const TableExampleLoadingRowWithSkeleton = () => {
+ return (
+
+ (isLoader(row) ? `loader` : `${row.id}`)}
+ />
+
+ );
+};