diff --git a/packages/components/src/spectrum/ItemTooltip.scss b/packages/components/src/spectrum/ItemTooltip.scss new file mode 100644 index 0000000000..33001f5942 --- /dev/null +++ b/packages/components/src/spectrum/ItemTooltip.scss @@ -0,0 +1,19 @@ +.dh-item-tooltip { + --item-tooltip-description-color: var(--spectrum-global-color-gray-700); + --item-tooltip-description-font-size: var( + --spectrum-global-dimension-font-size-75 + ); +} + +/** + * The Spectrum ListView styles for item descriptions only apply when the + * description is a child of the ListViewItem. For example, here is a selector + * for the styles: + * .C64cMW_react-spectrum-ListViewItem .C64cMW_react-spectrum-ListViewItem-description + * This will not work in Tooltips where there isn't a wrapping ListViewItem, so + * we copy the necessary styles. + */ +.dh-item-tooltip-description { + color: var(--item-tooltip-description-color); + font-size: var(--item-tooltip-description-font-size); +} diff --git a/packages/components/src/spectrum/ItemTooltip.tsx b/packages/components/src/spectrum/ItemTooltip.tsx index a86588d2ff..2b6823ebf2 100644 --- a/packages/components/src/spectrum/ItemTooltip.tsx +++ b/packages/components/src/spectrum/ItemTooltip.tsx @@ -1,9 +1,11 @@ -import { ReactNode } from 'react'; +import { Children, cloneElement, ReactElement, ReactNode } from 'react'; +import cl from 'classnames'; import { isElementOfType } from '@deephaven/react-hooks'; import { TooltipOptions } from './utils'; import { Tooltip } from '../popper'; import { Flex } from './layout'; -import { Text } from './Text'; +import { Text, TextProps } from './Text'; +import './ItemTooltip.scss'; export interface ItemTooltipProps { children: ReactNode; @@ -18,13 +20,27 @@ export function ItemTooltip({ options, }: ItemTooltipProps): JSX.Element { if (Array.isArray(children)) { + // Multiple children scenarios include a `` node for the label and at + // least 1 of an optional icon or `` node. In such + // cases we only show the label and description `` nodes. + const textElements: ReactElement[] = children.filter(node => + isElementOfType(node, Text) + ); + return ( - - {/* Multiple children scenarios include a `` node for the label - and at least 1 of an optional icon or `` node. - In such cases we only show the label and description `` nodes. */} + - {children.filter(node => isElementOfType(node, Text))} + {Children.map(textElements, textEl => + textEl.props.slot === 'description' + ? cloneElement(textEl, { + ...textEl.props, + UNSAFE_className: cl( + textEl.props.UNSAFE_className, + 'dh-item-tooltip-description' + ), + }) + : textEl + )} );