| 1 |
import React, { useId } from 'react' |
| 2 |
import classnames from 'classnames' |
| 3 |
import { __ } from '@wordpress/i18n' |
| 4 |
import { trimTrailingChar } from '../../utils/text' |
| 5 |
import type { ReactNode } from 'react' |
| 6 |
|
| 7 |
export interface TooltipProps { |
| 8 |
block?: boolean |
| 9 |
inline?: boolean |
| 10 |
start?: boolean |
| 11 |
end?: boolean |
| 12 |
icon?: ReactNode |
| 13 |
children: ReactNode |
| 14 |
className?: classnames.Argument |
| 15 |
label?: string |
| 16 |
} |
| 17 |
|
| 18 |
export const Tooltip: React.FC<TooltipProps> = ({ |
| 19 |
block, inline, start, end, |
| 20 |
icon, |
| 21 |
className, |
| 22 |
children, |
| 23 |
label |
| 24 |
}) => { |
| 25 |
const tooltipId = useId() |
| 26 |
return ( |
| 27 |
<div className={classnames( |
| 28 |
'tooltip help-tooltip', |
| 29 |
{ 'tooltip-block': block, 'tooltip-inline': inline, 'tooltip-start': start, 'tooltip-end': end }, |
| 30 |
className |
| 31 |
)}> |
| 32 |
<button |
| 33 |
type="button" |
| 34 |
className="tooltip-trigger" |
| 35 |
aria-label={label ?? __('More information', 'code-snippets')} |
| 36 |
aria-describedby={tooltipId} |
| 37 |
> |
| 38 |
{icon ?? <span className="dashicons dashicons-editor-help" aria-hidden="true"></span>} |
| 39 |
</button> |
| 40 |
<div role="tooltip" className="tooltip-content" id={tooltipId}> |
| 41 |
{children} |
| 42 |
</div> |
| 43 |
</div> |
| 44 |
) |
| 45 |
} |
| 46 |
|
| 47 |
export const ErrorTooltip: React.FC<{ message: string }> = ({ message }) => |
| 48 |
<Tooltip |
| 49 |
block |
| 50 |
end |
| 51 |
label={__('Error', 'code-snippets')} |
| 52 |
icon={<span className="dashicons dashicons-warning" aria-hidden="true"></span>} |
| 53 |
> |
| 54 |
{`${trimTrailingChar(message, '.!?')}. ${__('Please try again.', 'code-snippets')}`} |
| 55 |
</Tooltip> |
| 56 |
|