@astral/ui 4.45.0 → 4.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/components/ComplianceStatus/ComplianceStatus.d.ts +1 -43
  2. package/components/ComplianceStatus/ComplianceStatus.js +17 -2
  3. package/components/ComplianceStatus/constants.d.ts +14 -0
  4. package/components/ComplianceStatus/constants.js +18 -0
  5. package/components/ComplianceStatus/index.d.ts +2 -1
  6. package/components/ComplianceStatus/index.js +1 -1
  7. package/components/ComplianceStatus/public.d.ts +2 -1
  8. package/components/ComplianceStatus/public.js +1 -1
  9. package/components/ComplianceStatus/styles.d.ts +0 -5
  10. package/components/ComplianceStatus/styles.js +21 -3
  11. package/components/ComplianceStatus/types.d.ts +42 -0
  12. package/components/ComplianceStatus/types.js +1 -0
  13. package/components/DataGrid/Body/Body.d.ts +1 -98
  14. package/components/DataGrid/Body/Body.js +3 -15
  15. package/components/DataGrid/Body/index.d.ts +1 -0
  16. package/components/DataGrid/Body/index.js +1 -0
  17. package/components/DataGrid/Body/types.d.ts +110 -0
  18. package/components/DataGrid/Body/types.js +1 -0
  19. package/components/DataGrid/DataGrid.js +30 -5
  20. package/components/DataGrid/Head/Head.d.ts +4 -0
  21. package/components/DataGrid/Head/Head.js +3 -2
  22. package/components/DataGrid/Loader/Loader.js +2 -2
  23. package/components/DataGrid/Loader/styles.js +4 -2
  24. package/components/DataGrid/PinnedSections/PinnedSections.d.ts +35 -0
  25. package/components/DataGrid/PinnedSections/PinnedSections.js +11 -0
  26. package/components/DataGrid/PinnedSections/Section/Section.d.ts +3 -0
  27. package/components/DataGrid/PinnedSections/Section/Section.js +17 -0
  28. package/components/DataGrid/PinnedSections/Section/index.d.ts +1 -0
  29. package/components/DataGrid/PinnedSections/Section/index.js +1 -0
  30. package/components/DataGrid/PinnedSections/Section/styles.d.ts +5 -0
  31. package/components/DataGrid/PinnedSections/Section/styles.js +100 -0
  32. package/components/DataGrid/PinnedSections/Section/types.d.ts +26 -0
  33. package/components/DataGrid/PinnedSections/Section/types.js +1 -0
  34. package/components/DataGrid/PinnedSections/Section/useLogic/useLogic.d.ts +9 -0
  35. package/components/DataGrid/PinnedSections/Section/useLogic/useLogic.js +16 -0
  36. package/components/DataGrid/PinnedSections/index.d.ts +1 -0
  37. package/components/DataGrid/PinnedSections/index.js +1 -0
  38. package/components/DataGrid/PinnedSections/styles.d.ts +7 -0
  39. package/components/DataGrid/PinnedSections/styles.js +18 -0
  40. package/components/DataGrid/PinnedSections/types.d.ts +5 -0
  41. package/components/DataGrid/PinnedSections/types.js +1 -0
  42. package/components/DataGrid/PinnedSections/useLogic/index.js +1 -0
  43. package/components/DataGrid/PinnedSections/useLogic/useLogic.d.ts +9 -0
  44. package/components/DataGrid/PinnedSections/useLogic/useLogic.js +19 -0
  45. package/components/DataGrid/Row/NestedChildren/NestedChildren.js +2 -2
  46. package/components/DataGrid/Row/Row.d.ts +1 -94
  47. package/components/DataGrid/Row/Row.js +23 -8
  48. package/components/DataGrid/Row/constants.d.ts +3 -1
  49. package/components/DataGrid/Row/constants.js +3 -1
  50. package/components/DataGrid/Row/styles.js +9 -8
  51. package/components/DataGrid/Row/types.d.ts +118 -0
  52. package/components/DataGrid/Row/types.js +1 -0
  53. package/components/DataGrid/Row/useLogic/useLogic.d.ts +3 -2
  54. package/components/DataGrid/Row/useLogic/useLogic.js +14 -2
  55. package/components/DataGrid/constants.d.ts +7 -0
  56. package/components/DataGrid/constants.js +7 -0
  57. package/components/DataGrid/hooks/index.d.ts +1 -0
  58. package/components/DataGrid/hooks/index.js +1 -0
  59. package/components/DataGrid/hooks/useRowHover/index.d.ts +1 -0
  60. package/components/DataGrid/hooks/useRowHover/index.js +1 -0
  61. package/components/DataGrid/hooks/useRowHover/useRowHover.d.ts +15 -0
  62. package/components/DataGrid/hooks/useRowHover/useRowHover.js +93 -0
  63. package/components/DataGrid/styles.js +17 -0
  64. package/components/DataGrid/types.d.ts +4 -0
  65. package/components/DataGrid/useLogic/hooks/index.d.ts +2 -0
  66. package/components/DataGrid/useLogic/hooks/index.js +2 -0
  67. package/components/DataGrid/useLogic/hooks/useClassnames/index.d.ts +1 -0
  68. package/components/DataGrid/useLogic/hooks/useClassnames/index.js +1 -0
  69. package/components/DataGrid/useLogic/hooks/useClassnames/useClassnames.d.ts +12 -0
  70. package/components/DataGrid/useLogic/hooks/useClassnames/useClassnames.js +14 -0
  71. package/components/DataGrid/useLogic/hooks/usePinnedColumns/index.d.ts +1 -0
  72. package/components/DataGrid/useLogic/hooks/usePinnedColumns/index.js +1 -0
  73. package/components/DataGrid/useLogic/hooks/usePinnedColumns/usePinnedColumns.d.ts +18 -0
  74. package/components/DataGrid/useLogic/hooks/usePinnedColumns/usePinnedColumns.js +43 -0
  75. package/components/DataGrid/useLogic/useLogic.d.ts +30 -4
  76. package/components/DataGrid/useLogic/useLogic.js +55 -16
  77. package/components/DataGrid/useLogic/utils/getColumnSections/getColumnSections.d.ts +17 -0
  78. package/components/DataGrid/useLogic/utils/getColumnSections/getColumnSections.js +45 -0
  79. package/components/DataGrid/useLogic/utils/getColumnSections/index.d.ts +1 -0
  80. package/components/DataGrid/useLogic/utils/getColumnSections/index.js +1 -0
  81. package/components/DataGrid/useLogic/utils/index.d.ts +2 -1
  82. package/components/DataGrid/useLogic/utils/index.js +2 -1
  83. package/components/DataGrid/useLogic/utils/syncRowsHeight/index.d.ts +1 -0
  84. package/components/DataGrid/useLogic/utils/syncRowsHeight/index.js +1 -0
  85. package/components/DataGrid/useLogic/utils/syncRowsHeight/syncRowsHeight.d.ts +5 -0
  86. package/components/DataGrid/useLogic/utils/syncRowsHeight/syncRowsHeight.js +21 -0
  87. package/components/DataGrid/utils/index.d.ts +1 -0
  88. package/components/DataGrid/utils/index.js +1 -0
  89. package/components/DataGridInfinite/useLogic/useLogic.js +1 -1
  90. package/node/components/ComplianceStatus/ComplianceStatus.d.ts +1 -43
  91. package/node/components/ComplianceStatus/ComplianceStatus.js +17 -2
  92. package/node/components/ComplianceStatus/constants.d.ts +14 -0
  93. package/node/components/ComplianceStatus/constants.js +21 -0
  94. package/node/components/ComplianceStatus/index.d.ts +2 -1
  95. package/node/components/ComplianceStatus/public.d.ts +2 -1
  96. package/node/components/ComplianceStatus/styles.d.ts +0 -5
  97. package/node/components/ComplianceStatus/styles.js +21 -3
  98. package/node/components/ComplianceStatus/types.d.ts +42 -0
  99. package/node/components/ComplianceStatus/types.js +2 -0
  100. package/node/components/DataGrid/Body/Body.d.ts +1 -98
  101. package/node/components/DataGrid/Body/Body.js +3 -15
  102. package/node/components/DataGrid/Body/index.d.ts +1 -0
  103. package/node/components/DataGrid/Body/index.js +1 -0
  104. package/node/components/DataGrid/Body/types.d.ts +110 -0
  105. package/node/components/DataGrid/Body/types.js +2 -0
  106. package/node/components/DataGrid/DataGrid.js +29 -4
  107. package/node/components/DataGrid/Head/Head.d.ts +4 -0
  108. package/node/components/DataGrid/Head/Head.js +3 -2
  109. package/node/components/DataGrid/Loader/Loader.js +1 -1
  110. package/node/components/DataGrid/Loader/styles.js +4 -2
  111. package/node/components/DataGrid/PinnedSections/PinnedSections.d.ts +35 -0
  112. package/node/components/DataGrid/PinnedSections/PinnedSections.js +15 -0
  113. package/node/components/DataGrid/PinnedSections/Section/Section.d.ts +3 -0
  114. package/node/components/DataGrid/PinnedSections/Section/Section.js +21 -0
  115. package/node/components/DataGrid/PinnedSections/Section/index.d.ts +1 -0
  116. package/node/components/DataGrid/PinnedSections/Section/index.js +17 -0
  117. package/node/components/DataGrid/PinnedSections/Section/styles.d.ts +5 -0
  118. package/node/components/DataGrid/PinnedSections/Section/styles.js +103 -0
  119. package/node/components/DataGrid/PinnedSections/Section/types.d.ts +26 -0
  120. package/node/components/DataGrid/PinnedSections/Section/types.js +2 -0
  121. package/node/components/DataGrid/PinnedSections/Section/useLogic/index.d.ts +1 -0
  122. package/node/components/DataGrid/PinnedSections/Section/useLogic/useLogic.d.ts +9 -0
  123. package/node/components/DataGrid/PinnedSections/Section/useLogic/useLogic.js +20 -0
  124. package/node/components/DataGrid/PinnedSections/index.d.ts +1 -0
  125. package/node/components/DataGrid/PinnedSections/index.js +17 -0
  126. package/node/components/DataGrid/PinnedSections/styles.d.ts +7 -0
  127. package/node/components/DataGrid/PinnedSections/styles.js +21 -0
  128. package/node/components/DataGrid/PinnedSections/types.d.ts +5 -0
  129. package/node/components/DataGrid/PinnedSections/types.js +2 -0
  130. package/node/components/DataGrid/PinnedSections/useLogic/index.d.ts +1 -0
  131. package/node/components/DataGrid/PinnedSections/useLogic/index.js +17 -0
  132. package/node/components/DataGrid/PinnedSections/useLogic/useLogic.d.ts +9 -0
  133. package/node/components/DataGrid/PinnedSections/useLogic/useLogic.js +23 -0
  134. package/node/components/DataGrid/Row/NestedChildren/NestedChildren.js +1 -1
  135. package/node/components/DataGrid/Row/Row.d.ts +1 -94
  136. package/node/components/DataGrid/Row/Row.js +23 -8
  137. package/node/components/DataGrid/Row/constants.d.ts +3 -1
  138. package/node/components/DataGrid/Row/constants.js +4 -2
  139. package/node/components/DataGrid/Row/styles.js +8 -7
  140. package/node/components/DataGrid/Row/types.d.ts +118 -0
  141. package/node/components/DataGrid/Row/types.js +2 -0
  142. package/node/components/DataGrid/Row/useLogic/useLogic.d.ts +3 -2
  143. package/node/components/DataGrid/Row/useLogic/useLogic.js +13 -1
  144. package/node/components/DataGrid/constants.d.ts +7 -0
  145. package/node/components/DataGrid/constants.js +7 -0
  146. package/node/components/DataGrid/hooks/index.d.ts +1 -0
  147. package/node/components/DataGrid/hooks/index.js +17 -0
  148. package/node/components/DataGrid/hooks/useRowHover/index.d.ts +1 -0
  149. package/node/components/DataGrid/hooks/useRowHover/index.js +17 -0
  150. package/node/components/DataGrid/hooks/useRowHover/useRowHover.d.ts +15 -0
  151. package/node/components/DataGrid/hooks/useRowHover/useRowHover.js +97 -0
  152. package/node/components/DataGrid/styles.js +17 -0
  153. package/node/components/DataGrid/types.d.ts +4 -0
  154. package/node/components/DataGrid/useLogic/hooks/index.d.ts +2 -0
  155. package/node/components/DataGrid/useLogic/hooks/index.js +18 -0
  156. package/node/components/DataGrid/useLogic/hooks/useClassnames/index.d.ts +1 -0
  157. package/node/components/DataGrid/useLogic/hooks/useClassnames/index.js +17 -0
  158. package/node/components/DataGrid/useLogic/hooks/useClassnames/useClassnames.d.ts +12 -0
  159. package/node/components/DataGrid/useLogic/hooks/useClassnames/useClassnames.js +18 -0
  160. package/node/components/DataGrid/useLogic/hooks/usePinnedColumns/index.d.ts +1 -0
  161. package/node/components/DataGrid/useLogic/hooks/usePinnedColumns/index.js +17 -0
  162. package/node/components/DataGrid/useLogic/hooks/usePinnedColumns/usePinnedColumns.d.ts +18 -0
  163. package/node/components/DataGrid/useLogic/hooks/usePinnedColumns/usePinnedColumns.js +47 -0
  164. package/node/components/DataGrid/useLogic/useLogic.d.ts +30 -4
  165. package/node/components/DataGrid/useLogic/useLogic.js +53 -14
  166. package/node/components/DataGrid/useLogic/utils/getColumnSections/getColumnSections.d.ts +17 -0
  167. package/node/components/DataGrid/useLogic/utils/getColumnSections/getColumnSections.js +50 -0
  168. package/node/components/DataGrid/useLogic/utils/getColumnSections/index.d.ts +1 -0
  169. package/node/components/DataGrid/useLogic/utils/getColumnSections/index.js +17 -0
  170. package/node/components/DataGrid/useLogic/utils/index.d.ts +2 -1
  171. package/node/components/DataGrid/useLogic/utils/index.js +5 -3
  172. package/node/components/DataGrid/useLogic/utils/syncRowsHeight/index.d.ts +1 -0
  173. package/node/components/DataGrid/useLogic/utils/syncRowsHeight/index.js +17 -0
  174. package/node/components/DataGrid/useLogic/utils/syncRowsHeight/syncRowsHeight.d.ts +5 -0
  175. package/node/components/DataGrid/useLogic/utils/syncRowsHeight/syncRowsHeight.js +25 -0
  176. package/node/components/DataGrid/utils/index.d.ts +1 -0
  177. package/node/components/DataGrid/utils/index.js +3 -1
  178. package/node/components/DataGridInfinite/useLogic/useLogic.js +1 -1
  179. package/package.json +2 -1
  180. package/components/DataGrid/Body/useLogic/useLogic.d.ts +0 -12
  181. package/components/DataGrid/Body/useLogic/useLogic.js +0 -11
  182. package/node/components/DataGrid/Body/useLogic/useLogic.d.ts +0 -12
  183. package/node/components/DataGrid/Body/useLogic/useLogic.js +0 -15
  184. /package/components/DataGrid/{Body → PinnedSections/Section}/useLogic/index.d.ts +0 -0
  185. /package/components/DataGrid/{Body → PinnedSections/Section}/useLogic/index.js +0 -0
  186. /package/{node/components/DataGrid/Body → components/DataGrid/PinnedSections}/useLogic/index.d.ts +0 -0
  187. /package/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/getGridTemplateColumns.d.ts +0 -0
  188. /package/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/getGridTemplateColumns.js +0 -0
  189. /package/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/index.d.ts +0 -0
  190. /package/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/index.js +0 -0
  191. /package/node/components/DataGrid/{Body → PinnedSections/Section}/useLogic/index.js +0 -0
  192. /package/node/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/getGridTemplateColumns.d.ts +0 -0
  193. /package/node/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/getGridTemplateColumns.js +0 -0
  194. /package/node/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/index.d.ts +0 -0
  195. /package/node/components/DataGrid/{useLogic/utils → utils}/getGridTemplateColumns/index.js +0 -0
@@ -1,12 +1,13 @@
1
1
  import { type MouseEvent, type SyntheticEvent } from 'react';
2
2
  import type { CellValue } from '../../types';
3
- import { type RowProps } from '../Row';
3
+ import type { RowProps } from '../types';
4
4
  type UseLogicParams<TData extends Record<string, CellValue>> = RowProps<TData>;
5
- export declare const useLogic: <TData extends Record<string, unknown>>({ keyId, columns, row, nestedChildren, level, variant, activeRowId, options, isInitialExpanded, expandedLevel, isSelectable, selectedRows, onSelectRow, onRowClick, isVisibleCollapseButton, }: UseLogicParams<TData>) => {
5
+ export declare const useLogic: <TData extends Record<string, unknown>>({ keyId, columns, row, nestedChildren, level, variant, activeRowId, options, isInitialExpanded, expandedLevel, isSelectable, selectedRows, onSelectRow, onRowClick, isVisibleCollapseButton, registerRowElement, unregisterRowElement, }: UseLogicParams<TData>) => {
6
6
  isOpen: boolean;
7
7
  isShowConnector: boolean;
8
8
  childrenColumns: any[];
9
9
  rowId: string;
10
+ rowRef: (element: HTMLElement | null) => void;
10
11
  disabled: boolean | undefined;
11
12
  isRenderCollapseButton: boolean;
12
13
  handleToggle: (event: MouseEvent<HTMLButtonElement>) => void;
@@ -1,14 +1,25 @@
1
- import { useContext, useEffect, useMemo, useState, } from 'react';
1
+ import { useContext, useEffect, useMemo, useRef, useState, } from 'react';
2
2
  import { redirectToLink } from '../../../utils/redirectToLink';
3
3
  import { DataGridContext } from '../../DataGridContext';
4
4
  import { Variant } from '../../enums';
5
5
  import { DISABLE_ROW_ATTR } from '../constants';
6
6
  import { RowContext } from '../RowContext';
7
7
  import { mergeColumnsOptions } from './utils';
8
- export const useLogic = ({ keyId, columns, row, nestedChildren, level, variant, activeRowId, options, isInitialExpanded = false, expandedLevel, isSelectable, selectedRows, onSelectRow, onRowClick, isVisibleCollapseButton, }) => {
8
+ export const useLogic = ({ keyId, columns, row, nestedChildren, level, variant, activeRowId, options, isInitialExpanded = false, expandedLevel, isSelectable, selectedRows, onSelectRow, onRowClick, isVisibleCollapseButton, registerRowElement, unregisterRowElement, }) => {
9
9
  const isDefaultExpanded = isInitialExpanded && level <= expandedLevel - 1 && nestedChildren?.length;
10
10
  const { checkIsOpened, toggleOpenItems } = useContext(DataGridContext);
11
11
  const { isDisabled, disabledReason } = useContext(RowContext);
12
+ const savedElementRef = useRef(null);
13
+ const rowRef = (element) => {
14
+ if (element) {
15
+ savedElementRef.current = element;
16
+ registerRowElement?.(rowId, element);
17
+ }
18
+ else if (savedElementRef.current) {
19
+ unregisterRowElement?.(rowId, savedElementRef.current);
20
+ savedElementRef.current = null;
21
+ }
22
+ };
12
23
  const [isVisibleTooltip, setVisibleTooltip] = useState(false);
13
24
  const rowId = row[keyId];
14
25
  const { isDisabled: isExternalDisabled, disabledReason: externalDisabledReason, href, target, } = options || {};
@@ -61,6 +72,7 @@ export const useLogic = ({ keyId, columns, row, nestedChildren, level, variant,
61
72
  isShowConnector,
62
73
  childrenColumns,
63
74
  rowId,
75
+ rowRef,
64
76
  disabled,
65
77
  isRenderCollapseButton,
66
78
  handleToggle,
@@ -9,4 +9,11 @@ export declare const dataGridClassnames: {
9
9
  root: string;
10
10
  body: string;
11
11
  bodyEmpty: string;
12
+ disabled: string;
13
+ pinnedSectionNoData: string;
14
+ dataGridHasPinnedSections: string;
15
+ pinnedSections: string;
16
+ leftPinnedSection: string;
17
+ rightPinnedSection: string;
18
+ overflowed: string;
12
19
  };
@@ -10,4 +10,11 @@ export const dataGridClassnames = {
10
10
  root: createUIKitClassname('data-grid'),
11
11
  body: createUIKitClassname('data-grid__body'),
12
12
  bodyEmpty: createUIKitClassname('data-grid__body_empty'),
13
+ disabled: createUIKitClassname('data-grid_disabled'),
14
+ pinnedSectionNoData: createUIKitClassname('data-grid__pinned-section_no-data'),
15
+ dataGridHasPinnedSections: createUIKitClassname('data-grid_has-pinned-sections'),
16
+ pinnedSections: createUIKitClassname('data-grid__pinned-sections'),
17
+ leftPinnedSection: createUIKitClassname('data-grid__left-pinned-section'),
18
+ rightPinnedSection: createUIKitClassname('data-grid__right-pinned-section'),
19
+ overflowed: createUIKitClassname('data-grid_overflowed'),
13
20
  };
@@ -0,0 +1 @@
1
+ export * from './useRowHover';
@@ -0,0 +1 @@
1
+ export * from './useRowHover';
@@ -0,0 +1 @@
1
+ export * from './useRowHover';
@@ -0,0 +1 @@
1
+ export * from './useRowHover';
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ type UseRowHoverParams = {
3
+ hasPinnedColumns?: boolean;
4
+ };
5
+ /**
6
+ * Хук для синхронизации hover-состояния строк DataGrid через прямую работу с DOM.
7
+ */
8
+ export declare const useRowHover: ({ hasPinnedColumns, }: UseRowHoverParams) => {
9
+ rowsMapRef: import("react").RefObject<Map<string, Set<HTMLElement>>>;
10
+ registerRowElement: (rowId: string, el: HTMLElement) => void;
11
+ unregisterRowElement: (rowId: string, el: HTMLElement) => void;
12
+ onRowEnter: (rowId: string) => void;
13
+ onRowLeave: (rowId: string, e: PointerEvent) => void;
14
+ };
15
+ export {};
@@ -0,0 +1,93 @@
1
+ import { useCallback, useRef } from 'react';
2
+ import { dataGridRowClassnames } from '../../Row/constants';
3
+ /**
4
+ * Хук для синхронизации hover-состояния строк DataGrid через прямую работу с DOM.
5
+ */
6
+ export const useRowHover = ({ hasPinnedColumns = false, }) => {
7
+ const rowsMapRef = useRef(new Map());
8
+ const hoveredRowIdRef = useRef(null);
9
+ const highlight = useCallback((rowId) => {
10
+ if (!hasPinnedColumns) {
11
+ return;
12
+ }
13
+ const elements = rowsMapRef.current.get(rowId);
14
+ if (!elements) {
15
+ return;
16
+ }
17
+ elements.forEach((el) => {
18
+ if (!el.classList.contains(dataGridRowClassnames.hover)) {
19
+ el.classList.add(dataGridRowClassnames.hover);
20
+ }
21
+ });
22
+ }, [hasPinnedColumns]);
23
+ const unhighlight = useCallback((rowId) => {
24
+ if (!hasPinnedColumns) {
25
+ return;
26
+ }
27
+ const elements = rowsMapRef.current.get(rowId);
28
+ if (!elements) {
29
+ return;
30
+ }
31
+ elements.forEach((el) => el.classList.remove(dataGridRowClassnames.hover));
32
+ return;
33
+ }, [hasPinnedColumns]);
34
+ const registerRowElement = useCallback((rowId, el) => {
35
+ if (!hasPinnedColumns) {
36
+ return;
37
+ }
38
+ const map = rowsMapRef.current;
39
+ if (!map.has(rowId)) {
40
+ map.set(rowId, new Set());
41
+ }
42
+ map.get(rowId).add(el);
43
+ }, [hasPinnedColumns]);
44
+ const unregisterRowElement = useCallback((rowId, el) => {
45
+ if (!hasPinnedColumns) {
46
+ return;
47
+ }
48
+ const map = rowsMapRef.current;
49
+ const set = map.get(rowId);
50
+ if (!set) {
51
+ return;
52
+ }
53
+ set.delete(el);
54
+ if (set.size === 0) {
55
+ map.delete(rowId);
56
+ }
57
+ }, [hasPinnedColumns]);
58
+ const onRowEnter = useCallback((rowId) => {
59
+ if (!hasPinnedColumns) {
60
+ return;
61
+ }
62
+ if (hoveredRowIdRef.current === rowId) {
63
+ return;
64
+ }
65
+ if (hoveredRowIdRef.current) {
66
+ unhighlight(hoveredRowIdRef.current);
67
+ }
68
+ highlight(rowId);
69
+ hoveredRowIdRef.current = rowId;
70
+ }, [hasPinnedColumns, highlight, unhighlight]);
71
+ /**
72
+ * Обрабатывает уход курсора со строки.
73
+ * Убирает hover, если курсор действительно покинул строку.
74
+ */
75
+ const onRowLeave = useCallback((rowId, e) => {
76
+ if (!hasPinnedColumns) {
77
+ return;
78
+ }
79
+ const next = e.relatedTarget;
80
+ if (next?.closest(`[data-row-id="${rowId}"]`)) {
81
+ return;
82
+ }
83
+ unhighlight(rowId);
84
+ hoveredRowIdRef.current = null;
85
+ }, [hasPinnedColumns, unhighlight]);
86
+ return {
87
+ rowsMapRef,
88
+ registerRowElement,
89
+ unregisterRowElement,
90
+ onRowEnter,
91
+ onRowLeave,
92
+ };
93
+ };
@@ -1,4 +1,5 @@
1
1
  import { styled } from '../styled';
2
+ import { dataGridClassnames } from './constants';
2
3
  export const Container = styled('div', {
3
4
  shouldForwardProp: (prop) => !['$maxHeight', '$isAllowHorizontalScroll'].includes(prop),
4
5
  }) `
@@ -11,6 +12,22 @@ export const Container = styled('div', {
11
12
  width: 100%;
12
13
  height: 100%;
13
14
  max-height: ${({ $maxHeight }) => $maxHeight ? `${$maxHeight}px` : 'initial'};
15
+
16
+ &.${dataGridClassnames.dataGridHasPinnedSections} {
17
+ overflow: hidden;
18
+ }
19
+
20
+ @supports not (container-type: scroll-state) {
21
+ &.${dataGridClassnames.overflowed} {
22
+ & .${dataGridClassnames.rightPinnedSection} {
23
+ box-shadow: -3px 0 4px 0 #63636326;
24
+ }
25
+
26
+ & .${dataGridClassnames.leftPinnedSection} {
27
+ box-shadow: 3px 0 4px 0 #63636326;
28
+ }
29
+ }
30
+ }
14
31
  `;
15
32
  export const DataGridWrapper = styled('div', {
16
33
  shouldForwardProp: (prop) => !['$isAllowHorizontalScroll'].includes(prop),
@@ -232,6 +232,10 @@ export type DataGridColumns<TData extends Record<string, CellValue>> = {
232
232
  * Принимает компонент DataGridColumnHintIcon - подсказка в шапке колонки
233
233
  */
234
234
  columnHint?: ReactNode;
235
+ /**
236
+ * Закрепление колонки в таблице
237
+ */
238
+ pinned?: 'left' | 'right';
235
239
  };
236
240
  export type DataGridRowOptionColumns<TData extends Record<string, CellValue>> = {
237
241
  /**
@@ -0,0 +1,2 @@
1
+ export * from './usePinnedColumns';
2
+ export * from './useClassnames';
@@ -0,0 +1,2 @@
1
+ export * from './usePinnedColumns';
2
+ export * from './useClassnames';
@@ -0,0 +1 @@
1
+ export * from './useClassnames';
@@ -0,0 +1 @@
1
+ export * from './useClassnames';
@@ -0,0 +1,12 @@
1
+ type UseClassnamesParams = {
2
+ isDataGridDisabled?: boolean;
3
+ dataGridClassName?: string;
4
+ hasPinnedColumns?: boolean;
5
+ isNoData?: boolean;
6
+ };
7
+ export declare const useClassnames: ({ isDataGridDisabled, dataGridClassName, hasPinnedColumns, isNoData, }: UseClassnamesParams) => {
8
+ pinnedSectionsClassname: string;
9
+ dataGridClassname: string;
10
+ bodyClassName: string;
11
+ };
12
+ export {};
@@ -0,0 +1,14 @@
1
+ import { classNames } from '../../../../utils/classNames';
2
+ import { dataGridClassnames } from '../../../constants';
3
+ export const useClassnames = ({ isDataGridDisabled, dataGridClassName, hasPinnedColumns, isNoData, }) => {
4
+ const pinnedSectionsClassname = classNames(dataGridClassnames.pinnedSections, {
5
+ [dataGridClassnames.disabled]: isDataGridDisabled,
6
+ });
7
+ const dataGridClassname = classNames(dataGridClassnames.root, dataGridClassName, {
8
+ [dataGridClassnames.dataGridHasPinnedSections]: hasPinnedColumns,
9
+ });
10
+ const bodyClassName = classNames(dataGridClassnames.body, {
11
+ [dataGridClassnames.bodyEmpty]: isNoData,
12
+ });
13
+ return { pinnedSectionsClassname, dataGridClassname, bodyClassName };
14
+ };
@@ -0,0 +1 @@
1
+ export * from './usePinnedColumns';
@@ -0,0 +1 @@
1
+ export * from './usePinnedColumns';
@@ -0,0 +1,18 @@
1
+ /// <reference types="react" />
2
+ import { type CellValue, type DataGridColumns, type DataGridRow } from '../../../types';
3
+ type UsePinnedColumnsParams<TData extends Record<string, CellValue> = DataGridRow> = {
4
+ isLoading?: boolean;
5
+ columns: DataGridColumns<TData>[];
6
+ };
7
+ export declare const usePinnedColumns: <TData extends Record<string, unknown> = DataGridRow>({ isLoading, columns, }: UsePinnedColumnsParams<TData>) => {
8
+ containerRef: import("react").RefObject<HTMLDivElement | null>;
9
+ rowHoverProps: {
10
+ registerRowElement: (rowId: string, el: HTMLElement) => void;
11
+ unregisterRowElement: (rowId: string, el: HTMLElement) => void;
12
+ onRowEnter: (rowId: string) => void;
13
+ onRowLeave: (rowId: string, e: PointerEvent) => void;
14
+ };
15
+ sections: import("../../../PinnedSections/types").PinnedSection<TData>[];
16
+ hasPinnedColumns: boolean;
17
+ };
18
+ export {};
@@ -0,0 +1,43 @@
1
+ import { useCallback, useLayoutEffect, useMemo, useRef } from 'react';
2
+ import { dataGridClassnames } from '../../../constants';
3
+ import { useRowHover } from '../../../hooks/useRowHover';
4
+ import { getColumnSections } from '../../utils/getColumnSections';
5
+ import { syncRowsHeight } from '../../utils/syncRowsHeight';
6
+ export const usePinnedColumns = ({ isLoading, columns, }) => {
7
+ const containerRef = useRef(null);
8
+ const hasPinnedColumns = useMemo(() => columns.some((column) => column.pinned), [columns]);
9
+ const { rowsMapRef, ...rowHoverProps } = useRowHover({ hasPinnedColumns });
10
+ const isScrollStateSupported = CSS.supports('container-type', 'scroll-state');
11
+ const checkOverflow = useCallback((element) => {
12
+ if (element) {
13
+ return element.scrollWidth > element.clientWidth;
14
+ }
15
+ return false;
16
+ }, []);
17
+ const { sections } = useMemo(() => getColumnSections(columns), [columns]);
18
+ useLayoutEffect(() => {
19
+ if (isLoading || !hasPinnedColumns || typeof window === 'undefined') {
20
+ return;
21
+ }
22
+ const resizeObserver = new ResizeObserver(() => {
23
+ syncRowsHeight(rowsMapRef.current);
24
+ if (isScrollStateSupported) {
25
+ return;
26
+ }
27
+ if (checkOverflow(containerRef.current)) {
28
+ containerRef.current?.classList.add(dataGridClassnames.overflowed);
29
+ }
30
+ else {
31
+ containerRef.current?.classList.remove(dataGridClassnames.overflowed);
32
+ }
33
+ });
34
+ if (!containerRef.current) {
35
+ return;
36
+ }
37
+ resizeObserver.observe(containerRef.current);
38
+ return () => {
39
+ resizeObserver.disconnect();
40
+ };
41
+ }, [hasPinnedColumns, isLoading]);
42
+ return { containerRef, rowHoverProps, sections, hasPinnedColumns };
43
+ };
@@ -1,7 +1,9 @@
1
1
  import { type ChangeEvent } from 'react';
2
2
  import type { CellValue, DataGridProps, DataGridRow } from '../types';
3
3
  type UseLogicParams<TData extends Record<string, CellValue> = DataGridRow, TSortField extends keyof TData = keyof TData> = DataGridProps<TData, TSortField>;
4
- export declare const useLogic: <TData extends Record<string, unknown> = DataGridRow, TSortField extends keyof TData = keyof TData>({ keyId, columns, rows, variant, tree, subrows, selectedRows, isLoading, isDisabled, onSelectRow, isHideSelectAll, isHideHeaderIfNoData, }: UseLogicParams<TData, TSortField>) => {
4
+ export declare const useLogic: <TData extends Record<string, unknown> = DataGridRow, TSortField extends keyof TData = keyof TData>({ keyId, columns, rows, variant, tree, subrows, selectedRows, isLoading, isDisabled, onSelectRow, isError, onRetry, errorMsg, isHideSelectAll, isHideHeaderIfNoData, sorting, className, onSort, }: UseLogicParams<TData, TSortField>) => {
5
+ pinnedSectionsClassname: string;
6
+ dataGridClassname: string;
5
7
  isDataGridDisabled: boolean | undefined;
6
8
  treeRenderConfig: {
7
9
  isInitialExpanded?: boolean | undefined;
@@ -11,20 +13,44 @@ export declare const useLogic: <TData extends Record<string, unknown> = DataGrid
11
13
  renderRows: TData[];
12
14
  isAllowHorizontalScroll: boolean;
13
15
  isHideHead: boolean;
16
+ hasPinnedColumns: boolean;
17
+ contentStateProps: {
18
+ isLoading: boolean | undefined;
19
+ isError: boolean | undefined;
20
+ loadingTitle: string;
21
+ errorState: {
22
+ imgAlt: string;
23
+ errorList: string[];
24
+ imgSrc: string;
25
+ onRetry: () => void;
26
+ };
27
+ isSmoothLoading: boolean;
28
+ };
29
+ rowHoverProps: {
30
+ registerRowElement: (rowId: string, el: HTMLElement) => void;
31
+ unregisterRowElement: (rowId: string, el: HTMLElement) => void;
32
+ onRowEnter: (rowId: string) => void;
33
+ onRowLeave: (rowId: string, e: PointerEvent) => void;
34
+ };
35
+ containerRef: import("react").RefObject<HTMLDivElement | null>;
36
+ gridColumns: string;
37
+ isNoData: boolean;
38
+ headColumns: import("../types").DataGridColumns<TData>[];
14
39
  headProps: {
15
40
  rowsCount: number;
16
41
  uncheckedRowsCount: number;
17
- gridColumns: string;
18
42
  isSelectable: boolean;
19
- columns: import("../types").DataGridColumns<TData>[];
20
43
  onSelectAllRows: (event: ChangeEvent<HTMLInputElement>) => void;
21
44
  isHideSelectAll: boolean | undefined;
45
+ sorting: import("../types").DataGridSort<TSortField> | undefined;
46
+ onSort: ((sorting: import("../types").DataGridSort<TSortField> | undefined) => void) | undefined;
22
47
  };
23
48
  bodyProps: {
24
- gridColumns: string;
25
49
  isSelectable: boolean;
26
50
  onSelectRow: (row: TData) => (event: ChangeEvent<HTMLInputElement>) => void;
27
51
  };
52
+ bodyClassName: string;
53
+ sections: import("../PinnedSections/types").PinnedSection<TData>[];
28
54
  loaderProps: {
29
55
  isLoading: boolean | undefined;
30
56
  isVisibleDivider: boolean;
@@ -1,33 +1,28 @@
1
- import { useCallback, useEffect, useMemo, useRef, } from 'react';
1
+ import { useCallback, useContext, useEffect, useMemo, useRef, } from 'react';
2
+ import { ConfigContext } from '../../ConfigProvider';
2
3
  import { useFirstMountState } from '../../useFirstMountState';
3
4
  import { prop } from '../../utils/prop';
4
5
  import { uniqueBy } from '../../utils/uniqueBy';
5
6
  import { Variant } from '../enums';
6
- import { getGridTemplateColumns, getIsAllowHorizontalScroll } from './utils';
7
- export const useLogic = ({ keyId, columns, rows = [], variant, tree, subrows, selectedRows = [], isLoading, isDisabled, onSelectRow, isHideSelectAll, isHideHeaderIfNoData = false, }) => {
7
+ import { getGridTemplateColumns } from '../utils/getGridTemplateColumns';
8
+ import { useClassnames, usePinnedColumns } from './hooks';
9
+ import { getIsAllowHorizontalScroll } from './utils';
10
+ export const useLogic = ({ keyId, columns, rows = [], variant, tree, subrows, selectedRows = [], isLoading, isDisabled, onSelectRow, isError, onRetry, errorMsg, isHideSelectAll, isHideHeaderIfNoData = false, sorting, className, onSort, }) => {
8
11
  const isFirstRender = useFirstMountState();
9
12
  const isSelectable = Boolean(onSelectRow);
10
13
  const isDataGridDisabled = isLoading || isDisabled;
14
+ const { imagesMap } = useContext(ConfigContext);
11
15
  // Реф добавлен для избежания замыкания selectedRows в handleSelectRow (иначе в handleSelectRow приходят некорректные значения selectedRows).
12
16
  const selectedRowsRef = useRef(selectedRows);
13
17
  useEffect(() => {
14
18
  selectedRowsRef.current = selectedRows;
15
19
  }, [selectedRows]);
16
- const treeRenderConfig = Object.is(variant, Variant.Subrows)
17
- ? { ...subrows, isInitialExpanded: true }
18
- : tree;
19
- const availableRows = rows.filter((row) => !(row.options?.isDisabled || row.options?.isNotSelectable));
20
20
  const prevRowsRef = useRef([]);
21
21
  useEffect(() => {
22
22
  if (!isLoading) {
23
23
  prevRowsRef.current = rows;
24
24
  }
25
25
  }, [rows, isLoading]);
26
- const gridColumns = getGridTemplateColumns(columns);
27
- const isAllowHorizontalScroll = getIsAllowHorizontalScroll(columns);
28
- const uncheckedRowsCount = useMemo(() => {
29
- return availableRows.filter((row) => !selectedRows.find((selectedRow) => selectedRow[keyId] === row[keyId])).length;
30
- }, [availableRows, selectedRows, keyId]);
31
26
  const processedColumns = useCallback(() => {
32
27
  if (rows.length <= 1) {
33
28
  return columns.map((column) => ({ ...column, sortable: false }));
@@ -35,6 +30,26 @@ export const useLogic = ({ keyId, columns, rows = [], variant, tree, subrows, se
35
30
  return columns;
36
31
  }, [columns, rows]);
37
32
  const renderRows = isLoading ? prevRowsRef.current : rows;
33
+ const isNoData = !renderRows.length;
34
+ const { containerRef, rowHoverProps, sections, hasPinnedColumns } = usePinnedColumns({
35
+ isLoading,
36
+ columns: processedColumns(),
37
+ });
38
+ const { pinnedSectionsClassname, dataGridClassname, bodyClassName } = useClassnames({
39
+ isDataGridDisabled,
40
+ dataGridClassName: className,
41
+ hasPinnedColumns,
42
+ isNoData,
43
+ });
44
+ const treeRenderConfig = Object.is(variant, Variant.Subrows)
45
+ ? { ...subrows, isInitialExpanded: true }
46
+ : tree;
47
+ const availableRows = rows.filter((row) => !(row.options?.isDisabled || row.options?.isNotSelectable));
48
+ const gridColumns = getGridTemplateColumns(columns);
49
+ const isAllowHorizontalScroll = getIsAllowHorizontalScroll(columns);
50
+ const uncheckedRowsCount = useMemo(() => {
51
+ return availableRows.filter((row) => !selectedRows.find((selectedRow) => selectedRow[keyId] === row[keyId])).length;
52
+ }, [availableRows, selectedRows, keyId]);
38
53
  const handleSelectAllRows = (event) => {
39
54
  if (!onSelectRow) {
40
55
  return;
@@ -55,27 +70,51 @@ export const useLogic = ({ keyId, columns, rows = [], variant, tree, subrows, se
55
70
  }
56
71
  onSelectRow(selectedRowsRef.current.filter((selectedRow) => selectedRow[keyId] !== row[keyId]));
57
72
  };
58
- const isHideHead = isHideHeaderIfNoData && rows.length === 0;
73
+ const isHideHead = isHideHeaderIfNoData && isNoData;
74
+ const contentStateProps = useMemo(() => {
75
+ return {
76
+ isLoading: isLoading && isNoData,
77
+ isError: isError && isNoData,
78
+ loadingTitle: 'Загрузка данных',
79
+ errorState: {
80
+ imgAlt: 'Что-то пошло не так',
81
+ errorList: [errorMsg || ''],
82
+ imgSrc: imagesMap.defaultErrorImgSrc,
83
+ onRetry,
84
+ },
85
+ isSmoothLoading: false,
86
+ };
87
+ }, [isLoading, isError, isNoData, errorMsg, onRetry, imagesMap]);
59
88
  return {
89
+ pinnedSectionsClassname,
90
+ dataGridClassname,
60
91
  isDataGridDisabled,
61
92
  treeRenderConfig,
62
93
  renderRows,
63
94
  isAllowHorizontalScroll,
64
95
  isHideHead,
96
+ hasPinnedColumns,
97
+ contentStateProps,
98
+ rowHoverProps,
99
+ containerRef,
100
+ gridColumns,
101
+ isNoData,
102
+ headColumns: processedColumns(),
65
103
  headProps: {
66
104
  rowsCount: availableRows.length,
67
105
  uncheckedRowsCount,
68
- gridColumns,
69
106
  isSelectable,
70
- columns: processedColumns(),
71
107
  onSelectAllRows: handleSelectAllRows,
72
108
  isHideSelectAll,
109
+ sorting,
110
+ onSort,
73
111
  },
74
112
  bodyProps: {
75
- gridColumns,
76
113
  isSelectable,
77
114
  onSelectRow: handleSelectRow,
78
115
  },
116
+ bodyClassName,
117
+ sections,
79
118
  loaderProps: {
80
119
  isLoading: !isFirstRender && isLoading,
81
120
  isVisibleDivider: Boolean(rows.length),
@@ -0,0 +1,17 @@
1
+ import type { PinnedSection } from '../../../PinnedSections/types';
2
+ import type { DataGridColumns, DataGridRow } from '../../../types';
3
+ /**
4
+ * Валидирует корректность комбинаций закрепления колонок.
5
+ * Выбрасывает ошибку, если колонки с pinned="right" не идут непрерывным блоком в конце
6
+ * или колонки с pinned="left" не идут непрерывным блоком в начале.
7
+ */
8
+ export declare const validatePinnedColumns: (positions: ('left' | 'right' | 'center')[]) => void;
9
+ /**
10
+ * Группирует колонки DataGrid по закреплённым позициям (pinned):
11
+ * - left (закреплены слева)
12
+ * - center (обычные, не закреплённые)
13
+ * - right (закреплены справа)
14
+ */
15
+ export declare const getColumnSections: <TData extends Record<string, unknown> = DataGridRow>(columns: DataGridColumns<TData>[]) => {
16
+ sections: PinnedSection<TData>[];
17
+ };
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Валидирует корректность комбинаций закрепления колонок.
3
+ * Выбрасывает ошибку, если колонки с pinned="right" не идут непрерывным блоком в конце
4
+ * или колонки с pinned="left" не идут непрерывным блоком в начале.
5
+ */
6
+ export const validatePinnedColumns = (positions) => {
7
+ const firstRight = positions.indexOf('right');
8
+ if (firstRight !== -1 &&
9
+ positions.slice(firstRight).some((p) => p !== 'right')) {
10
+ // biome-ignore lint/suspicious/noConsole: Сообщение для интеграторов
11
+ console.error('DataGrid: Колонки с pinned="right" должны идти непрерывным блоком в конце');
12
+ }
13
+ // left: должны быть в начале
14
+ const lastLeft = positions.lastIndexOf('left');
15
+ if (lastLeft !== -1 &&
16
+ positions.slice(0, lastLeft + 1).some((p) => p !== 'left')) {
17
+ // biome-ignore lint/suspicious/noConsole: Сообщение для интеграторов
18
+ console.error('DataGrid: Колонки с pinned="left" должны идти непрерывным блоком в начале');
19
+ }
20
+ };
21
+ /**
22
+ * Группирует колонки DataGrid по закреплённым позициям (pinned):
23
+ * - left (закреплены слева)
24
+ * - center (обычные, не закреплённые)
25
+ * - right (закреплены справа)
26
+ */
27
+ export const getColumnSections = (columns) => {
28
+ const groups = columns.reduce((acc, col) => {
29
+ const position = col.pinned ?? 'center';
30
+ if (!acc[position]) {
31
+ acc[position] = [];
32
+ }
33
+ acc[position].push(col);
34
+ return acc;
35
+ }, {});
36
+ const positions = columns.map((c) => c.pinned ?? 'center');
37
+ validatePinnedColumns(positions);
38
+ return {
39
+ sections: [
40
+ { position: 'left', columns: groups.left },
41
+ { position: 'center', columns: groups.center },
42
+ { position: 'right', columns: groups.right },
43
+ ],
44
+ };
45
+ };
@@ -0,0 +1 @@
1
+ export * from './getColumnSections';
@@ -0,0 +1 @@
1
+ export * from './getColumnSections';
@@ -1,2 +1,3 @@
1
- export { getGridTemplateColumns } from './getGridTemplateColumns';
2
1
  export { getIsAllowHorizontalScroll } from './getIsAllowHorizontalScroll';
2
+ export { syncRowsHeight } from './syncRowsHeight';
3
+ export { getColumnSections } from './getColumnSections';
@@ -1,2 +1,3 @@
1
- export { getGridTemplateColumns } from './getGridTemplateColumns';
2
1
  export { getIsAllowHorizontalScroll } from './getIsAllowHorizontalScroll';
2
+ export { syncRowsHeight } from './syncRowsHeight';
3
+ export { getColumnSections } from './getColumnSections';
@@ -0,0 +1 @@
1
+ export * from './syncRowsHeight';
@@ -0,0 +1 @@
1
+ export * from './syncRowsHeight';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Синхронизирует высоту строк DataGrid на основе высоты их содержимого.
3
+ * Каждая строка устанавливает высоту равной максимальной высоте всех своих ячеек.
4
+ */
5
+ export declare const syncRowsHeight: (rowsMap: Map<string, Set<HTMLElement>>) => void;