feat: display only one card action overflow menu (#2427)

Instead of stopping whole click event propagation from actions to card element, specifically stop click event if the source target is actions menu.
This commit is contained in:
Navin Karkera
2025-09-09 03:17:17 +05:30
committed by GitHub
parent 87239ab723
commit 720b591add
7 changed files with 121 additions and 93 deletions

View File

@@ -7,11 +7,12 @@ import {
Stack,
} from '@openedx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
import { getItemIcon, getComponentStyleColor } from '@src/generic/block-type-utils';
import ComponentCount from '@src/generic/component-count';
import TagCount from '@src/generic/tag-count';
import { BlockTypeLabel, type ContentHitTags, Highlight } from '@src/search-manager';
import { skipIfUnwantedTarget } from '@src/utils';
import messages from './messages';
import { getItemIcon, getComponentStyleColor } from '../../generic/block-type-utils';
import ComponentCount from '../../generic/component-count';
import TagCount from '../../generic/tag-count';
import { BlockTypeLabel, type ContentHitTags, Highlight } from '../../search-manager';
type BaseCardProps = {
itemType: string;
@@ -52,7 +53,7 @@ const BaseCard = ({
<Container className="library-item-card selected">
<Card
isClickable
onClick={onSelect}
onClick={(e: React.MouseEvent) => skipIfUnwantedTarget(e, onSelect)}
onKeyDown={(e: React.KeyboardEvent) => {
if (['Enter', ' '].includes(e.key)) {
onSelect();
@@ -65,12 +66,13 @@ const BaseCard = ({
title={
<Icon src={itemIcon} className="library-item-header-icon" />
}
actions={
// Wrap the actions in a div to prevent the card from being clicked when the actions are clicked
/* eslint-disable-next-line jsx-a11y/click-events-have-key-events,
jsx-a11y/no-static-element-interactions */
<div onClick={(e) => e.stopPropagation()}>{actions}</div>
}
actions={(
<div
// Prevent card being clicked when actions menu are clicked
className="stop-event-propagation"
>{actions}
</div>
)}
/>
<Card.Body className="w-100">
<Card.Section>

View File

@@ -24,7 +24,7 @@ import { ToastContext } from '../../generic/toast-context';
import TagCount from '../../generic/tag-count';
import { useLibraryRoutes } from '../routes';
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
import { useRunOnNextRender } from '../../utils';
import { skipIfUnwantedTarget, useRunOnNextRender } from '../../utils';
import { ContainerMenu } from '../containers/ContainerCard';
interface LibraryContainerChildrenProps {
@@ -76,7 +76,7 @@ const ContainerRow = ({ containerKey, container, readOnly }: ContainerRowProps)
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
<div
// Prevent parent card from being clicked.
onClick={(e) => e.stopPropagation()}
className="stop-event-propagation"
>
<InplaceTextEditor
onSave={handleSaveDisplayName}
@@ -90,8 +90,7 @@ const ContainerRow = ({ containerKey, container, readOnly }: ContainerRowProps)
direction="horizontal"
gap={3}
// Prevent parent card from being clicked.
/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
onClick={(e) => e.stopPropagation()}
className="stop-event-propagation"
>
{!showOnlyPublished && container.hasUnpublishedChanges && (
<Badge
@@ -230,7 +229,7 @@ export const LibraryContainerChildren = ({ containerKey, readOnly }: LibraryCont
borderLeft: '8px solid #E1DDDB',
}}
isClickable={!readOnly}
onClick={(e) => handleChildClick(child, e.detail)}
onClick={(e) => skipIfUnwantedTarget(e, (event) => handleChildClick(child, event.detail))}
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleChildClick(child, 1);

View File

@@ -7,16 +7,18 @@ import classNames from 'classnames';
import {
useCallback, useContext, useEffect, useState,
} from 'react';
import { blockTypes } from '../../editors/data/constants/app';
import DraggableList, { SortableItem } from '../../generic/DraggableList';
import { blockTypes } from '@src/editors/data/constants/app';
import DraggableList, { SortableItem } from '@src/generic/DraggableList';
import ErrorAlert from '../../generic/alert-error';
import { getItemIcon } from '../../generic/block-type-utils';
import { COMPONENT_TYPES } from '../../generic/block-type-utils/constants';
import { IframeProvider } from '../../generic/hooks/context/iFrameContext';
import { InplaceTextEditor } from '../../generic/inplace-text-editor';
import Loading from '../../generic/Loading';
import TagCount from '../../generic/tag-count';
import ErrorAlert from '@src/generic/alert-error';
import { getItemIcon } from '@src/generic/block-type-utils';
import { COMPONENT_TYPES } from '@src/generic/block-type-utils/constants';
import { IframeProvider } from '@src/generic/hooks/context/iFrameContext';
import { InplaceTextEditor } from '@src/generic/inplace-text-editor';
import Loading from '@src/generic/Loading';
import TagCount from '@src/generic/tag-count';
import { ToastContext } from '@src/generic/toast-context';
import { skipIfUnwantedTarget, useRunOnNextRender } from '@src/utils';
import { useLibraryContext } from '../common/context/LibraryContext';
import ComponentMenu from '../components';
import { LibraryBlockMetadata } from '../data/api';
@@ -28,9 +30,7 @@ import {
import { LibraryBlock } from '../LibraryBlock';
import messages from './messages';
import { SidebarActions, SidebarBodyItemId, useSidebarContext } from '../common/context/SidebarContext';
import { ToastContext } from '../../generic/toast-context';
import { canEditComponent } from '../components/ComponentEditorModal';
import { useRunOnNextRender } from '../../utils';
/** Components that need large min height in preview */
const LARGE_COMPONENTS = [
@@ -91,9 +91,7 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
<Stack
direction="horizontal"
gap={2}
className="font-weight-bold"
// Prevent parent card from being clicked.
onClick={(e) => e.stopPropagation()}
className="font-weight-bold stop-event-propagation"
>
<Icon src={getItemIcon(block.blockType)} />
<InplaceTextEditor
@@ -106,8 +104,7 @@ const BlockHeader = ({ block, readOnly }: ComponentBlockProps) => {
<Stack
direction="horizontal"
gap={3}
// Prevent parent card from being clicked.
onClick={(e) => e.stopPropagation()}
className="stop-event-propagation"
>
{!showOnlyPublished && block.hasUnpublishedChanges && (
<Badge
@@ -185,7 +182,7 @@ const ComponentBlock = ({ block, readOnly, isDragging }: ComponentBlockProps) =>
borderBottom: 'solid 1px #E1DDDB',
}}
isClickable={!readOnly}
onClick={(e) => handleComponentSelection(e.detail)}
onClick={(e) => skipIfUnwantedTarget(e, (event) => handleComponentSelection(event.detail))}
onKeyDown={(e) => {
if (e.key === 'Enter') {
handleComponentSelection(e.detail);