diff --git a/.changeset/happy-plums-work.md b/.changeset/happy-plums-work.md new file mode 100644 index 00000000000..428bb2b14cb --- /dev/null +++ b/.changeset/happy-plums-work.md @@ -0,0 +1,5 @@ +--- +"@primer/components": patch +--- + +Allow custom `children` in `ActionItem`. `text` and `description` can still be provided as a shortcut, but `children` is now available if you need more control over the rending of the item, without sacrificing benefits from `Item` by using `renderItem`. diff --git a/src/ActionList/Item.tsx b/src/ActionList/Item.tsx index f23821506f9..905b5c18065 100644 --- a/src/ActionList/Item.tsx +++ b/src/ActionList/Item.tsx @@ -13,7 +13,7 @@ export interface ItemProps extends React.ComponentPropsWithoutRef<'div'>, SxProp /** * Primary text which names an `Item`. */ - text: string + text?: string /** * Secondary text which provides additional information about an `Item`. @@ -179,6 +179,7 @@ export function Item(itemProps: Partial & {item?: ItemInput}): JSX.El disabled, onAction, onKeyPress, + children, onClick, ...props } = itemProps @@ -224,10 +225,13 @@ export function Item(itemProps: Partial & {item?: ItemInput}): JSX.El )} - -
{text}
- {description && {description}} -
+ {children} + {(text || description) && ( + + {text &&
{text}
} + {description && {description}} +
+ )} {(TrailingIcon || trailingText) && ( {trailingText &&
{trailingText}
} diff --git a/src/__tests__/ActionMenu.tsx b/src/__tests__/ActionMenu.tsx index e50936a1afc..bd5322be231 100644 --- a/src/__tests__/ActionMenu.tsx +++ b/src/__tests__/ActionMenu.tsx @@ -78,7 +78,7 @@ describe('ActionMenu', () => { }) portalRoot = menu.baseElement.querySelector('#__primerPortalRoot__') expect(portalRoot).toBeTruthy() - const menuItem = await menu.queryByText(items[0].text) + const menuItem = await menu.queryByText(items[0].text!) act(() => { fireEvent.click(menuItem as Element) }) diff --git a/src/stories/ActionList.stories.tsx b/src/stories/ActionList.stories.tsx index 40c48f7111a..d005557b54c 100644 --- a/src/stories/ActionList.stories.tsx +++ b/src/stories/ActionList.stories.tsx @@ -7,12 +7,14 @@ import { NoteIcon, ProjectIcon, FilterIcon, - GearIcon + GearIcon, + ArrowRightIcon, + ArrowLeftIcon } from '@primer/octicons-react' import {Meta} from '@storybook/react' import React from 'react' import styled from 'styled-components' -import {ThemeProvider} from '..' +import {Label, ThemeProvider} from '..' import {ActionList as _ActionList} from '../ActionList' import {Header} from '../ActionList/Header' import BaseStyles from '../BaseStyles' @@ -238,3 +240,27 @@ export function HeaderStory(): JSX.Element { ) } HeaderStory.storyName = 'Header' + +export function CustomItemChildren(): JSX.Element { + return ( + <> +

Custom Item Children

+ + + Choose this one + + ), + trailingIcon: ArrowLeftIcon + } + ]} + /> + + + ) +} +CustomItemChildren.storyName = 'Custom Item Children' diff --git a/src/stories/ActionMenu.stories.tsx b/src/stories/ActionMenu.stories.tsx index 9b7ca389b8b..45555283f3d 100644 --- a/src/stories/ActionMenu.stories.tsx +++ b/src/stories/ActionMenu.stories.tsx @@ -48,7 +48,7 @@ const ErsatzOverlay = styled.div` export function ActionsStory(): JSX.Element { const [option, setOption] = useState('Select an option') const onAction = (itemProps: ItemProps) => { - setOption(itemProps.text) + setOption(itemProps.text ?? '') } return ( <> @@ -85,7 +85,7 @@ ActionsStory.storyName = 'Actions' export function SimpleListStory(): JSX.Element { const [option, setOption] = useState('Select an option') const onAction = (itemProps: ItemProps) => { - setOption(itemProps.text) + setOption(itemProps.text || '') } return ( <> @@ -116,7 +116,7 @@ SimpleListStory.storyName = 'Simple List' export function ComplexListStory(): JSX.Element { const [option, setOption] = useState('Select an option') const onAction = (itemProps: ItemProps) => { - setOption(itemProps.text) + setOption(itemProps.text || '') } return ( <> @@ -177,7 +177,7 @@ export function CustomTrigger(): JSX.Element { const customAnchor = (props: LinkProps) => const [option, setOption] = useState('Select an option') const onAction = useCallback((itemProps: ItemProps) => { - setOption(itemProps.text) + setOption(itemProps.text || '') }, []) return ( <>