@bit.rhplus/ag-grid 0.0.76 → 0.0.78

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 (73) hide show
  1. package/AgGridColumn.js +35 -5
  2. package/BulkEdit/BulkEditButton.jsx +11 -1
  3. package/BulkEdit/BulkEditDatePicker.jsx +10 -1
  4. package/BulkEdit/BulkEditInput.jsx +10 -1
  5. package/BulkEdit/BulkEditModule.jsx +10 -1
  6. package/BulkEdit/BulkEditPopover.jsx +10 -1
  7. package/BulkEdit/BulkEditSelect.jsx +10 -1
  8. package/Renderers/BooleanRenderer.jsx +10 -1
  9. package/Renderers/ButtonRenderer.jsx +16 -2
  10. package/Renderers/CheckboxRenderer.jsx +22 -9
  11. package/Renderers/CountrySelectRenderer.jsx +62 -14
  12. package/Renderers/IconRenderer.jsx +10 -1
  13. package/Renderers/ImageRenderer.jsx +13 -2
  14. package/Renderers/LinkRenderer.jsx +132 -0
  15. package/Renderers/ObjectRenderer.jsx +139 -0
  16. package/Renderers/SelectRenderer.jsx +76 -9
  17. package/Renderers/StateRenderer.jsx +10 -1
  18. package/dist/AgGridColumn.js +35 -5
  19. package/dist/AgGridColumn.js.map +1 -1
  20. package/dist/BulkEdit/BulkEditButton.d.ts +4 -17
  21. package/dist/BulkEdit/BulkEditButton.js +5 -1
  22. package/dist/BulkEdit/BulkEditButton.js.map +1 -1
  23. package/dist/BulkEdit/BulkEditDatePicker.d.ts +4 -3
  24. package/dist/BulkEdit/BulkEditDatePicker.js +6 -1
  25. package/dist/BulkEdit/BulkEditDatePicker.js.map +1 -1
  26. package/dist/BulkEdit/BulkEditInput.d.ts +4 -3
  27. package/dist/BulkEdit/BulkEditInput.js +6 -1
  28. package/dist/BulkEdit/BulkEditInput.js.map +1 -1
  29. package/dist/BulkEdit/BulkEditModule.d.ts +4 -3
  30. package/dist/BulkEdit/BulkEditModule.js +6 -1
  31. package/dist/BulkEdit/BulkEditModule.js.map +1 -1
  32. package/dist/BulkEdit/BulkEditPopover.d.ts +4 -17
  33. package/dist/BulkEdit/BulkEditPopover.js +4 -1
  34. package/dist/BulkEdit/BulkEditPopover.js.map +1 -1
  35. package/dist/BulkEdit/BulkEditSelect.d.ts +4 -3
  36. package/dist/BulkEdit/BulkEditSelect.js +6 -1
  37. package/dist/BulkEdit/BulkEditSelect.js.map +1 -1
  38. package/dist/Renderers/BooleanRenderer.d.ts +1 -2
  39. package/dist/Renderers/BooleanRenderer.js +4 -1
  40. package/dist/Renderers/BooleanRenderer.js.map +1 -1
  41. package/dist/Renderers/ButtonRenderer.d.ts +1 -2
  42. package/dist/Renderers/ButtonRenderer.js +9 -2
  43. package/dist/Renderers/ButtonRenderer.js.map +1 -1
  44. package/dist/Renderers/CheckboxRenderer.d.ts +4 -1
  45. package/dist/Renderers/CheckboxRenderer.js +17 -7
  46. package/dist/Renderers/CheckboxRenderer.js.map +1 -1
  47. package/dist/Renderers/CountrySelectRenderer.d.ts +4 -1
  48. package/dist/Renderers/CountrySelectRenderer.js +40 -11
  49. package/dist/Renderers/CountrySelectRenderer.js.map +1 -1
  50. package/dist/Renderers/IconRenderer.d.ts +1 -2
  51. package/dist/Renderers/IconRenderer.js +4 -1
  52. package/dist/Renderers/IconRenderer.js.map +1 -1
  53. package/dist/Renderers/ImageRenderer.d.ts +1 -2
  54. package/dist/Renderers/ImageRenderer.js +5 -1
  55. package/dist/Renderers/ImageRenderer.js.map +1 -1
  56. package/dist/Renderers/LinkRenderer.d.ts +3 -0
  57. package/dist/Renderers/LinkRenderer.js +75 -0
  58. package/dist/Renderers/LinkRenderer.js.map +1 -0
  59. package/dist/Renderers/ObjectRenderer.d.ts +3 -0
  60. package/dist/Renderers/ObjectRenderer.js +78 -0
  61. package/dist/Renderers/ObjectRenderer.js.map +1 -0
  62. package/dist/Renderers/SelectRenderer.d.ts +1 -2
  63. package/dist/Renderers/SelectRenderer.js +51 -9
  64. package/dist/Renderers/SelectRenderer.js.map +1 -1
  65. package/dist/Renderers/StateRenderer.d.ts +1 -2
  66. package/dist/Renderers/StateRenderer.js +4 -1
  67. package/dist/Renderers/StateRenderer.js.map +1 -1
  68. package/dist/index.d.ts +2 -2
  69. package/dist/index.js +196 -66
  70. package/dist/index.js.map +1 -1
  71. package/index.jsx +218 -66
  72. package/package.json +8 -7
  73. /package/dist/{preview-1768297732386.js → preview-1768388646791.js} +0 -0
package/AgGridColumn.js CHANGED
@@ -21,20 +21,50 @@ export const AgGridColumn = (column, options) => {
21
21
  (data.value && moment(data.value).format(column.dateRenderer)) || "";
22
22
  }
23
23
 
24
- if (column.booleanRenderer)
24
+ if (column.booleanRenderer) {
25
25
  column.cellRenderer = "booleanRenderer";
26
+ // AG-Grid deferRender: odkládá rendering během scrollování pro lepší výkon
27
+ column.cellRendererParams = {
28
+ ...column.booleanRendererParams,
29
+ deferRender: true
30
+ };
31
+ }
26
32
 
27
- if (column.iconRenderer)
33
+ if (column.iconRenderer) {
28
34
  column.cellRenderer = "iconRenderer";
35
+ // AG-Grid deferRender: odkládá rendering během scrollování pro lepší výkon
36
+ column.cellRendererParams = {
37
+ ...column.iconRendererParams,
38
+ deferRender: true
39
+ };
40
+ }
29
41
 
30
- if (column.imageRenderer)
42
+ if (column.imageRenderer) {
31
43
  column.cellRenderer = "imageRenderer";
44
+ // AG-Grid deferRender: odkládá rendering během scrollování pro lepší výkon
45
+ column.cellRendererParams = {
46
+ ...column.imageRendererParams,
47
+ deferRender: true
48
+ };
49
+ }
32
50
 
33
- if (column.stateRenderer)
51
+ if (column.stateRenderer) {
34
52
  column.cellRenderer = "stateRenderer";
53
+ // AG-Grid deferRender: odkládá rendering během scrollování pro lepší výkon
54
+ column.cellRendererParams = {
55
+ ...column.stateRendererParams,
56
+ deferRender: true
57
+ };
58
+ }
35
59
 
36
- if (column.buttonRenderer)
60
+ if (column.buttonRenderer) {
37
61
  column.cellRenderer = "buttonRenderer";
62
+ // AG-Grid deferRender: odkládá rendering během scrollování pro lepší výkon
63
+ column.cellRendererParams = {
64
+ ...column.buttonRendererParams,
65
+ deferRender: true
66
+ };
67
+ }
38
68
 
39
69
  if (column.headerHtmlText) {
40
70
  column.headerComponentParams = {
@@ -4,6 +4,7 @@ import ReactDOM from 'react-dom';
4
4
  import { Button, Tooltip } from 'antd';
5
5
  import { EditOutlined } from '@ant-design/icons';
6
6
  import BulkEditPopover from './BulkEditPopover';
7
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
7
8
 
8
9
  /**
9
10
  * Floating button komponenta pro bulk edit
@@ -209,4 +210,13 @@ const BulkEditButton = ({
209
210
  );
210
211
  };
211
212
 
212
- export default BulkEditButton;
213
+ // React.memo optimalizace - rerender pouze při změně kritických props
214
+ // Callback změny (onOpenPopover, onValueChange, onSubmit, onCancel) ignorujeme
215
+ const arePropsEqual = createMemoComparison(
216
+ ['visible', 'position', 'range', 'column', 'cellCount', 'rowsContainer', 'editPopover'],
217
+ ['onOpenPopover', 'onValueChange', 'onSubmit', 'onCancel'],
218
+ false,
219
+ 'BulkEditButton'
220
+ );
221
+
222
+ export default React.memo(BulkEditButton, arePropsEqual);
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable */
2
2
  import React, { useState, useCallback, useMemo } from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
3
4
  import { Calendar, Button, Space, Tooltip } from 'antd';
4
5
  import dayjs from 'dayjs';
5
6
  import 'dayjs/locale/cs';
@@ -292,4 +293,12 @@ const BulkEditDatePicker = ({
292
293
  );
293
294
  };
294
295
 
295
- export default BulkEditDatePicker;
296
+ // React.memo optimalizace
297
+ const arePropsEqual = createMemoComparison(
298
+ [], // všechny props jsou kritické
299
+ [], // žádné ignorované
300
+ false,
301
+ 'BulkEditDatePicker'
302
+ );
303
+
304
+ export default React.memo(BulkEditDatePicker, arePropsEqual);
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable */
2
2
  import React, { useRef, useEffect } from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
3
4
  import { Input, Button, Space } from 'antd';
4
5
 
5
6
  const BulkEditInput = ({
@@ -68,4 +69,12 @@ const BulkEditInput = ({
68
69
  );
69
70
  };
70
71
 
71
- export default BulkEditInput;
72
+ // React.memo optimalizace
73
+ const arePropsEqual = createMemoComparison(
74
+ [], // všechny props jsou kritické
75
+ [], // žádné ignorované
76
+ false,
77
+ 'BulkEditInput'
78
+ );
79
+
80
+ export default React.memo(BulkEditInput, arePropsEqual);
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable */
2
2
  import React, { useRef, useEffect } from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
3
4
  import { Button, Space } from 'antd';
4
5
  import ModuleDropdownList from '@bit.rhplus/ui2.module-dropdown-list';
5
6
 
@@ -65,4 +66,12 @@ const BulkEditModule = ({
65
66
  );
66
67
  };
67
68
 
68
- export default BulkEditModule;
69
+ // React.memo optimalizace
70
+ const arePropsEqual = createMemoComparison(
71
+ [], // všechny props jsou kritické
72
+ [], // žádné ignorované
73
+ false,
74
+ 'BulkEditModule'
75
+ );
76
+
77
+ export default React.memo(BulkEditModule, arePropsEqual);
@@ -2,6 +2,7 @@
2
2
  import React, { useCallback, useEffect, useRef } from 'react';
3
3
  import { Input, InputNumber, Button, Alert, Space } from 'antd';
4
4
  import { validateValue, getInputType } from './utils';
5
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
5
6
 
6
7
  /**
7
8
  * Popover komponenta s inputem pro bulk edit
@@ -298,4 +299,12 @@ const BulkEditPopover = ({
298
299
  );
299
300
  };
300
301
 
301
- export default BulkEditPopover;
302
+ // React.memo optimalizace - rerender pouze při změně kritických props
303
+ const arePropsEqual = createMemoComparison(
304
+ ['visible', 'value', 'loading', 'error', 'column', 'range', 'cellCount'],
305
+ ['onValueChange', 'onSubmit', 'onCancel'],
306
+ false,
307
+ 'BulkEditPopover'
308
+ );
309
+
310
+ export default React.memo(BulkEditPopover, arePropsEqual);
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable */
2
2
  import React, { useRef, useEffect } from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
3
4
  import { Select, Button, Space } from 'antd';
4
5
  import * as LucideIcons from 'lucide-react';
5
6
 
@@ -93,4 +94,12 @@ const BulkEditSelect = ({
93
94
  );
94
95
  };
95
96
 
96
- export default BulkEditSelect;
97
+ // React.memo optimalizace
98
+ const arePropsEqual = createMemoComparison(
99
+ [], // všechny props jsou kritické
100
+ [], // žádné ignorované
101
+ false,
102
+ 'BulkEditSelect'
103
+ );
104
+
105
+ export default React.memo(BulkEditSelect, arePropsEqual);
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable */
2
2
  import * as React from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
3
4
  import { CircleHelp, Check, X } from 'lucide-react';
4
5
 
5
6
  // Memoized Icon component
@@ -83,4 +84,12 @@ function BooleanRenderer(props) {
83
84
  );
84
85
  }
85
86
 
86
- export default React.memo(BooleanRenderer);
87
+ // React.memo optimalizace pro AG-Grid renderer
88
+ const arePropsEqual = createMemoComparison(
89
+ ['value', 'colDef'],
90
+ [],
91
+ false,
92
+ 'BooleanRenderer'
93
+ );
94
+
95
+ export default React.memo(BooleanRenderer, arePropsEqual);
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable */
2
2
  import React, { useState, useCallback, useMemo } from 'react';
3
3
  import Button from 'antd/es/button';
4
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
4
5
 
5
6
  const DEFAULT_STYLE = {
6
7
  fontSize: '12px'
@@ -82,7 +83,9 @@ function ButtonRenderer(props) {
82
83
 
83
84
  const isEmptyValue = value === null || value === '' || value === undefined;
84
85
 
85
- const visible = useMemo(() => visibleGetter(props), [visibleGetter, props]);
86
+ // FIX: Odstranit props z dependencies - props objekt se mění každý render
87
+ // visibleGetter je stabilní funkce, props bereme přímo z closure
88
+ const visible = useMemo(() => visibleGetter(props), [visibleGetter]);
86
89
 
87
90
  const containerStyle = useMemo(() => ({
88
91
  display: 'flex',
@@ -119,4 +122,15 @@ function ButtonRenderer(props) {
119
122
  );
120
123
  }
121
124
 
122
- export default React.memo(ButtonRenderer);
125
+ ButtonRenderer.displayName = 'ButtonRenderer';
126
+
127
+ // React.memo optimalizace s custom comparison
128
+ // AG-Grid renderery dostávají props které obsahují AG-Grid API reference
129
+ const arePropsEqual = createMemoComparison(
130
+ ['value', 'colDef'],
131
+ [],
132
+ false,
133
+ 'ButtonRenderer'
134
+ );
135
+
136
+ export default React.memo(ButtonRenderer, arePropsEqual);
@@ -1,7 +1,20 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  // Style constant
4
- const CONTAINER_STYLE = { textAlign: "center" };
4
+ const CONTAINER_STYLE = {
5
+ textAlign: "center",
6
+ display: "flex",
7
+ alignItems: "center",
8
+ justifyContent: "center",
9
+ height: "100%",
10
+ };
11
+
12
+ // Memoizovaný CheckboxElement sub-komponenta
13
+ const CheckboxElement = React.memo(({ checked, onChange }) => (
14
+ <input type="checkbox" checked={checked} onChange={onChange} />
15
+ ));
16
+
17
+ CheckboxElement.displayName = 'CheckboxElement';
5
18
 
6
19
  function CheckboxRenderer(props) {
7
20
  const {
@@ -12,9 +25,10 @@ function CheckboxRenderer(props) {
12
25
 
13
26
  const onChange = React.useCallback((e) => {
14
27
  e.preventDefault();
15
- const {context: { componentParent: {onCheckboxChange} = {}} = {}} = props || {};
16
- if (onCheckboxChange)
28
+ const { context: { componentParent: { onCheckboxChange } = {} } = {} } = props || {};
29
+ if (onCheckboxChange) {
17
30
  onCheckboxChange(props);
31
+ }
18
32
  }, [props]);
19
33
 
20
34
  const visibleCondition = React.useMemo(() =>
@@ -27,17 +41,16 @@ function CheckboxRenderer(props) {
27
41
  return !newItem && (showOnGroup || !!data) && visibleCondition;
28
42
  }, [data, showOnGroup, visibleCondition]);
29
43
 
30
- if (!showCondition) return <div />;
31
-
32
- if (value === undefined) {
33
- return <div />
34
- }
44
+ if (!showCondition) return null;
45
+ if (value === undefined) return null;
35
46
 
36
47
  return (
37
48
  <div style={CONTAINER_STYLE}>
38
- <input type="checkbox" checked={value} onChange={onChange} />
49
+ <CheckboxElement checked={value} onChange={onChange} />
39
50
  </div>
40
51
  );
41
52
  }
42
53
 
54
+ CheckboxRenderer.displayName = 'CheckboxRenderer';
55
+
43
56
  export default React.memo(CheckboxRenderer);
@@ -1,8 +1,55 @@
1
1
  import * as React from 'react';
2
2
 
3
3
  // Style constants
4
- const SPAN_STYLE = { marginLeft: 10, marginRight: 10 };
5
- const IMG_STYLE = { marginTop: -5 };
4
+ const CONTAINER_STYLE = {
5
+ display: 'flex',
6
+ alignItems: 'center',
7
+ height: '100%',
8
+ };
9
+
10
+ const FLAG_WRAPPER_STYLE = {
11
+ marginLeft: 10,
12
+ marginRight: 10,
13
+ display: 'inline-flex',
14
+ alignItems: 'center',
15
+ };
16
+
17
+ const IMG_STYLE = {
18
+ marginTop: -5,
19
+ objectFit: 'contain',
20
+ };
21
+
22
+ // Memoizovaná CountryFlag sub-komponenta
23
+ const CountryFlag = React.memo(({ code, size = 16 }) => {
24
+ const [hasError, setHasError] = React.useState(false);
25
+
26
+ const imageUrl = React.useMemo(() => {
27
+ if (!code) return "";
28
+ return `https://rhplus.blob.core.windows.net/countries/${code.toUpperCase()}.png`;
29
+ }, [code]);
30
+
31
+ const handleError = React.useCallback(() => {
32
+ setHasError(true);
33
+ }, []);
34
+
35
+ React.useEffect(() => {
36
+ setHasError(false);
37
+ }, [imageUrl]);
38
+
39
+ if (hasError || !imageUrl) return null;
40
+
41
+ return (
42
+ <img
43
+ alt="country flag"
44
+ style={{ ...IMG_STYLE, width: size, height: size }}
45
+ src={imageUrl}
46
+ loading="lazy"
47
+ onError={handleError}
48
+ />
49
+ );
50
+ });
51
+
52
+ CountryFlag.displayName = 'CountryFlag';
6
53
 
7
54
  function SimpleCountryCellRenderer(params) {
8
55
  const {
@@ -14,31 +61,32 @@ function SimpleCountryCellRenderer(params) {
14
61
  } = {},
15
62
  } = {},
16
63
  } = params;
17
- const {id, name, code} = value;
64
+ const { id, name, code } = value;
18
65
 
19
- const visibleCondition = condition ? condition(data) : true;
66
+ // Memoizovaná visibleCondition
67
+ const visibleCondition = React.useMemo(() =>
68
+ condition ? condition(data) : true,
69
+ [condition, data]
70
+ );
20
71
 
21
72
  const showCondition = React.useMemo(() => {
22
73
  const newItem = (data && data._rh_plus_ag_grid_new_item) || false;
23
74
  return !newItem && (showOnGroup || !!data) && visibleCondition;
24
75
  }, [data, showOnGroup, visibleCondition]);
25
76
 
26
- const imageUrl = React.useMemo(() => {
27
- if (!code) return "";
28
- return `https://rhplus.blob.core.windows.net/countries/${code.toUpperCase()}.png`;
29
- }, [code]);
30
-
31
- if (!showCondition) return <div />;
32
- if (!id || !code) return <div />;
77
+ if (!showCondition) return null;
78
+ if (!id || !code) return null;
33
79
 
34
80
  return (
35
- <div>
36
- <span style={SPAN_STYLE}>
37
- <img alt="img" style={IMG_STYLE} src={imageUrl} />
81
+ <div style={CONTAINER_STYLE}>
82
+ <span style={FLAG_WRAPPER_STYLE}>
83
+ <CountryFlag code={code} size={16} />
38
84
  </span>
39
85
  {name}
40
86
  </div>
41
87
  );
42
88
  }
43
89
 
90
+ SimpleCountryCellRenderer.displayName = 'SimpleCountryCellRenderer';
91
+
44
92
  export default React.memo(SimpleCountryCellRenderer);
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable */
2
2
  import * as React from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
3
4
  import { CircleHelp } from 'lucide-react';
4
5
  import * as LucideIcons from 'lucide-react';
5
6
 
@@ -255,4 +256,12 @@ function IconRenderer(props) {
255
256
  );
256
257
  }
257
258
 
258
- export default React.memo(IconRenderer);
259
+ // React.memo optimalizace pro AG-Grid renderer
260
+ const arePropsEqual = createMemoComparison(
261
+ ['value', 'colDef'],
262
+ [],
263
+ false,
264
+ 'IconRenderer'
265
+ );
266
+
267
+ export default React.memo(IconRenderer, arePropsEqual);
@@ -1,11 +1,12 @@
1
1
  /* eslint-disable */
2
2
  import * as React from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
3
4
 
4
5
  function ImageRenderer(props) {
5
6
  const { data, value, colDef: { imageRendererParams = {} } = {} } = props;
6
7
 
7
8
  if (!imageRendererParams) return null;
8
-
9
+
9
10
  const {
10
11
  cellAlign = 'center',
11
12
  visibleGetter,
@@ -88,4 +89,14 @@ function ImageRenderer(props) {
88
89
  );
89
90
  }
90
91
 
91
- export default React.memo(ImageRenderer);
92
+ ImageRenderer.displayName = 'ImageRenderer';
93
+
94
+ // React.memo optimalizace pro AG-Grid renderer
95
+ const arePropsEqual = createMemoComparison(
96
+ ['value', 'colDef'],
97
+ [],
98
+ false,
99
+ 'ImageRenderer'
100
+ );
101
+
102
+ export default React.memo(ImageRenderer, arePropsEqual);
@@ -0,0 +1,132 @@
1
+ /* eslint-disable */
2
+ import * as React from 'react';
3
+ import { createMemoComparison } from '@bit.rhplus/react-memo';
4
+
5
+ // Style constants
6
+ const CONTAINER_STYLE = {
7
+ width: '100%',
8
+ height: '100%',
9
+ display: 'flex',
10
+ alignItems: 'center',
11
+ };
12
+
13
+ const DEFAULT_LINK_STYLE = {
14
+ color: '#1a73e8',
15
+ textDecoration: 'none',
16
+ cursor: 'pointer',
17
+ };
18
+
19
+ const DEFAULT_HOVER_STYLE = {
20
+ textDecoration: 'underline',
21
+ };
22
+
23
+ function LinkRenderer(props) {
24
+ const {
25
+ value,
26
+ data,
27
+ colDef: { linkRendererParams = {} } = {},
28
+ } = props;
29
+
30
+ const {
31
+ onClick,
32
+ linkStyle,
33
+ hoverStyle,
34
+ overviewToggle = false,
35
+ showOnGroup = false,
36
+ visibleGetter,
37
+ } = linkRendererParams;
38
+
39
+ const [isHovered, setIsHovered] = React.useState(false);
40
+
41
+ const handleMouseEnter = React.useCallback(() => {
42
+ setIsHovered(true);
43
+ }, []);
44
+
45
+ const handleMouseLeave = React.useCallback(() => {
46
+ setIsHovered(false);
47
+ }, []);
48
+
49
+ const handleClick = React.useCallback(
50
+ (event) => {
51
+ event.stopPropagation();
52
+
53
+ if (overviewToggle && props.api) {
54
+ props.api.dispatchEvent({
55
+ type: 'overviewToggle',
56
+ data: props.data,
57
+ params: props,
58
+ });
59
+ }
60
+
61
+ if (onClick) {
62
+ onClick(props);
63
+ }
64
+ },
65
+ [onClick, overviewToggle, props]
66
+ );
67
+
68
+ const handleKeyPress = React.useCallback(
69
+ (event) => {
70
+ if (event.key === 'Enter' || event.key === ' ') {
71
+ handleClick(event);
72
+ }
73
+ },
74
+ [handleClick]
75
+ );
76
+
77
+ const visibleResult = React.useMemo(() =>
78
+ visibleGetter ? visibleGetter(data) : true,
79
+ [visibleGetter, data]
80
+ );
81
+
82
+ const showCondition = React.useMemo(() => {
83
+ const newItem = (data && data._rh_plus_ag_grid_new_item) || false;
84
+ return !newItem && (showOnGroup || !!data) && visibleResult;
85
+ }, [data, showOnGroup, visibleResult]);
86
+
87
+ const computedLinkStyle = React.useMemo(() => ({
88
+ ...DEFAULT_LINK_STYLE,
89
+ ...(typeof linkStyle === 'function'
90
+ ? linkStyle(props)
91
+ : linkStyle || {}),
92
+ }), [linkStyle, props]);
93
+
94
+ const computedHoverStyle = React.useMemo(() => ({
95
+ ...DEFAULT_LINK_STYLE,
96
+ ...computedLinkStyle,
97
+ ...DEFAULT_HOVER_STYLE,
98
+ ...(typeof hoverStyle === 'function'
99
+ ? hoverStyle(props)
100
+ : hoverStyle || {}),
101
+ }), [computedLinkStyle, hoverStyle, props]);
102
+
103
+ if (!showCondition || !value) return null;
104
+
105
+ return (
106
+ <div className="link-cell-container" style={CONTAINER_STYLE}>
107
+ <span
108
+ onClick={handleClick}
109
+ onMouseEnter={handleMouseEnter}
110
+ onMouseLeave={handleMouseLeave}
111
+ onKeyPress={handleKeyPress}
112
+ style={isHovered ? computedHoverStyle : computedLinkStyle}
113
+ role="button"
114
+ tabIndex={0}
115
+ >
116
+ {value}
117
+ </span>
118
+ </div>
119
+ );
120
+ }
121
+
122
+ LinkRenderer.displayName = 'LinkRenderer';
123
+
124
+ // React.memo optimalizace pro AG-Grid renderer
125
+ const arePropsEqual = createMemoComparison(
126
+ ['value', 'colDef'],
127
+ [],
128
+ false,
129
+ 'LinkRenderer'
130
+ );
131
+
132
+ export default React.memo(LinkRenderer, arePropsEqual);