@topconsultnpm/sdkui-react 6.20.0-dev1.47 → 6.20.0-dev1.48

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.
@@ -136,7 +136,7 @@ const TMContextMenu = ({ items, trigger = 'right', children, externalControl, ke
136
136
  };
137
137
  // iOS-specific touch handlers for long press
138
138
  const handleTouchStart = (e) => {
139
- if (!isIOS || trigger !== 'right')
139
+ if (!isIOS)
140
140
  return;
141
141
  const touch = e.touches[0];
142
142
  touchStartPos.current = { x: touch.clientX, y: touch.clientY };
@@ -176,7 +176,6 @@ const TMContextMenu = ({ items, trigger = 'right', children, externalControl, ke
176
176
  const handleTouchEnd = () => {
177
177
  if (!isIOS)
178
178
  return;
179
- // Clear long press timeout if touch ended before long press completed
180
179
  if (longPressTimeoutRef.current) {
181
180
  clearTimeout(longPressTimeoutRef.current);
182
181
  longPressTimeoutRef.current = null;
@@ -186,23 +185,19 @@ const TMContextMenu = ({ items, trigger = 'right', children, externalControl, ke
186
185
  const handleItemClick = (item) => {
187
186
  if (item.disabled)
188
187
  return;
189
- // Always execute onClick if present
190
188
  if (item.onClick) {
191
189
  item.onClick();
192
190
  }
193
191
  if (item.submenu && item.submenu.length > 0) {
194
192
  if (isMobile) {
195
- // Mobile: Push submenu to stack
196
193
  setMenuState(prev => ({
197
194
  ...prev,
198
195
  submenuStack: [...prev.submenuStack, item.submenu],
199
196
  parentNames: [...prev.parentNames, item.name],
200
197
  }));
201
198
  }
202
- // Desktop: Submenus are handled by hover, don't close menu
203
199
  }
204
200
  else {
205
- // No submenu: close menu after executing action (unless keepOpenOnClick is true)
206
201
  if (!keepOpenOnClick) {
207
202
  handleClose();
208
203
  }
@@ -292,17 +292,70 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
292
292
  const handleMouseUp = useCallback(() => {
293
293
  setState(s => ({ ...s, isDragging: false }));
294
294
  }, []);
295
+ // Touch event handlers for tablet support
296
+ const handleTouchStart = (e) => {
297
+ if (state.isConfigMode)
298
+ return;
299
+ const touch = e.touches[0];
300
+ const containerRect = containerRef.current?.getBoundingClientRect();
301
+ if (containerRect) {
302
+ if (isConstrained) {
303
+ dragOffset.current = {
304
+ x: touch.clientX - containerRect.left - state.position.x,
305
+ y: touch.clientY - containerRect.top - state.position.y,
306
+ };
307
+ }
308
+ else {
309
+ dragOffset.current = {
310
+ x: touch.clientX - state.position.x,
311
+ y: touch.clientY - state.position.y,
312
+ };
313
+ }
314
+ }
315
+ setState(s => ({ ...s, isDragging: true }));
316
+ };
317
+ const handleTouchMove = useCallback((e) => {
318
+ if (!state.isDragging || !containerRef.current || !floatingRef.current)
319
+ return;
320
+ const touch = e.touches[0];
321
+ const container = containerRef.current.getBoundingClientRect();
322
+ const floating = floatingRef.current.getBoundingClientRect();
323
+ let newX, newY;
324
+ if (isConstrained) {
325
+ newX = touch.clientX - container.left - dragOffset.current.x;
326
+ newY = touch.clientY - container.top - dragOffset.current.y;
327
+ newX = Math.max(0, Math.min(newX, container.width - floating.width));
328
+ newY = Math.max(0, Math.min(newY, container.height - floating.height));
329
+ }
330
+ else {
331
+ newX = touch.clientX - dragOffset.current.x;
332
+ newY = touch.clientY - dragOffset.current.y;
333
+ newX = Math.max(0, Math.min(newX, window.innerWidth - floating.width));
334
+ newY = Math.max(0, Math.min(newY, window.innerHeight - floating.height));
335
+ }
336
+ setState(s => ({
337
+ ...s,
338
+ position: { x: newX, y: newY },
339
+ }));
340
+ }, [state.isDragging, containerRef, isConstrained]);
341
+ const handleTouchEnd = useCallback(() => {
342
+ setState(s => ({ ...s, isDragging: false }));
343
+ }, []);
295
344
  useEffect(() => {
296
345
  if (state.isDragging) {
297
346
  document.addEventListener('mousemove', handleMouseMove);
298
347
  document.addEventListener('mouseup', handleMouseUp);
348
+ document.addEventListener('touchmove', handleTouchMove);
349
+ document.addEventListener('touchend', handleTouchEnd);
299
350
  return () => {
300
351
  document.removeEventListener('mousemove', handleMouseMove);
301
352
  document.removeEventListener('mouseup', handleMouseUp);
353
+ document.removeEventListener('touchmove', handleTouchMove);
354
+ document.removeEventListener('touchend', handleTouchEnd);
302
355
  };
303
356
  }
304
357
  return undefined;
305
- }, [state.isDragging, handleMouseMove, handleMouseUp]);
358
+ }, [state.isDragging, handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
306
359
  // Save to SDKUI_Globals.userSettings only when NOT in config mode (when applying changes)
307
360
  useEffect(() => {
308
361
  if (state.isConfigMode)
@@ -530,7 +583,7 @@ const TMFloatingMenuBar = ({ containerRef, contextMenuItems = [], isConstrained
530
583
  name: state.orientation === 'horizontal' ? 'Floating bar verticale' : 'Floating bar orizzontale',
531
584
  onClick: toggleOrientation,
532
585
  },
533
- ], trigger: "right", children: _jsx(S.GripHandle, { "$orientation": state.orientation, onMouseDown: handleMouseDown, onDoubleClick: handleGripDoubleClick, children: _jsx(IconDraggableDots, {}) }) })) : (_jsx(S.GripHandle, { "$orientation": state.orientation, onMouseDown: handleMouseDown, onDoubleClick: handleGripDoubleClick, children: _jsx(IconDraggableDots, {}) })), _jsx(S.Separator, { "$orientation": state.orientation }), state.items.map((item, index) => {
586
+ ], trigger: "right", children: _jsx(S.GripHandle, { "$orientation": state.orientation, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onDoubleClick: handleGripDoubleClick, children: _jsx(IconDraggableDots, {}) }) })) : (_jsx(S.GripHandle, { "$orientation": state.orientation, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, onDoubleClick: handleGripDoubleClick, children: _jsx(IconDraggableDots, {}) })), _jsx(S.Separator, { "$orientation": state.orientation }), state.items.map((item, index) => {
534
587
  // Get current state (disabled and onClick) from contextMenuItems
535
588
  const currentState = getCurrentItemState(item.id);
536
589
  const isDisabled = currentState.disabled || false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react",
3
- "version": "6.20.0-dev1.47",
3
+ "version": "6.20.0-dev1.48",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",