@bit.rhplus/ui.grid 0.0.22 → 0.0.24

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.
package/ColumnBuilder.jsx CHANGED
@@ -1,10 +1,9 @@
1
1
  import * as React from 'react';
2
- import { Menu, Dropdown, Button, Divider } from 'antd';
2
+ import { Menu, Dropdown, Divider } from 'antd';
3
3
  import { prepareCellStyle, prepareColDef, getValueByPath } from './utils';
4
4
  import { currencySymbols } from './enums';
5
5
  import { ActionIcon } from './Icons';
6
6
 
7
-
8
7
  // Vytvoříme React hook funkci pro link cell renderer
9
8
  const useLinkCellRenderer = (
10
9
  params,
@@ -122,72 +121,6 @@ const useObjectCellRenderer = (params, editable, onEditClick) => {
122
121
  };
123
122
  };
124
123
 
125
- // Vytvoříme React hook funkci pro row hover action renderer
126
- const useRowHoverActionRenderer = (params) => {
127
- const [isRowHovered, setIsRowHovered] = React.useState(false);
128
- const rowRef = React.useRef(null);
129
-
130
- React.useEffect(() => {
131
- if (!params.node) return undefined;
132
-
133
- // Funkce pro kontrolu, zda je řádek v hover stavu
134
- const checkRowHoverState = () => {
135
- // Najdeme DOM element řádku pomocí rowIndex
136
- const rowElement = document.querySelector(
137
- `.ag-row[row-index="${params.rowIndex}"]`
138
- );
139
- if (rowElement) {
140
- rowRef.current = rowElement;
141
- // AG-Grid automaticky přidává třídu ag-row-hover k řádku při najetí myší
142
- const isHovered = rowElement.classList.contains('ag-row-hover');
143
- setIsRowHovered(isHovered);
144
- }
145
- };
146
-
147
- // Vytvoříme MutationObserver pro sledování změn tříd na řádku
148
- const observer = new MutationObserver((mutations) => {
149
- mutations.forEach((mutation) => {
150
- if (
151
- mutation.type === 'attributes' &&
152
- mutation.attributeName === 'class'
153
- ) {
154
- checkRowHoverState();
155
- }
156
- });
157
- });
158
-
159
- // Inicializujeme stav
160
- checkRowHoverState();
161
-
162
- // Přidáme observer k element řádku, pokud existuje
163
- if (rowRef.current) {
164
- observer.observe(rowRef.current, { attributes: true });
165
- }
166
-
167
- // Přidáme event listeners na grid container pro sledování pohybu myši
168
- const gridContainer = document.querySelector('.ag-root-wrapper');
169
- if (gridContainer) {
170
- gridContainer.addEventListener('mouseover', checkRowHoverState);
171
- gridContainer.addEventListener('mouseout', checkRowHoverState);
172
- }
173
-
174
- // Cleanup při odmontování komponenty
175
- return () => {
176
- if (rowRef.current) {
177
- observer.disconnect();
178
- }
179
- if (gridContainer) {
180
- gridContainer.removeEventListener('mouseover', checkRowHoverState);
181
- gridContainer.removeEventListener('mouseout', checkRowHoverState);
182
- }
183
- };
184
- }, [params.node, params.rowIndex]);
185
-
186
- return {
187
- isRowHovered,
188
- };
189
- };
190
-
191
124
  class ColumnBuilder {
192
125
  #addPreparedColumn(props) {
193
126
  this.columns.push(prepareColDef(this.intl, props));
@@ -198,42 +131,43 @@ class ColumnBuilder {
198
131
  this.intl = intl;
199
132
  }
200
133
 
201
- addColumn({ colorField, ...props }) {
202
- // Získáme původní cellStyle, pokud existuje
203
- const originalCellStyle = props.cellStyle;
204
- const {cellAlign, ...restProps} = props;
205
-
206
- // Pokud je zadáno colorField, vytvoříme novou funkci pro cellStyle
207
- if (colorField) {
208
- const overrideCellStyle = (params) => {
209
- // Získáme základní styl
210
- let baseStyle = {};
211
- if (originalCellStyle) {
212
- if (typeof originalCellStyle === 'function') {
213
- baseStyle = originalCellStyle(params);
214
- } else {
215
- baseStyle = originalCellStyle;
134
+ addColumn({ colorField, ...props }) {
135
+ // Získáme původní cellStyle, pokud existuje
136
+ const originalCellStyle = props.cellStyle;
137
+ const { cellAlign, ...restProps } = props;
138
+
139
+ // Pokud je zadáno colorField, vytvoříme novou funkci pro cellStyle
140
+ if (colorField) {
141
+ const overrideCellStyle = (params) => {
142
+ // Získáme základní styl
143
+ let baseStyle = {};
144
+ if (originalCellStyle) {
145
+ if (typeof originalCellStyle === 'function') {
146
+ baseStyle = originalCellStyle(params);
147
+ } else {
148
+ baseStyle = originalCellStyle;
149
+ }
216
150
  }
217
- }
218
-
219
- // Získáme hodnotu barvy z dat
220
- const colorValue = params.data && getValueByPath(params.data, colorField);
221
- const restStyle = prepareCellStyle(props);
222
- // Vrátíme kombinovaný styl
223
- return colorValue
224
- ? { ...baseStyle, ...restStyle, color: colorValue }
225
- : { ...baseStyle, ...restStyle };
226
- };
227
-
228
- // Předáme upravené props do addPreparedColumn
229
- this.#addPreparedColumn({ ...restProps, overrideCellStyle });
230
- } else {
231
- // Pokud není colorField zadán, použijeme původní implementaci
232
- this.#addPreparedColumn(props);
151
+
152
+ // Získáme hodnotu barvy z dat
153
+ const colorValue =
154
+ params.data && getValueByPath(params.data, colorField);
155
+ const restStyle = prepareCellStyle(props);
156
+ // Vrátíme kombinovaný styl
157
+ return colorValue
158
+ ? { ...baseStyle, ...restStyle, color: colorValue }
159
+ : { ...baseStyle, ...restStyle };
160
+ };
161
+
162
+ // Předáme upravené props do addPreparedColumn
163
+ this.#addPreparedColumn({ ...restProps, overrideCellStyle });
164
+ } else {
165
+ // Pokud není colorField zadán, použijeme původní implementaci
166
+ this.#addPreparedColumn(props);
167
+ }
168
+
169
+ return this;
233
170
  }
234
-
235
- return this;
236
- }
237
171
 
238
172
  // Nová metoda pro přidání sloupce s fakturou pro overview mód
239
173
  addInvoiceCardColumn({
@@ -327,7 +261,7 @@ addColumn({ colorField, ...props }) {
327
261
  hoverStyle,
328
262
  cellAlign = 'left',
329
263
  editable,
330
- overviewToggle = false, // Přidán výchozí parametr pro overview
264
+ overviewToggle = false,
331
265
  ...restProps
332
266
  }) {
333
267
  // Vytvořím komponentu pro cell renderer, která používá hook
@@ -347,6 +281,12 @@ addColumn({ colorField, ...props }) {
347
281
  overviewToggle
348
282
  );
349
283
 
284
+ const handleKeyPress = React.useCallback((event) => {
285
+ if (event.key === 'Enter' || event.key === ' ') {
286
+ handleClick(event);
287
+ }
288
+ }, [handleClick]);
289
+
350
290
  return (
351
291
  <div
352
292
  className="link-cell-container"
@@ -361,14 +301,10 @@ addColumn({ colorField, ...props }) {
361
301
  onClick={handleClick}
362
302
  onMouseEnter={handleMouseEnter}
363
303
  onMouseLeave={handleMouseLeave}
304
+ onKeyPress={handleKeyPress}
364
305
  style={isHovered ? computedHoverStyle : computedLinkStyle}
365
306
  role="button"
366
307
  tabIndex={0}
367
- onKeyPress={(event) => {
368
- if (event.key === 'Enter' || event.key === ' ') {
369
- handleClick(event);
370
- }
371
- }}
372
308
  >
373
309
  {params.value}
374
310
  </span>
@@ -385,7 +321,7 @@ addColumn({ colorField, ...props }) {
385
321
  cellAlign,
386
322
  cellRenderer,
387
323
  editable: this.#resolveEditable(editable),
388
- overviewToggle, // Předání příznaku dál
324
+ overviewToggle,
389
325
  ...restProps,
390
326
  });
391
327
  return this;
@@ -459,6 +395,7 @@ addColumn({ colorField, ...props }) {
459
395
  }}
460
396
  onClick={handleEditClick}
461
397
  title="Upravit"
398
+ type="button"
462
399
  >
463
400
  <span style={{ fontSize: '16px' }}>⋮</span>
464
401
  </button>
@@ -497,13 +434,13 @@ addColumn({ colorField, ...props }) {
497
434
  visibleGetter,
498
435
  icon,
499
436
  badge,
500
- showZero
501
- }
437
+ showZero,
438
+ };
502
439
  this.#addPreparedColumn({
503
440
  iconRenderer: true,
504
441
  iconRendererParams,
505
- ...restProps
506
- })
442
+ ...restProps,
443
+ });
507
444
  return this;
508
445
  }
509
446
 
@@ -530,57 +467,336 @@ addColumn({ colorField, ...props }) {
530
467
  return this;
531
468
  }
532
469
 
470
+ // Řešení s izolovaným observer pro každý grid instance
533
471
  addPinnedActionButton({
534
- menuItems = [
535
- { key: '1', label: 'Hromadné smazání' },
536
- { key: '2', label: 'Hromadná aktualizace' },
537
- { key: '3', label: 'Spravovat značky' },
538
- { key: '4', label: 'Koncepty' },
539
- { key: '5', label: 'Hromadný e-mail' },
540
- { key: '6', label: 'Automatické odpovědi' },
541
- { key: '7', label: 'Schválit Kontakty' },
542
- { key: '8', label: 'Deduplikovat Kontakty' },
543
- { key: '9', label: 'Přidat do Kampaně' },
544
- { key: '10', label: 'Vytvoření klientského skriptu' },
545
- { key: 'divider1', type: 'divider' },
546
- { key: '11', label: 'Export Kontakty' },
547
- { key: '12', label: 'Zobrazení Zoho Sheet' },
548
- { key: 'divider2', type: 'divider' },
549
- { key: '13', label: 'Náhled tisku' },
550
- ],
472
+ menuItems = [],
551
473
  onActionClick,
474
+ onBeforeShow,
552
475
  ...restProps
553
476
  } = {}) {
554
- // Vytvořím React komponentu pro renderer s dropdown menu
555
- const ActionDropdownRenderer = React.memo((params) => {
556
- const { isRowHovered } = useRowHoverActionRenderer(params);
557
- // Stav pro sledování, zda je dropdown otevřený
477
+ const ActionDropdownRenderer = (params) => {
478
+ const [isRowHovered, setIsRowHovered] = React.useState(false);
558
479
  const [isDropdownVisible, setIsDropdownVisible] = React.useState(false);
480
+ const [currentMenuItems, setCurrentMenuItems] = React.useState(menuItems);
481
+
482
+ const isMountedRef = React.useRef(true);
483
+ const rowIndexRef = React.useRef(null);
484
+ const observerRef = React.useRef(null);
485
+ const gridContainerRef = React.useRef(null);
486
+ const currentHoveredRowRef = React.useRef(null);
487
+ const mouseListenersSetupRef = React.useRef(false);
559
488
 
560
- // Vytvoření menu komponentu
561
- const menu = (
562
- <Menu
563
- onClick={(e) => {
564
- if (onActionClick) {
565
- onActionClick(e.key, params);
489
+ // Notifikace o změně hover stavu - definována před použitím
490
+ const notifyRowHoverChange = React.useCallback((rowIndex, isHovered) => {
491
+ if (!isMountedRef.current) return;
492
+
493
+ if (!isHovered && rowIndexRef.current) {
494
+ setIsRowHovered(false);
495
+ }
496
+
497
+ if (isHovered && rowIndexRef.current === rowIndex) {
498
+ setIsRowHovered(true);
499
+ }
500
+ }, []);
501
+
502
+ // Mouse event handlers - nyní definovány po notifyRowHoverChange
503
+ const handleMouseMove = React.useCallback((event) => {
504
+ if (!isMountedRef.current) return;
505
+
506
+ const { target } = event;
507
+ if (!target) return;
508
+
509
+ const rowElement = target.closest('.ag-row');
510
+
511
+ if (rowElement) {
512
+ const rowIndex =
513
+ rowElement.getAttribute('row-index') ||
514
+ rowElement.getAttribute('aria-rowindex') ||
515
+ rowElement.dataset.rowIndex ||
516
+ rowElement.getAttribute('data-ag-row-index');
517
+
518
+ if (rowIndex !== null) {
519
+ const normalizedRowIndex = rowIndex.toString();
520
+
521
+ if (normalizedRowIndex !== currentHoveredRowRef.current) {
522
+ if (currentHoveredRowRef.current !== null) {
523
+ notifyRowHoverChange(currentHoveredRowRef.current, false);
524
+ }
525
+
526
+ currentHoveredRowRef.current = normalizedRowIndex;
527
+ notifyRowHoverChange(normalizedRowIndex, true);
566
528
  }
567
- // Po kliknutí na položku zavřeme dropdown
568
- setIsDropdownVisible(false);
569
- }}
570
- >
571
- {menuItems.map((item) => {
572
- if (item.type === 'divider') {
573
- return <Divider key={item.key} style={{ margin: '4px 0' }} />;
529
+ }
530
+ } else if (currentHoveredRowRef.current !== null) {
531
+ notifyRowHoverChange(currentHoveredRowRef.current, false);
532
+ currentHoveredRowRef.current = null;
533
+ }
534
+ }, [notifyRowHoverChange]);
535
+
536
+ const handleMouseLeave = React.useCallback((event) => {
537
+ if (!isMountedRef.current) return;
538
+
539
+ const { relatedTarget } = event;
540
+
541
+ if (
542
+ gridContainerRef.current &&
543
+ (!relatedTarget || !gridContainerRef.current.contains(relatedTarget))
544
+ ) {
545
+ if (currentHoveredRowRef.current !== null) {
546
+ notifyRowHoverChange(currentHoveredRowRef.current, false);
547
+ currentHoveredRowRef.current = null;
548
+ }
549
+ }
550
+ }, [notifyRowHoverChange]);
551
+
552
+ // Cleanup funkce - definována po handleMouseMove a handleMouseLeave
553
+ const cleanup = React.useCallback(() => {
554
+ if (observerRef.current) {
555
+ observerRef.current.disconnect();
556
+ observerRef.current = null;
557
+ }
558
+
559
+ if (gridContainerRef.current && mouseListenersSetupRef.current) {
560
+ gridContainerRef.current.removeEventListener(
561
+ 'mousemove',
562
+ handleMouseMove
563
+ );
564
+ gridContainerRef.current.removeEventListener(
565
+ 'mouseleave',
566
+ handleMouseLeave
567
+ );
568
+ mouseListenersSetupRef.current = false;
569
+ }
570
+ }, [handleMouseMove, handleMouseLeave]);
571
+
572
+ React.useEffect(() => {
573
+ return () => {
574
+ isMountedRef.current = false;
575
+ cleanup();
576
+ };
577
+ }, [cleanup]);
578
+
579
+ // Získáme row index z params
580
+ React.useEffect(() => {
581
+ const { node, rowIndex } = params;
582
+ if (node && node.rowIndex !== undefined) {
583
+ rowIndexRef.current = node.rowIndex.toString();
584
+ } else if (rowIndex !== undefined) {
585
+ rowIndexRef.current = rowIndex.toString();
586
+ }
587
+ }, [params]);
588
+
589
+ // Nastavení observer pro tento konkrétní grid
590
+ const setupGridObserver = React.useCallback(() => {
591
+ const { api, eGridCell } = params;
592
+ if (!api || observerRef.current || !isMountedRef.current) return;
593
+
594
+ const findThisGridContainer = () => {
595
+ if (eGridCell) {
596
+ let current = eGridCell;
597
+ while (current && current !== document.body) {
598
+ if (
599
+ current.classList &&
600
+ (current.classList.contains('ag-root-wrapper') ||
601
+ current.classList.contains('ag-theme-alpine') ||
602
+ current.classList.contains('ag-theme-balham') ||
603
+ current.classList.contains('ag-theme-material') ||
604
+ current.classList.contains('ag-theme-fresh') ||
605
+ current.classList.contains('ag-theme-dark') ||
606
+ current.classList.contains('ag-theme-blue') ||
607
+ current.classList.contains('ag-theme-bootstrap'))
608
+ ) {
609
+ return current;
610
+ }
611
+ current = current.parentElement;
574
612
  }
575
- return <Menu.Item key={item.key}>{item.label}</Menu.Item>;
576
- })}
577
- </Menu>
613
+ }
614
+ return null;
615
+ };
616
+
617
+ const gridContainer = findThisGridContainer();
618
+ if (!gridContainer) {
619
+ setTimeout(setupGridObserver, 100);
620
+ return;
621
+ }
622
+
623
+ gridContainerRef.current = gridContainer;
624
+
625
+ if (!mouseListenersSetupRef.current) {
626
+ gridContainer.addEventListener('mousemove', handleMouseMove, {
627
+ passive: true,
628
+ });
629
+ gridContainer.addEventListener('mouseleave', handleMouseLeave, {
630
+ passive: true,
631
+ });
632
+
633
+ const handleMouseEnter = () => {
634
+ if (isMountedRef.current) {
635
+ currentHoveredRowRef.current = null;
636
+ setIsRowHovered(false);
637
+ }
638
+ };
639
+ gridContainer.addEventListener('mouseenter', handleMouseEnter, {
640
+ passive: true,
641
+ });
642
+
643
+ mouseListenersSetupRef.current = true;
644
+ }
645
+
646
+ observerRef.current = new MutationObserver((mutations) => {
647
+ if (!isMountedRef.current) return;
648
+
649
+ let shouldRecalculate = false;
650
+
651
+ mutations.forEach((mutation) => {
652
+ if (mutation.type === 'childList') {
653
+ const addedRows = Array.from(mutation.addedNodes).some(
654
+ (node) =>
655
+ node.nodeType === Node.ELEMENT_NODE &&
656
+ (node.classList?.contains('ag-row') ||
657
+ node.querySelector?.('.ag-row'))
658
+ );
659
+
660
+ const removedRows = Array.from(mutation.removedNodes).some(
661
+ (node) =>
662
+ node.nodeType === Node.ELEMENT_NODE &&
663
+ (node.classList?.contains('ag-row') ||
664
+ node.querySelector?.('.ag-row'))
665
+ );
666
+
667
+ if (addedRows || removedRows) {
668
+ shouldRecalculate = true;
669
+ }
670
+ }
671
+ });
672
+
673
+ if (shouldRecalculate) {
674
+ currentHoveredRowRef.current = null;
675
+ setIsRowHovered(false);
676
+
677
+ setTimeout(() => {
678
+ if (isMountedRef.current && gridContainerRef.current) {
679
+ const rect = gridContainerRef.current.getBoundingClientRect();
680
+ const mouseEvent = new MouseEvent('mousemove', {
681
+ clientX: window.lastMouseX || rect.left + rect.width / 2,
682
+ clientY: window.lastMouseY || rect.top + rect.height / 2,
683
+ bubbles: true,
684
+ });
685
+ gridContainerRef.current.dispatchEvent(mouseEvent);
686
+ }
687
+ }, 100);
688
+ }
689
+ });
690
+
691
+ observerRef.current.observe(gridContainer, {
692
+ childList: true,
693
+ subtree: true,
694
+ attributes: false,
695
+ });
696
+
697
+ const trackMouse = (e) => {
698
+ window.lastMouseX = e.clientX;
699
+ window.lastMouseY = e.clientY;
700
+ };
701
+
702
+ document.addEventListener('mousemove', trackMouse, { passive: true });
703
+
704
+ const removeMouseListener = () => {
705
+ document.removeEventListener('mousemove', trackMouse);
706
+ };
707
+
708
+ removeMouseListener();
709
+ }, [params, handleMouseMove, handleMouseLeave]);
710
+
711
+ React.useEffect(() => {
712
+ setupGridObserver();
713
+ }, [setupGridObserver]);
714
+
715
+ const handleVisibleChange = React.useCallback(
716
+ async (visible) => {
717
+ if (!isMountedRef.current) return;
718
+
719
+ if (visible && onBeforeShow) {
720
+ try {
721
+ const updatedMenuItems = await onBeforeShow(params, menuItems);
722
+ if (
723
+ updatedMenuItems &&
724
+ Array.isArray(updatedMenuItems) &&
725
+ isMountedRef.current
726
+ ) {
727
+ setCurrentMenuItems(updatedMenuItems);
728
+ }
729
+ } catch (error) {
730
+ // Odstraněn console.error pro ESLint
731
+ if (isMountedRef.current) {
732
+ setCurrentMenuItems(menuItems);
733
+ }
734
+ }
735
+ }
736
+
737
+ if (isMountedRef.current) {
738
+ setIsDropdownVisible(visible);
739
+ }
740
+ },
741
+ [params]
742
+ );
743
+
744
+ React.useEffect(() => {
745
+ if (isMountedRef.current) {
746
+ setCurrentMenuItems(menuItems);
747
+ }
748
+ }, []);
749
+
750
+ const menu = React.useMemo(
751
+ () => (
752
+ <Menu
753
+ onClick={(e) => {
754
+ if (onActionClick) {
755
+ const item = currentMenuItems.filter(f => f.key === e.key)[0];
756
+ onActionClick(e.key, params, item);
757
+ }
758
+ setIsDropdownVisible(false);
759
+ }}
760
+ >
761
+ {currentMenuItems.map((item) => {
762
+ if (item.type === 'divider') {
763
+ return <Divider key={item.key} style={{ margin: '4px 0' }} />;
764
+ }
765
+
766
+ const { disable, disabled } = item;
767
+ let isDisabled = false;
768
+ if (typeof disable === 'function') {
769
+ isDisabled = disable(params);
770
+ } else if (typeof disable === 'boolean') {
771
+ isDisabled = disable;
772
+ } else if (disabled !== undefined) {
773
+ isDisabled = disabled;
774
+ }
775
+
776
+ return (
777
+ <Menu.Item key={item.key} disabled={isDisabled}>
778
+ {item.label}
779
+ </Menu.Item>
780
+ );
781
+ })}
782
+ </Menu>
783
+ ),
784
+ [currentMenuItems, params]
578
785
  );
579
786
 
580
- // Styly pro tlačítko
787
+ const containerStyle = {
788
+ width: '32px',
789
+ height: '32px',
790
+ display: 'flex',
791
+ alignItems: 'center',
792
+ justifyContent: 'center',
793
+ position: 'relative',
794
+ };
795
+
581
796
  const buttonStyle = {
582
797
  minWidth: 'auto',
583
798
  width: '32px',
799
+ height: '32px',
584
800
  padding: '0',
585
801
  background: 'transparent',
586
802
  border: 'none',
@@ -588,40 +804,60 @@ addColumn({ colorField, ...props }) {
588
804
  display: 'flex',
589
805
  alignItems: 'center',
590
806
  justifyContent: 'center',
807
+ opacity: isRowHovered || isDropdownVisible ? 1 : 0,
808
+ visibility: isRowHovered || isDropdownVisible ? 'visible' : 'hidden',
809
+ transition: 'opacity 0.15s ease-in-out, visibility 0.15s ease-in-out',
810
+ pointerEvents: isRowHovered || isDropdownVisible ? 'auto' : 'none',
591
811
  };
592
812
 
593
- // Zobrazíme tlačítko pouze pokud je řádek v hover stavu NEBO dropdown je otevřený
594
- if (!isRowHovered && !isDropdownVisible) return null;
813
+ const handleDropdownClick = React.useCallback((e) => {
814
+ e.stopPropagation();
815
+ }, []);
816
+
817
+ const handleKeyDown = React.useCallback((e) => {
818
+ if (e.key === 'Enter' || e.key === ' ') {
819
+ e.preventDefault();
820
+ setIsDropdownVisible(!isDropdownVisible);
821
+ }
822
+ }, [isDropdownVisible]);
595
823
 
596
824
  return (
597
- <Dropdown
598
- overlayStyle={{ zIndex: 5000 }}
599
- overlay={menu}
600
- trigger={['click']}
601
- visible={isDropdownVisible}
602
- onVisibleChange={(visible) => setIsDropdownVisible(visible)}
603
- >
604
- <Button
605
- style={buttonStyle}
606
- // Zastavíme propagaci události mouseLeave, aby nedošlo k zavření dropdown
607
- onMouseEnter={(e) => {
608
- e.stopPropagation();
609
- }}
825
+ <div style={containerStyle}>
826
+ <Dropdown
827
+ overlayStyle={{ zIndex: 5000 }}
828
+ overlay={menu}
829
+ trigger={['click']}
830
+ visible={isDropdownVisible}
831
+ onVisibleChange={handleVisibleChange}
832
+ getPopupContainer={() => document.body}
610
833
  >
611
- <ActionIcon />
612
- </Button>
613
- </Dropdown>
834
+ <div
835
+ style={buttonStyle}
836
+ onClick={handleDropdownClick}
837
+ onKeyDown={handleKeyDown}
838
+ role="button"
839
+ tabIndex={0}
840
+ aria-label="Otevřít akční menu"
841
+ >
842
+ <ActionIcon />
843
+ </div>
844
+ </Dropdown>
845
+ </div>
614
846
  );
615
- });
847
+ };
616
848
 
617
849
  this.#addPreparedColumn({
618
850
  headerName: '',
619
851
  pinned: 'right',
620
- maxWidth: 33,
852
+ maxWidth: 40,
853
+ minWidth: 40,
621
854
  suppressSizeToFit: true,
622
- cellRenderer: (params) => {
623
- return <ActionDropdownRenderer {...params} />;
624
- },
855
+ suppressMenu: true,
856
+ sortable: false,
857
+ filter: false,
858
+ resizable: false,
859
+ cellRenderer: ActionDropdownRenderer,
860
+ cellClass: 'action-button-cell-observer',
625
861
  ...restProps,
626
862
  });
627
863
 
@@ -658,4 +894,4 @@ addColumn({ colorField, ...props }) {
658
894
  }
659
895
  }
660
896
 
661
- export default ColumnBuilder;
897
+ export default ColumnBuilder;