From 430c7faa987ef135906044b299ae8cb7acc4b77d Mon Sep 17 00:00:00 2001 From: Dmitri Date: Thu, 25 Jun 2026 11:45:28 +0200 Subject: [PATCH] fixed effects for disabled buttons --- frontend/src/components/Constructor/CanvasElement.tsx | 11 ++++++++--- frontend/src/components/RuntimeElement.tsx | 10 +++++----- frontend/src/pages/constructor.tsx | 6 ++++++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/Constructor/CanvasElement.tsx b/frontend/src/components/Constructor/CanvasElement.tsx index 29c88a9..f72695b 100644 --- a/frontend/src/components/Constructor/CanvasElement.tsx +++ b/frontend/src/components/Constructor/CanvasElement.tsx @@ -26,6 +26,8 @@ interface CanvasElementProps { element: CanvasElementType; isSelected: boolean; isEditMode: boolean; + /** Whether constructor interact-mode action should be ignored for this element */ + isDisabled?: boolean; onClick: () => void; onMouseDown?: (event: React.MouseEvent) => void; /** Optional URL resolver for preloaded blob URLs */ @@ -54,6 +56,7 @@ const CanvasElement: React.FC = ({ element, isSelected, isEditMode, + isDisabled = false, onClick, onMouseDown, resolveUrl, @@ -112,7 +115,8 @@ const CanvasElement: React.FC = ({ // Uses resolveUrl prop to resolve preloaded blob URLs useAudioEffects({ hoverAudioUrl: isEditMode ? undefined : effectProperties.hoverAudioUrl, - clickAudioUrl: isEditMode ? undefined : effectProperties.clickAudioUrl, + clickAudioUrl: + isEditMode || isDisabled ? undefined : effectProperties.clickAudioUrl, volume: parseFloat(effectProperties.audioVolume || '1'), isHovered: effectState.isHovered, isActive: effectState.isActive, @@ -155,11 +159,11 @@ const CanvasElement: React.FC = ({ // Wrapped click handler - toggles persistence state in preview mode // Skip toggle for info panel elements (their visibility is tied to panel open state) const handleClick = useCallback(() => { - if (!isEditMode && !isInfoPanelElementType(element.type)) { + if (!isEditMode && !isDisabled && !isInfoPanelElementType(element.type)) { onPersistClick(); // Toggle persistence state for hover reveal } onClick(); - }, [isEditMode, element.type, onPersistClick, onClick]); + }, [isEditMode, isDisabled, element.type, onPersistClick, onClick]); // Handle keyboard interaction for accessibility const handleKeyDown = (event: React.KeyboardEvent) => { @@ -182,6 +186,7 @@ const CanvasElement: React.FC = ({ onMouseDown={isEditMode ? onMouseDown : undefined} onClick={handleClick} onKeyDown={handleKeyDown} + aria-disabled={isDisabled} {...(!isEditMode && !needsEffectWrapper ? eventHandlers : {})} > {needsEffectWrapper ? ( diff --git a/frontend/src/components/RuntimeElement.tsx b/frontend/src/components/RuntimeElement.tsx index 1a8406b..893e3cd 100644 --- a/frontend/src/components/RuntimeElement.tsx +++ b/frontend/src/components/RuntimeElement.tsx @@ -72,7 +72,7 @@ const RuntimeElement: React.FC = ({ eventHandlers, onPersistClick, state: effectState, - } = useElementEffects(isDisabled ? {} : effectProperties, { + } = useElementEffects(effectProperties, { resetKey: element.id, // Reset reveal on element change forceVisible: isInfoPanelOpen, }); @@ -80,7 +80,7 @@ const RuntimeElement: React.FC = ({ // Audio effects - uses exposed state from useElementEffects // resolveUrl prop resolves to preloaded blob URLs via RuntimePresentation useAudioEffects({ - hoverAudioUrl: isDisabled ? undefined : effectProperties.hoverAudioUrl, + hoverAudioUrl: effectProperties.hoverAudioUrl, clickAudioUrl: isDisabled ? undefined : effectProperties.clickAudioUrl, volume: parseFloat(effectProperties.audioVolume || '1'), isHovered: effectState.isHovered, @@ -148,7 +148,7 @@ const RuntimeElement: React.FC = ({ ); // Check if we need the inner wrapper for effects - const needsEffectWrapper = !isDisabled && hasAnyEffects(effectProperties); + const needsEffectWrapper = hasAnyEffects(effectProperties); return (
= ({ style={positionStyle} onClick={handleClick} onKeyDown={handleKeyDown} - tabIndex={isDisabled ? -1 : 0} + tabIndex={0} aria-disabled={isDisabled} - {...(!isDisabled && !needsEffectWrapper ? eventHandlers : {})} + {...(!needsEffectWrapper ? eventHandlers : {})} > {needsEffectWrapper ? ( // Inner wrapper handles hover/focus/active effects independently from animation diff --git a/frontend/src/pages/constructor.tsx b/frontend/src/pages/constructor.tsx index a4ec698..028c8d4 100644 --- a/frontend/src/pages/constructor.tsx +++ b/frontend/src/pages/constructor.tsx @@ -2160,6 +2160,12 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => { element={element} isSelected={selectedElementId === element.id} isEditMode={isConstructorEditMode} + isDisabled={ + (isNavigationElementType(element.type) && + Boolean(element.navDisabled)) || + (isInfoPanelElementType(element.type) && + Boolean(element.infoPanelDisabled)) + } onClick={() => onCanvasElementClick(element)} onMouseDown={(event) => onElementMouseDown(event, element.id)