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:
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user