diff --git a/packages/react-component-library/src/components/ContextMenu/ContextMenu.stories.tsx b/packages/react-component-library/src/components/ContextMenu/ContextMenu.stories.tsx
index f336ad3966..8b3bfc3874 100644
--- a/packages/react-component-library/src/components/ContextMenu/ContextMenu.stories.tsx
+++ b/packages/react-component-library/src/components/ContextMenu/ContextMenu.stories.tsx
@@ -57,3 +57,44 @@ export const Default = () => {
}
Default.storyName = 'Default'
+
+export const NoIcons = () => {
+ const ref = useRef()
+
+ return (
+ <>
+
+ Right click me!
+
+
+
+ Edit} />
+ Delete} />
+ Action} />
+
+ Add} />
+
+ Do something else}
+ />
+
+
+ This is too much text to put into a context menu item
+
+ )}
+ />
+
+ >
+ )
+}
+
+NoIcons.storyName = 'No icons'
diff --git a/packages/react-component-library/src/components/ContextMenu/ContextMenu.test.tsx b/packages/react-component-library/src/components/ContextMenu/ContextMenu.test.tsx
index 922f6775b9..7423d0406e 100644
--- a/packages/react-component-library/src/components/ContextMenu/ContextMenu.test.tsx
+++ b/packages/react-component-library/src/components/ContextMenu/ContextMenu.test.tsx
@@ -2,6 +2,7 @@ import React, { useRef } from 'react'
import '@testing-library/jest-dom/extend-expect'
import { RenderResult, render, fireEvent, act } from '@testing-library/react'
import { IconSettings } from '@royalnavy/icon-library'
+import 'jest-styled-components'
import { ContextMenu, ContextMenuItem, ContextMenuDivider } from '.'
import { Link } from '../Link'
@@ -18,7 +19,7 @@ describe('ContextMenu', () => {
let wrapper: RenderResult
let onClickSpy: (e: React.MouseEvent) => void
- describe('With links and closed', () => {
+ describe('With links, no icons and closed', () => {
beforeEach(() => {
const ContextExample = () => {
const ref = useRef()
@@ -46,7 +47,7 @@ describe('ContextMenu', () => {
})
})
- describe('With links and open', () => {
+ describe('With links, no icons and and open', () => {
beforeEach(() => {
const ContextExample = () => {
const ref = useRef()
@@ -71,6 +72,12 @@ describe('ContextMenu', () => {
fireEvent.contextMenu(wrapper.getByText('Right click me!'))
})
+ it('should add margin to items', () => {
+ wrapper.getAllByTestId('context-menu-item-text').forEach((item) => {
+ expect(item).toHaveStyleRule('margin-left', '1.25rem')
+ })
+ })
+
it('is rendered to the DOM', () => {
expect(wrapper.queryByTestId('context-menu')).toBeInTheDocument()
})
@@ -149,6 +156,12 @@ describe('ContextMenu', () => {
fireEvent.contextMenu(wrapper.getByText('Right click me!'))
})
+ it('should not add margin to items', () => {
+ wrapper.getAllByTestId('context-menu-item-text').forEach((item) => {
+ expect(item).not.toHaveStyleRule('margin-left', '1.25rem')
+ })
+ })
+
it('renders the icons', () => {
expect(
wrapper.queryByTestId('context-menu-item-icon')
diff --git a/packages/react-component-library/src/components/ContextMenu/ContextMenu.tsx b/packages/react-component-library/src/components/ContextMenu/ContextMenu.tsx
index e6a127c0e8..79c9b4d11f 100644
--- a/packages/react-component-library/src/components/ContextMenu/ContextMenu.tsx
+++ b/packages/react-component-library/src/components/ContextMenu/ContextMenu.tsx
@@ -1,9 +1,10 @@
import React from 'react'
-import styled from 'styled-components'
+import styled, { css } from 'styled-components'
import { selectors } from '@royalnavy/design-tokens'
import { ComponentWithClass } from '../../common/ComponentWithClass'
import { useRightClick } from '../../hooks/useRightClick'
+import { StyledText } from './ContextMenuItem'
interface ContextMenuProps extends ComponentWithClass {
attachedToRef?: React.RefObject
@@ -12,6 +13,7 @@ interface ContextMenuProps extends ComponentWithClass {
interface StyledContextMenuProps {
top: number
left: number
+ $hasIcons: boolean
}
const { color, spacing } = selectors
@@ -28,6 +30,14 @@ const StyledContextMenu = styled.ol`
border-radius: 4px;
border: 1px solid ${color('neutral', '200')};
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.12), 0 1px 3px 0 rgba(0, 0, 0, 0.04);
+
+ ${({ $hasIcons }) =>
+ !$hasIcons &&
+ css`
+ ${StyledText} {
+ margin-left: 0;
+ }
+ `}
`
export const ContextMenu: React.FC = ({
@@ -37,6 +47,10 @@ export const ContextMenu: React.FC = ({
}) => {
const { position, isOpen } = useRightClick(attachedToRef)
+ const hasIcons = !!React.Children.toArray(children).filter(
+ (child: React.ReactNode) => (child as React.ReactElement)?.props?.icon
+ ).length
+
return (
<>
{isOpen && (
@@ -44,6 +58,7 @@ export const ContextMenu: React.FC = ({
className={className}
top={position.y}
left={position.x}
+ $hasIcons={hasIcons}
data-testid="context-menu"
>
{children}
diff --git a/packages/react-component-library/src/components/ContextMenu/ContextMenuItem.tsx b/packages/react-component-library/src/components/ContextMenu/ContextMenuItem.tsx
index 0003f4e1f2..ed4c74c331 100644
--- a/packages/react-component-library/src/components/ContextMenu/ContextMenuItem.tsx
+++ b/packages/react-component-library/src/components/ContextMenu/ContextMenuItem.tsx
@@ -14,8 +14,9 @@ interface StyledTextProps {
const { color, fontSize, spacing } = selectors
-const StyledContextMenuItem = styled.li`
+export const StyledContextMenuItem = styled.li`
border-radius: 2px;
+
> * {
text-overflow: ellipsis;
display: flex;
@@ -32,7 +33,7 @@ const StyledContextMenuItem = styled.li`
}
`
-const StyledIcon = styled.div`
+export const StyledIcon = styled.div`
display: inline-flex;
align-items: center;
margin-right: ${spacing('2')};
@@ -42,7 +43,7 @@ const StyledIcon = styled.div`
}
`
-const StyledText = styled.div`
+export const StyledText = styled.div`
color: ${color('neutral', '400')};
font-weight: 600;
font-size: ${fontSize('base')};
@@ -68,7 +69,9 @@ export const ContextMenuItem: React.FC = ({
children: (
<>
{icon && {icon}}
- {linkElement.props.children}
+
+ {linkElement.props.children}
+
>
),
})