@topconsultnpm/sdkui-react 6.20.0-dev1.99 → 6.20.0-test1

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 (89) hide show
  1. package/lib/assets/headergradient.svg +87 -0
  2. package/lib/components/NewComponents/ContextMenu/TMContextMenu.js +56 -18
  3. package/lib/components/NewComponents/ContextMenu/styles.js +13 -34
  4. package/lib/components/NewComponents/ContextMenu/types.d.ts +8 -2
  5. package/lib/components/NewComponents/FloatingMenuBar/TMFloatingMenuBar.js +315 -271
  6. package/lib/components/NewComponents/FloatingMenuBar/styles.d.ts +4 -0
  7. package/lib/components/NewComponents/FloatingMenuBar/styles.js +6 -2
  8. package/lib/components/NewComponents/FloatingMenuBar/types.d.ts +7 -4
  9. package/lib/components/base/TMButton.js +6 -0
  10. package/lib/components/base/TMClosableList.js +4 -0
  11. package/lib/components/base/TMDropDownMenu.js +2 -0
  12. package/lib/components/base/TMListView.js +1 -1
  13. package/lib/components/base/TMPanel.d.ts +1 -1
  14. package/lib/components/base/TMPanel.js +3 -1
  15. package/lib/components/base/TMPopUp.js +6 -0
  16. package/lib/components/base/TMToolbarCard.js +2 -0
  17. package/lib/components/base/TMTreeView.d.ts +2 -1
  18. package/lib/components/base/TMTreeView.js +33 -26
  19. package/lib/components/choosers/TMDataListItemChooser.d.ts +2 -0
  20. package/lib/components/choosers/TMDataListItemChooser.js +8 -2
  21. package/lib/components/choosers/TMDcmtTypeChooser.d.ts +1 -0
  22. package/lib/components/choosers/TMDcmtTypeChooser.js +11 -3
  23. package/lib/components/choosers/TMDistinctValues.js +2 -2
  24. package/lib/components/choosers/TMDynDataListItemChooser.d.ts +2 -0
  25. package/lib/components/choosers/TMDynDataListItemChooser.js +8 -2
  26. package/lib/components/choosers/TMMetadataChooser.d.ts +2 -0
  27. package/lib/components/choosers/TMMetadataChooser.js +11 -3
  28. package/lib/components/choosers/TMUserChooser.d.ts +2 -0
  29. package/lib/components/choosers/TMUserChooser.js +8 -2
  30. package/lib/components/editors/TMCheckBox.js +2 -0
  31. package/lib/components/editors/TMDateBox.js +18 -9
  32. package/lib/components/editors/TMEditorStyled.js +7 -0
  33. package/lib/components/editors/TMLocalizedTextBox.d.ts +3 -1
  34. package/lib/components/editors/TMLocalizedTextBox.js +16 -14
  35. package/lib/components/editors/TMMetadataEditor.d.ts +1 -0
  36. package/lib/components/editors/TMMetadataEditor.js +4 -4
  37. package/lib/components/editors/TMMetadataTextBox.d.ts +9 -0
  38. package/lib/components/editors/TMMetadataTextBox.js +92 -0
  39. package/lib/components/editors/TMMetadataValues.d.ts +2 -0
  40. package/lib/components/editors/TMMetadataValues.js +3 -3
  41. package/lib/components/editors/TMRadioButton.js +2 -0
  42. package/lib/components/editors/TMTextBox.d.ts +1 -1
  43. package/lib/components/editors/TMTextBox.js +23 -1
  44. package/lib/components/editors/TMTextExpression.js +6 -91
  45. package/lib/components/features/assistant/TMToppyDraggableHelpCenter.js +2 -0
  46. package/lib/components/features/documents/TMDcmtBlog.js +1 -1
  47. package/lib/components/features/documents/TMDcmtForm.js +120 -87
  48. package/lib/components/features/documents/TMDcmtPreview.js +27 -30
  49. package/lib/components/features/search/TMSearch.js +5 -1
  50. package/lib/components/features/search/TMSearchQueryEditor.d.ts +1 -0
  51. package/lib/components/features/search/TMSearchQueryEditor.js +10 -10
  52. package/lib/components/features/search/TMSearchQueryPanel.js +24 -10
  53. package/lib/components/features/search/TMSearchResult.js +168 -8
  54. package/lib/components/features/search/TMSearchResultsMenuItems.d.ts +1 -1
  55. package/lib/components/features/search/TMSearchResultsMenuItems.js +24 -4
  56. package/lib/components/features/search/TMViewHistoryDcmt.js +45 -50
  57. package/lib/components/features/tasks/TMTaskForm.js +55 -24
  58. package/lib/components/features/tasks/TMTasksUtils.js +14 -1
  59. package/lib/components/features/workflow/TMWorkflowPopup.js +5 -4
  60. package/lib/components/features/workflow/diagram/DiagramItemComponent.js +2 -0
  61. package/lib/components/features/workflow/diagram/DiagramItemForm.js +1 -1
  62. package/lib/components/features/workflow/diagram/WFDiagram.js +1 -1
  63. package/lib/components/forms/Login/TMLoginForm.js +1 -1
  64. package/lib/components/grids/TMValidationItemsList.js +6 -0
  65. package/lib/components/index.d.ts +1 -0
  66. package/lib/components/index.js +1 -0
  67. package/lib/components/layout/panelManager/TMPanelManagerContext.js +13 -5
  68. package/lib/components/query/TMQueryEditor.d.ts +4 -0
  69. package/lib/components/query/TMQueryEditor.js +13 -9
  70. package/lib/components/sidebar/TMHeader.js +11 -7
  71. package/lib/components/sidebar/TMSidebar.d.ts +0 -1
  72. package/lib/components/sidebar/TMSidebar.js +16 -44
  73. package/lib/components/sidebar/TMSidebarItem.js +36 -17
  74. package/lib/helper/SDKUI_Globals.d.ts +3 -0
  75. package/lib/helper/SDKUI_Globals.js +6 -3
  76. package/lib/helper/SDKUI_Localizator.d.ts +4 -16
  77. package/lib/helper/SDKUI_Localizator.js +37 -157
  78. package/lib/helper/TMIcons.d.ts +1 -0
  79. package/lib/helper/TMIcons.js +3 -0
  80. package/lib/helper/TMToppyMessage.js +4 -0
  81. package/lib/helper/helpers.d.ts +27 -1
  82. package/lib/helper/helpers.js +107 -1
  83. package/lib/helper/queryHelper.d.ts +1 -1
  84. package/lib/helper/queryHelper.js +24 -1
  85. package/lib/hooks/useFloatingBarPinnedItems.d.ts +11 -0
  86. package/lib/hooks/useFloatingBarPinnedItems.js +54 -0
  87. package/lib/hooks/useMetadataExpression.d.ts +19 -0
  88. package/lib/hooks/useMetadataExpression.js +99 -0
  89. package/package.json +55 -55
@@ -0,0 +1,87 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Livello_2" data-name="Livello 2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 505.45">
3
+ <defs>
4
+ <style>
5
+ .cls-1 {
6
+ fill: url(#Sfumatura_senza_nome_6);
7
+ }
8
+
9
+ .cls-1, .cls-2, .cls-3, .cls-4 {
10
+ opacity: .5;
11
+ }
12
+
13
+ .cls-5 {
14
+ clip-path: url(#clippath-2);
15
+ }
16
+
17
+ .cls-5, .cls-6, .cls-7, .cls-8, .cls-9 {
18
+ fill: none;
19
+ }
20
+
21
+ .cls-2 {
22
+ fill: url(#Sfumatura_senza_nome_2);
23
+ }
24
+
25
+ .cls-6 {
26
+ clip-path: url(#clippath-3);
27
+ }
28
+
29
+ .cls-8 {
30
+ clip-path: url(#clippath);
31
+ }
32
+
33
+ .cls-3 {
34
+ fill: url(#Sfumatura_senza_nome_3-2);
35
+ }
36
+
37
+ .cls-9 {
38
+ clip-path: url(#clippath-1);
39
+ }
40
+
41
+ .cls-4 {
42
+ fill: url(#Sfumatura_senza_nome_3);
43
+ }
44
+ </style>
45
+ <clipPath id="clippath">
46
+ <rect class="cls-7" x="1237.53" y="0" width="682.47" height="326.62"/>
47
+ </clipPath>
48
+ <radialGradient id="Sfumatura_senza_nome_3" data-name="Sfumatura senza nome 3" cx="1285.93" cy="3418.23" fx="1285.93" fy="3418.23" r="50" gradientTransform="translate(-6983.46 -9577.73) scale(6.82 2.8)" gradientUnits="userSpaceOnUse">
49
+ <stop offset="0" stop-color="#2459a4"/>
50
+ <stop offset="1" stop-color="#fff" stop-opacity="0"/>
51
+ </radialGradient>
52
+ <clipPath id="clippath-1">
53
+ <rect class="cls-7" x="0" y="0" width="682.47" height="326.62" transform="translate(682.47 326.62) rotate(-180)"/>
54
+ </clipPath>
55
+ <radialGradient id="Sfumatura_senza_nome_6" data-name="Sfumatura senza nome 6" cx="1673.12" cy="3418.23" fx="1673.12" fy="3418.23" r="50" gradientTransform="translate(11545.93 -9577.73) rotate(-180) scale(6.82 -2.8)" gradientUnits="userSpaceOnUse">
56
+ <stop offset="0" stop-color="#2459a4"/>
57
+ <stop offset="1" stop-color="#fff" stop-opacity="0"/>
58
+ </radialGradient>
59
+ <clipPath id="clippath-2">
60
+ <rect class="cls-7" x="0" y="0" width="1055.7" height="297.5"/>
61
+ </clipPath>
62
+ <radialGradient id="Sfumatura_senza_nome_3-2" data-name="Sfumatura senza nome 3" cx="955.6" cy="3436.6" fx="955.6" fy="3436.6" r="50" gradientTransform="translate(-9560.44 -8770.57) scale(10.56 2.55)" xlink:href="#Sfumatura_senza_nome_3"/>
63
+ <clipPath id="clippath-3">
64
+ <rect class="cls-7" x="297.09" y="0" width="1055.7" height="505.45"/>
65
+ </clipPath>
66
+ <radialGradient id="Sfumatura_senza_nome_2" data-name="Sfumatura senza nome 2" cx="983.74" cy="3351.83" fx="983.74" fy="3351.83" r="50" gradientTransform="translate(-9560.44 -14533.91) scale(10.56 4.33)" gradientUnits="userSpaceOnUse">
67
+ <stop offset="0" stop-color="#2459a4"/>
68
+ <stop offset="1" stop-color="#fff"/>
69
+ </radialGradient>
70
+ </defs>
71
+ <g id="Livello_1-2" data-name="Livello 1">
72
+ <g>
73
+ <g class="cls-8">
74
+ <ellipse class="cls-4" cx="1792.58" cy="-7.96" rx="341.23" ry="139.98"/>
75
+ </g>
76
+ <g class="cls-9">
77
+ <ellipse class="cls-1" cx="127.42" cy="-7.96" rx="341.23" ry="139.98"/>
78
+ </g>
79
+ <g class="cls-5">
80
+ <ellipse class="cls-3" cx="527.85" cy="-7.25" rx="527.85" ry="127.5"/>
81
+ </g>
82
+ <g class="cls-6">
83
+ <ellipse class="cls-2" cx="824.94" cy="-12.32" rx="527.85" ry="216.62"/>
84
+ </g>
85
+ </g>
86
+ </g>
87
+ </svg>
@@ -12,6 +12,8 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
12
12
  parentNames: [],
13
13
  });
14
14
  const [hoveredSubmenus, setHoveredSubmenus] = useState([]);
15
+ // Tracks items whose rightIconProps have been clicked, so the icon color flips immediately
16
+ const [toggledItemIds, setToggledItemIds] = useState(new Set());
15
17
  const isMobile = useIsMobile();
16
18
  const isIOS = useIsIOS();
17
19
  const menuRef = useRef(null);
@@ -35,6 +37,7 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
35
37
  }));
36
38
  }
37
39
  setHoveredSubmenus([]);
40
+ setToggledItemIds(new Set());
38
41
  };
39
42
  // Sync with external control when provided
40
43
  useEffect(() => {
@@ -61,8 +64,6 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
61
64
  const touchEvent = e;
62
65
  const element = e.currentTarget;
63
66
  const touch = touchEvent.touches[0];
64
- // Prevent text selection during long press
65
- e.preventDefault();
66
67
  let state = touchStateMap.get(element);
67
68
  if (!state) {
68
69
  state = { timeout: null, startX: 0, startY: 0, longPressTriggered: false };
@@ -85,6 +86,8 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
85
86
  clientX: touch.clientX,
86
87
  clientY: touch.clientY,
87
88
  });
89
+ // Mark this as our synthetic event
90
+ syntheticEvent.isSynthetic = true;
88
91
  element.dispatchEvent(syntheticEvent);
89
92
  if (state)
90
93
  state.timeout = null;
@@ -123,8 +126,11 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
123
126
  state.longPressTriggered = false;
124
127
  }
125
128
  };
126
- // Prevent default iOS context menu
129
+ // Prevent default iOS context menu (but allow our synthetic events)
127
130
  const handleContextMenu = (e) => {
131
+ // Don't prevent our own synthetic contextmenu events
132
+ if (e.isSynthetic)
133
+ return;
128
134
  e.preventDefault();
129
135
  e.stopPropagation();
130
136
  return false;
@@ -132,13 +138,12 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
132
138
  // Attach listeners to all matching elements
133
139
  elements.forEach(element => {
134
140
  const el = element;
135
- // Prevent iOS native callout and text selection
141
+ // Prevent iOS native callout and text selection - must be set before touch starts
136
142
  const style = el.style;
137
143
  style.webkitTouchCallout = 'none';
138
144
  style.webkitUserSelect = 'none';
139
- style.userSelect = 'none';
140
- el.addEventListener('touchstart', handleTouchStart, { passive: false });
141
- el.addEventListener('touchmove', handleTouchMove, { passive: false });
145
+ el.addEventListener('touchstart', handleTouchStart, { passive: true });
146
+ el.addEventListener('touchmove', handleTouchMove, { passive: true });
142
147
  el.addEventListener('touchend', handleTouchEnd);
143
148
  el.addEventListener('touchcancel', handleTouchEnd);
144
149
  el.addEventListener('contextmenu', handleContextMenu);
@@ -147,10 +152,10 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
147
152
  return () => {
148
153
  elements.forEach(element => {
149
154
  const el = element;
155
+ // Restore webkit properties
150
156
  const style = el.style;
151
157
  style.webkitTouchCallout = '';
152
158
  style.webkitUserSelect = '';
153
- style.userSelect = '';
154
159
  el.removeEventListener('touchstart', handleTouchStart);
155
160
  el.removeEventListener('touchmove', handleTouchMove);
156
161
  el.removeEventListener('touchend', handleTouchEnd);
@@ -212,9 +217,10 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
212
217
  if (!menuState.visible)
213
218
  return;
214
219
  const handleClickOutside = (event) => {
215
- // On iOS, prevent closing immediately after opening (within 300ms)
220
+ // On iOS, prevent closing immediately after opening (within 500ms for iOS, 300ms for others)
216
221
  // This handles the case where touchend from long-press triggers touchstart listener
217
- if (Date.now() - menuOpenedAtRef.current < 300) {
222
+ const delay = isIOS ? 500 : 300;
223
+ if (Date.now() - menuOpenedAtRef.current < delay) {
218
224
  return;
219
225
  }
220
226
  const target = event.target;
@@ -244,8 +250,17 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
244
250
  const handleContextMenu = (e) => {
245
251
  if (trigger === 'right') {
246
252
  e.preventDefault();
247
- e.stopPropagation(); // Prevent event from bubbling to close other menus prematurely
248
- // Small delay to ensure other menus receive the contextmenu event and close first
253
+ // Close any other open context menus by dispatching a synthetic contextmenu event to document
254
+ // This triggers the document listener in other ContextMenu instances to close them
255
+ const syntheticEvent = new MouseEvent('contextmenu', {
256
+ bubbles: true,
257
+ cancelable: true,
258
+ clientX: -1000, // Position outside viewport so it doesn't interfere
259
+ clientY: -1000,
260
+ });
261
+ document.dispatchEvent(syntheticEvent);
262
+ e.stopPropagation(); // Prevent event from bubbling after closing others
263
+ // Small delay to ensure other menus close first
249
264
  setTimeout(() => {
250
265
  setMenuState({
251
266
  visible: true,
@@ -418,13 +433,36 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
418
433
  e.stopPropagation();
419
434
  handleItemClick(item);
420
435
  };
421
- const handleRightIconClick = (e) => {
436
+ const handleRightIconPropsClick = (e) => {
437
+ e.preventDefault();
422
438
  e.stopPropagation();
423
- // if (item.disabled) return;
424
- item.onRightIconClick?.();
425
- handleClose();
439
+ e.nativeEvent.stopImmediatePropagation();
440
+ item.rightIconProps?.onClick?.();
441
+ if (item.id) {
442
+ setToggledItemIds(prev => {
443
+ const next = new Set(prev);
444
+ if (next.has(item.id))
445
+ next.delete(item.id);
446
+ else
447
+ next.add(item.id);
448
+ return next;
449
+ });
450
+ }
426
451
  };
427
- return (_jsxs(S.MenuItem, { "$disabled": item.disabled, "$hasSubmenu": !!item.submenu && item.submenu.length > 0, "$beginGroup": item.beginGroup, "data-disabled": item.disabled ? "true" : undefined, onMouseDown: handleClick, onMouseEnter: (e) => !isMobile && handleMouseEnter(item, e, depth + 1), onMouseLeave: () => !isMobile && handleMouseLeave(depth + 1), title: item.tooltip, children: [_jsxs(S.MenuItemContent, { children: [item.icon && _jsx(S.IconWrapper, { children: item.icon }), _jsx(S.MenuItemName, { children: item.name })] }), item.rightIcon && item.onRightIconClick && (_jsx(S.RightIconButton, { onClick: handleRightIconClick, onMouseDown: (e) => e.stopPropagation(), "aria-label": `Action for ${item.name}`, children: item.rightIcon })), item.submenu && item.submenu.length > 0 && (_jsx(S.SubmenuIndicator, { "$isMobile": isMobile, children: isMobile ? '›' : '▸' }))] }, itemKey));
452
+ // rightIconProps takes precedence over rightIcon
453
+ let rightIconElement = null;
454
+ let rightIconClickHandler = null;
455
+ if (item.rightIconProps) {
456
+ const rip = item.rightIconProps;
457
+ const wasToggled = item.id ? toggledItemIds.has(item.id) : false;
458
+ const isActive = wasToggled ? !rip.isActive : rip.isActive;
459
+ const color = isActive ? (rip.activeColor || '#d32f2f') : (rip.inactiveColor || '#626262');
460
+ rightIconElement = _jsx("span", { style: { color, display: 'flex', alignItems: 'center' }, children: rip.icon });
461
+ if (rip.onClick) {
462
+ rightIconClickHandler = handleRightIconPropsClick;
463
+ }
464
+ }
465
+ return (_jsxs(S.MenuItem, { "$disabled": item.disabled, "$hasSubmenu": !!item.submenu && item.submenu.length > 0, "$beginGroup": item.beginGroup, "data-disabled": item.disabled ? "true" : undefined, onMouseDown: handleClick, onMouseEnter: (e) => !isMobile && handleMouseEnter(item, e, depth + 1), onMouseLeave: () => !isMobile && handleMouseLeave(depth + 1), title: item.tooltip, children: [_jsxs(S.MenuItemContent, { children: [item.icon && _jsx(S.IconWrapper, { children: item.icon }), _jsx(S.MenuItemName, { children: item.name })] }), rightIconElement && rightIconClickHandler ? (_jsx(S.RightIconButton, { onClick: rightIconClickHandler, onMouseDown: (e) => e.stopPropagation(), "aria-label": `Action for ${item.name}`, children: rightIconElement })) : rightIconElement ? (_jsx(S.IconWrapper, { children: rightIconElement })) : null, item.submenu && item.submenu.length > 0 && (_jsx(S.SubmenuIndicator, { "$isMobile": isMobile, children: isMobile ? '›' : '▸' }))] }, itemKey));
428
466
  });
429
467
  };
430
468
  const currentParentName = menuState.parentNames.at(-1) || '';
@@ -433,7 +471,7 @@ const TMContextMenu = ({ items, trigger = 'right', children, target, externalCon
433
471
  handleClick(e);
434
472
  }
435
473
  }, role: "button", tabIndex: 0, style: {
436
- display: 'inline-block',
474
+ // display: 'inline-block',
437
475
  WebkitTouchCallout: isIOS ? 'none' : undefined,
438
476
  WebkitUserSelect: isIOS ? 'none' : undefined,
439
477
  }, children: children })), menuState.visible && createPortal(_jsxs(_Fragment, { children: [_jsxs(S.MenuContainer, { ref: menuRef, "$x": menuState.position.x, "$y": menuState.position.y, "$openLeft": openLeft, "$openUp": openUp, "$isPositioned": isCalculated, "$externalControl": !!externalControl, "$needsScroll": needsScroll, "$maxHeight": maxHeight, children: [isMobile && menuState.parentNames.length > 0 && (_jsxs(S.MobileMenuHeader, { children: [_jsx(S.BackButton, { onClick: handleBack, "aria-label": "Go back", children: _jsx(IconArrowLeft, {}) }), _jsx(S.HeaderTitle, { children: currentParentName })] })), renderMenuItems(currentMenu, 0)] }), !isMobile && hoveredSubmenus.map((submenu, idx) => (_jsx(S.Submenu, { "$parentRect": submenu.parentRect, "$openUp": submenu.openUp, "data-submenu": "true", onMouseEnter: handleSubmenuMouseEnter, onMouseLeave: () => handleMouseLeave(submenu.depth), children: renderMenuItems(submenu.items, submenu.depth) }, `submenu-${submenu.depth}-${idx}`)))] }), document.body)] }));
@@ -103,6 +103,8 @@ export const MenuItem = styled.div `
103
103
  transition: all 0.15s ease;
104
104
  position: relative;
105
105
  user-select: none;
106
+ -webkit-touch-callout: none;
107
+ -webkit-user-select: none;
106
108
  font-size: var(--base-font-size, 13px);
107
109
  color: ${props => props.$disabled ? '#999' : '#1a1a1a'};
108
110
  font-weight: 500;
@@ -237,11 +239,11 @@ export const Submenu = styled.div `
237
239
  position: fixed;
238
240
  left: ${props => {
239
241
  const spaceOnRight = globalThis.innerWidth - props.$parentRect.right;
240
- return spaceOnRight > 240 ? `${props.$parentRect.right - 8}px` : 'auto';
242
+ return spaceOnRight > 240 ? `${props.$parentRect.right - 4}px` : 'auto';
241
243
  }};
242
244
  right: ${props => {
243
245
  const spaceOnRight = globalThis.innerWidth - props.$parentRect.right;
244
- return spaceOnRight > 240 ? 'auto' : `${globalThis.innerWidth - props.$parentRect.left + 8}px`;
246
+ return spaceOnRight > 240 ? 'auto' : `${globalThis.innerWidth - props.$parentRect.left + 4}px`;
245
247
  }};
246
248
  /* Vertical positioning: Each submenu independently decides direction based on its own space */
247
249
  top: ${props => {
@@ -264,25 +266,25 @@ export const Submenu = styled.div `
264
266
  backdrop-filter: blur(10px);
265
267
  border: 1px solid rgba(0, 0, 0, 0.06);
266
268
 
267
- /* Add invisible padding to bridge the gap - works for both sides */
269
+ /* Invisible hover bridge on the LEFT side (for submenus opening left) */
268
270
  &::before {
269
271
  content: '';
270
272
  position: absolute;
271
273
  right: 100%;
272
- top: 0;
273
- bottom: 0;
274
- width: 15px;
274
+ top: -20px;
275
+ bottom: -20px;
276
+ width: 25px;
275
277
  background: transparent;
276
278
  }
277
279
 
278
- /* Bridge on the right side for nested submenus */
280
+ /* Invisible hover bridge on the RIGHT side (for submenus opening right) */
279
281
  &::after {
280
282
  content: '';
281
283
  position: absolute;
282
284
  left: 100%;
283
- top: 0;
284
- bottom: 0;
285
- width: 15px;
285
+ top: -20px;
286
+ bottom: -20px;
287
+ width: 25px;
286
288
  background: transparent;
287
289
  }
288
290
 
@@ -326,30 +328,7 @@ export const Submenu = styled.div `
326
328
  &::-webkit-scrollbar-thumb:hover {
327
329
  background: rgba(0, 0, 0, 0.3);
328
330
  }
329
- ` : `
330
- /* Fallback max-height for submenus that fit */
331
- max-height: calc(100vh - 40px);
332
- overflow-y: auto;
333
- overflow-x: hidden;
334
-
335
- &::-webkit-scrollbar {
336
- width: 8px;
337
- }
338
-
339
- &::-webkit-scrollbar-track {
340
- background: rgba(0, 0, 0, 0.05);
341
- border-radius: 4px;
342
- }
343
-
344
- &::-webkit-scrollbar-thumb {
345
- background: rgba(0, 0, 0, 0.2);
346
- border-radius: 4px;
347
- }
348
-
349
- &::-webkit-scrollbar-thumb:hover {
350
- background: rgba(0, 0, 0, 0.3);
351
- }
352
- `}
331
+ ` : ``}
353
332
 
354
333
  [data-theme='dark'] & {
355
334
  &::-webkit-scrollbar-track {
@@ -1,3 +1,10 @@
1
+ export interface RightIconProps {
2
+ icon: React.ReactNode;
3
+ activeColor?: string;
4
+ inactiveColor?: string;
5
+ isActive?: boolean;
6
+ onClick?: () => void;
7
+ }
1
8
  export interface TMContextMenuItemProps {
2
9
  id?: string;
3
10
  name: string;
@@ -6,8 +13,7 @@ export interface TMContextMenuItemProps {
6
13
  onClick?: (data?: any) => void;
7
14
  submenu?: TMContextMenuItemProps[];
8
15
  visible?: boolean;
9
- rightIcon?: React.ReactNode;
10
- onRightIconClick?: () => void;
16
+ rightIconProps?: RightIconProps;
11
17
  beginGroup?: boolean;
12
18
  tooltip?: string;
13
19
  operationType?: 'singleRow' | 'multiRow';