diff --git a/packages/react-components/src/components/Tooltip/Tooltip.mdx b/packages/react-components/src/components/Tooltip/Tooltip.mdx index 31c46b3da..55c9f872a 100644 --- a/packages/react-components/src/components/Tooltip/Tooltip.mdx +++ b/packages/react-components/src/components/Tooltip/Tooltip.mdx @@ -6,26 +6,210 @@ import * as Stories from './Tooltip.stories'; Tooltip -[Intro](#Intro) | [Component API](#ComponentAPI) | [Content Spec](#ContentSpec) +[Intro](#Intro) | [Usage](#Usage) | [Component API](#ComponentAPI) | [Content Spec](#ContentSpec) ## Intro -### Simple Tooltip +The Tooltip component provides contextual information when users interact with elements in your application. It enhances user experience by offering additional insights without cluttering the interface. + +## Usage + +- [Default Tooltip](#DefaultTooltip) +- [Info Tooltip](#InfoTooltip) +- [Interactive Tooltip](#InteractiveTooltip) +- [Reports Tooltip](#ReportsTooltip) +- [User Guide Tooltip](#UserGuideTooltip) + + +### Default Tooltip + +A simple tooltip that appears on hover or focus. + +```tsx +import { Tooltip, Button } from '@livechat/design-system-react-components'; + +Trigger}> + Simple text content +; +``` -### Info Tooltip +### Info Tooltip + +A tooltip with additional header and close button. + +```tsx +import { + Tooltip, + Button, + Info, +} from '@livechat/design-system-react-components'; + +Trigger}> + {}} + /> +; +``` -### Interactive Tooltip +### Interactive Tooltip + +A tooltip that can be interacted with. + +```tsx +import { + Tooltip, + Interactive, + Button, +} from '@livechat/design-system-react-components'; + +Trigger}> + {}, + label: 'Primary Button', + }} + secondaryButton={{ + handleClick: () => {}, + label: 'Secondary', + }} + /> +; +``` -### Reports Tooltip +### Reports Tooltip + +A tooltip that displays a report view. + +```tsx +import { + Tooltip, + Reports, + Button, +} from '@livechat/design-system-react-components'; + +Trigger}> + +
Reports component content
+
+ +
Reports component content
+
+ +
Reports component content
+
+
+``` +### User Guide Tooltip
+ +A simple user guide that can be used to guide users through a series of steps. + +```tsx +import { + UserGuide, + Button, +} from '@livechat/design-system-react-components'; + +const reducer = ( + state: { isVisible: boolean; reference: string }, + action: { type: string } +) => { + if (action.type === 'reference1') { + return { + ...state, + reference: 'reference1', + }; + } + if (action.type === 'reference2') { + return { + ...state, + reference: 'reference2', + }; + } + if (action.type === 'reference3') { + return { + ...state, + reference: 'reference3', + }; + } + if (action.type === 'isVisible') { + return { + reference: 'reference1', + isVisible: !state.isVisible, + }; + } + + return state; +}; + +const [state, dispatch] = React.useReducer(reducer, { + reference: 'reference1', + isVisible: false, +}); + +return ( +
+ +
+
dispatch({ type: 'reference1' })} + id="reference1" + className="guide-reference" + > + Example reference 1 +
+
dispatch({ type: 'reference2' })} + id="reference2" + className="guide-reference" + > + Example reference 2 +
+ +
dispatch({ type: 'reference3' })} + id="reference3" + className="guide-reference" + > + Example reference 3 +
+ + + {state.reference === 'reference1' && } + {state.reference === 'reference2' && } + {state.reference === 'reference3' && } + +
+
+); + +``` + + + ## Component API
diff --git a/packages/react-components/src/components/Tooltip/Tooltip.module.scss b/packages/react-components/src/components/Tooltip/Tooltip.module.scss index a6123fc93..51d630052 100644 --- a/packages/react-components/src/components/Tooltip/Tooltip.module.scss +++ b/packages/react-components/src/components/Tooltip/Tooltip.module.scss @@ -105,12 +105,12 @@ $radius: var(--radius-3); justify-content: space-between; margin: var(--spacing-4) 0 0; - &-secondary { - margin-left: var(--spacing-4); - } - &--interactive { justify-content: flex-start; + + button:not(:first-child) { + margin-left: var(--spacing-4); + } } &--user-guide-step { diff --git a/packages/react-components/src/components/Tooltip/Tooltip.stories.css b/packages/react-components/src/components/Tooltip/Tooltip.stories.css index af989e641..ae63d4bd4 100644 --- a/packages/react-components/src/components/Tooltip/Tooltip.stories.css +++ b/packages/react-components/src/components/Tooltip/Tooltip.stories.css @@ -19,6 +19,33 @@ height: 800px; } +.simple-user-guide-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 20px; +} + +.guide-container { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: 20px; +} + +.guide-reference { + display: flex; + align-items: center; + justify-content: center; + border: 1px dashed var(--border-default); + border-radius: 4px; + background-color: var(--surface-basic-default); + font-size: 18px; + padding: 10px; +} + .tooltip-preview-reports { display: flex; align-items: center; @@ -32,7 +59,7 @@ .tooltip-story { display: flex; - align-items: center; + align-items: flex-start; justify-content: center; margin: auto; width: 700px; diff --git a/packages/react-components/src/components/Tooltip/Tooltip.stories.tsx b/packages/react-components/src/components/Tooltip/Tooltip.stories.tsx index 3b4175366..25e309ba3 100644 --- a/packages/react-components/src/components/Tooltip/Tooltip.stories.tsx +++ b/packages/react-components/src/components/Tooltip/Tooltip.stories.tsx @@ -49,7 +49,6 @@ export default { }, }, parameters: { - layout: 'top', controls: { expanded: true }, chromatic: { delay: 300 }, }, @@ -107,7 +106,6 @@ export const TooltipInfo = (args: ITooltipProps): React.ReactElement => ( theme={args.kind || args.theme} header="Header - concise and clear" text="Tooltip content is used to explain the details of elements or features." - closeWithX handleCloseAction={noop} /> @@ -133,7 +131,7 @@ export const TooltipInteractive = (args: ITooltipProps): React.ReactElement => ( alt: 'image', }} text="Tooltip content is used to explain the details of elements or features." - closeWithX + handleCloseAction={noop} primaryButton={{ handleClick: noop, label: 'Primary Button', @@ -183,13 +181,111 @@ TooltipReports.decorators = [ ), ]; -export const TooltipUserGuide = (args: ITooltipProps): React.ReactElement => ( +export const SimpleUserGuide = (): React.ReactElement => { + const reducer = ( + state: { isVisible: boolean; reference: string }, + action: { type: string } + ) => { + if (action.type === 'reference1') { + return { + ...state, + reference: 'reference1', + }; + } + if (action.type === 'reference2') { + return { + ...state, + reference: 'reference2', + }; + } + if (action.type === 'reference3') { + return { + ...state, + reference: 'reference3', + }; + } + if (action.type === 'isVisible') { + return { + reference: 'reference1', + isVisible: !state.isVisible, + }; + } + + return state; + }; + + const [state, dispatch] = React.useReducer(reducer, { + reference: 'reference1', + isVisible: false, + }); + + return ( +
+ +
+
dispatch({ type: 'reference1' })} + id="reference1" + className="guide-reference" + > + Example reference 1 +
+
dispatch({ type: 'reference2' })} + id="reference2" + className="guide-reference" + > + Example reference 2 +
+ +
dispatch({ type: 'reference3' })} + id="reference3" + className="guide-reference" + > + Example reference 3 +
+ + + {state.reference === 'reference1' ? ( + + ) : null} + + {state.reference === 'reference2' ? ( + + ) : null} + + {state.reference === 'reference3' ? ( + + ) : null} + +
+
+ ); +}; + +export const ExtendedContentUserGuide = ( + args: ITooltipProps +): React.ReactElement => (
); -TooltipUserGuide.args = { +ExtendedContentUserGuide.args = { placement: 'bottom', isVisible: true, theme: 'default', @@ -244,7 +340,7 @@ const TooltipUserGuideExample: React.FC = (props) => { return (
component', () => { userEvent.click(button); expect(onClose).toHaveBeenCalledTimes(1); }); + + it('should render close button if handleCloseAction is provided and call the handler after user click', () => { + const onClose = vi.fn(); + const { getByRole } = renderComponent({ + ...defaultProps, + handleCloseAction: onClose, + }); + const button = getByRole('button'); + expect(button).toBeInTheDocument(); + userEvent.click(button); + expect(onClose).toHaveBeenCalledTimes(1); + }); }); diff --git a/packages/react-components/src/components/Tooltip/components/Info.tsx b/packages/react-components/src/components/Tooltip/components/Info.tsx index 44d9b6f12..120ed9045 100644 --- a/packages/react-components/src/components/Tooltip/components/Info.tsx +++ b/packages/react-components/src/components/Tooltip/components/Info.tsx @@ -21,7 +21,7 @@ export const Info: React.FC = ({ }) => { return (
- {closeWithX && ( + {(closeWithX || handleCloseAction) && ( + ); + }; + return (
- {closeWithX && ( + {(closeWithX || handleCloseAction) && ( - - {secondaryButton && ( - - )} + {renderButton(primaryButton, true)} + {renderButton(secondaryButton, false)}
); diff --git a/packages/react-components/src/components/Tooltip/components/UserGuide/UserGuideStep.tsx b/packages/react-components/src/components/Tooltip/components/UserGuide/UserGuideStep.tsx index 6fed2d91b..20024a6e4 100644 --- a/packages/react-components/src/components/Tooltip/components/UserGuide/UserGuideStep.tsx +++ b/packages/react-components/src/components/Tooltip/components/UserGuide/UserGuideStep.tsx @@ -83,7 +83,7 @@ export const UserGuideStep: React.FC<{ Step {currentStep} of {stepMax}
diff --git a/packages/react-components/src/components/Tooltip/index.ts b/packages/react-components/src/components/Tooltip/index.ts index 75d679627..d6937a2ad 100644 --- a/packages/react-components/src/components/Tooltip/index.ts +++ b/packages/react-components/src/components/Tooltip/index.ts @@ -5,4 +5,5 @@ export type { ITooltipProps, ITooltipInfoProps, ITooltipInteractiveProps, + TooltipButton, } from './types'; diff --git a/packages/react-components/src/components/Tooltip/types.ts b/packages/react-components/src/components/Tooltip/types.ts index f693bfc25..bc3b85a77 100644 --- a/packages/react-components/src/components/Tooltip/types.ts +++ b/packages/react-components/src/components/Tooltip/types.ts @@ -176,6 +176,7 @@ export interface ITooltipInfoProps { text: string; /** * Set to show close button + * @deprecated Use `handleCloseAction` instead */ closeWithX?: boolean; /** @@ -206,6 +207,7 @@ export interface ITooltipInteractiveProps { }; /** * Set to show close button + * @deprecated Use `handleCloseAction` instead */ closeWithX?: boolean; /** @@ -219,9 +221,9 @@ export interface ITooltipInteractiveProps { /** * The Interactive tooltip primary button props */ - primaryButton: TooltipButton; + primaryButton: TooltipButton | React.ReactNode; /** * The Interactive tooltip secondary button props */ - secondaryButton?: TooltipButton; + secondaryButton?: TooltipButton | React.ReactNode; }