From f6ea5ff62e0d2df7acb31de23083a69de3fc4c1b Mon Sep 17 00:00:00 2001 From: dgreif Date: Thu, 29 Apr 2021 16:06:08 -0700 Subject: [PATCH] Allow custom `children` in `ActionItem` --- src/ActionList/Item.tsx | 19 ++++++++++++++----- src/__tests__/ActionMenu.tsx | 2 +- src/stories/ActionList.stories.tsx | 30 ++++++++++++++++++++++++++++-- src/stories/ActionMenu.stories.tsx | 8 ++++---- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/ActionList/Item.tsx b/src/ActionList/Item.tsx index 03d4d72ad79..2da6c1c7d06 100644 --- a/src/ActionList/Item.tsx +++ b/src/ActionList/Item.tsx @@ -13,13 +13,18 @@ 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`. */ description?: string + /** + * Custom children content to show if text/description is not flexible enough. If supplied, leading/traling elements can still be used. + */ + children?: React.ReactNode + /** * Secondary text style variations. Usage is discretionary. * @@ -179,6 +184,7 @@ export function Item(itemProps: Partial & {item?: ItemInput}): JSX.El disabled, onAction, onKeyPress, + children, onClick, ...props } = itemProps @@ -224,10 +230,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..345eaac7a99 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 + } + ]} + /> + + + ) +} +SimpleListStory.storyName = 'Simple List' diff --git a/src/stories/ActionMenu.stories.tsx b/src/stories/ActionMenu.stories.tsx index 9b7ca389b8b..57055e6bc9e 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 ( <>