Skip to content

Commit

Permalink
feature, Add support to show CTAs button on group tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
Passanelli committed Nov 26, 2024
1 parent 4890c5a commit bfcb018
Show file tree
Hide file tree
Showing 6 changed files with 247 additions and 8 deletions.
17 changes: 17 additions & 0 deletions packages/polaris-viz/src/components/Grid/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,23 @@ export function Grid(props: GridProps) {
};
};

const handleBodyClick = useCallback(() => {
setGroupSelected(null);
handleGroupHover(null);
}, [handleGroupHover]);

useEffect(() => {
if (groupSelected) {
setTimeout(() => {
document.body.addEventListener('click', handleBodyClick);
}, 0);

return () => {
document.body.removeEventListener('click', handleBodyClick);
};
}
}, [groupSelected, handleBodyClick]);

const yTicks = useMemo(() => {
return Array.from({length: gridDimensions.rows}, (_, index) => ({
value: gridDimensions.rows - 1 - index,
Expand Down
42 changes: 36 additions & 6 deletions packages/polaris-viz/src/components/Grid/components/Tooltip.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
@import '../../../styles/common';
@import '../utilities/constants';

.TooltipActions {
margin-top: 12px;
}

.TooltipAction {
display: block;
text-decoration: none;
color: $color-gray-150;
font-size: 12px;
font-weight: 500;
line-height: 1.2;
margin: 0;
padding: 6px 12px;
text-align: center;
border-radius: 8px;
border: none;
box-shadow: 0 0 0.5px 0.5px rgba(0, 0, 0, 0.1),
0 1px 2px 0 rgba(0, 0, 0, 0.25);
background: $color-white;
}

.TooltipAction span {
box-sizing: border-box;
display: block;
}

.TooltipAction:hover {
background: rgba(0, 0, 0, 0.025);
}

.GroupGoal {
margin: 0;
font-size: 11px;
Expand All @@ -12,8 +42,8 @@
}

.TooltipTitle {
font-weight: 700;
font-size: 12px;
font-weight: 600;
font-size: 13px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
Expand All @@ -25,13 +55,13 @@
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
color: var(--p-color-bg-surface-inverse);
color: $color-gray-100;
margin-bottom: 8px;
}

.TooltipMetricInformation {
color: $color-gray-150;
font-weight: 600;
font-weight: 500;
}

.TooltipGoal {
Expand All @@ -48,7 +78,7 @@
font-size: 12px;
font-family: Inter, -apple-system, system-ui, 'San Francisco', 'Segoe UI',
Roboto, 'Helvetica Neue', sans-serif;
line-height: 1.2;
line-height: 1.3;
padding: 12px;
background: $color-white;
border-radius: 12px;
Expand All @@ -61,7 +91,7 @@
z-index: 1;
top: 0;
left: 0;
width: 250px;
width: 280px;
outline: none;
@container (max-width: #{$grid-small-breakpoint}) {
display: none;
Expand Down
65 changes: 65 additions & 0 deletions packages/polaris-viz/src/components/Grid/components/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {useEffect, useState, useRef} from 'react';
import {createPortal} from 'react-dom';

import type {CellGroup} from '../types';
Expand All @@ -15,6 +16,33 @@ interface TooltipProps {
export function Tooltip({x, y, group}: TooltipProps) {
const container = useRootContainer(TOOLTIP_ID);

const [actionsButtonsColumns, setActionsButtonsColumns] = useState(1);
const actionsContainerRef = useRef<HTMLDivElement>(null);

useEffect(() => {
if (group?.actions?.length && actionsContainerRef.current) {
// This is a workaround to determine if the buttons should be displayed in one or two columns depending if the copy fits in one line
const buttonsWrapper = actionsContainerRef.current;
const actionsButtons = buttonsWrapper.querySelectorAll('a span');

const heights: Set<number> = new Set();
let areWrapping = false;
for (const button of actionsButtons) {
const wrapping =
parseFloat(window.getComputedStyle(button).height) /
parseFloat(window.getComputedStyle(button).lineHeight) >
1;
if (wrapping) {
areWrapping = true;
}
heights.add(button.getBoundingClientRect().height);
}

const haveSameHeight = heights.size === 1;
setActionsButtonsColumns(haveSameHeight && !areWrapping ? 2 : 1);
}
}, [group?.actions, actionsContainerRef.current]);

if (!group) {
return null;
}
Expand All @@ -26,6 +54,9 @@ export function Tooltip({x, y, group}: TooltipProps) {
transform: `translate(${x}px, ${y}px)`,
}}
aria-label={group.name}
onClick={(event) => {
event.stopPropagation();
}}
>
<div className={styles.Tooltip}>
<div className={styles.TooltipTitle}>{group.name}</div>
Expand Down Expand Up @@ -56,6 +87,40 @@ export function Tooltip({x, y, group}: TooltipProps) {
<p className={styles.GroupGoal}>{group.goal}</p>
</div>
)}
{group.actions?.length && (
<div className={styles.TooltipActions} ref={actionsContainerRef}>
<div
style={{
display: 'grid',
gridTemplateColumns: `repeat(${actionsButtonsColumns}, 1fr)`,
gap: 8,
}}
>
{group.actions?.map((action, index) => {
const numActions = group.actions?.length || 0;
const oddNumActions = numActions % 2 !== 0;
const lastAction = index === numActions - 1;
const spanFullWidth = oddNumActions && lastAction;
return (
<div
key={`action-${index}`}
style={{
gridColumn: spanFullWidth ? 'span 2' : 'span 1',
}}
>
<a
className={styles.TooltipAction}
href={action.url}
target={action.target}
>
<span>{action.children}</span>
</a>
</div>
);
})}
</div>
</div>
)}
</div>
</div>,
container,
Expand Down
120 changes: 120 additions & 0 deletions packages/polaris-viz/src/components/Grid/stories/data.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Customers without recent purchases, but with a very strong history of orders and spend.',
goal: 'Goal: move customers to Loyal',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'at_risk',
Expand All @@ -48,6 +60,18 @@ export const CELL_GROUPS: CellGroup[] = [
description:
'Customers without recent purchases, but with a strong history of orders and spend.',
goal: 'Goal: move customers to Loyal or Needs Attention',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'dormant',
Expand All @@ -63,6 +87,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Customers without recent orders, with infrequent orders, and with low spend.',
goal: 'Goal: move customers to Almost lost',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'loyal',
Expand All @@ -78,6 +114,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Customers without recent purchases, but with a very strong history of orders and spend.',
goal: 'Goal: move customers to Loyal',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'needs_attention',
Expand All @@ -93,6 +141,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Customers who buy less recently, order sometimes and spend moderately with your store.',
goal: 'Goal: move customers to Loyal or Potential',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report long text',
url: '#',
target: '_blank',
},
],
},
{
id: 'almost_lost',
Expand All @@ -108,6 +168,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Customers without recent purchases, fewer orders, and with lower spend.',
goal: 'Goal: move customers to Active or Promising',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'promising',
Expand All @@ -122,6 +194,18 @@ export const CELL_GROUPS: CellGroup[] = [
description: 'Customers with recent purchases, few orders, and low spend.',
goal: 'Goal: move customers to Active.',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'active',
Expand All @@ -137,6 +221,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Customers with recent purchases, some orders, and moderate spend.',
goal: 'Goal: move customers to Champions or Loyal',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'new',
Expand All @@ -152,6 +248,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Clients ayant effectué des achats très récemment, ayant passé peu de commandes et ayant dépensé peu dargent.',
goal: 'Goal: move customers to Active',
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
{
id: 'champions',
Expand All @@ -166,6 +274,18 @@ export const CELL_GROUPS: CellGroup[] = [
'Customers with very recent purchases, many orders, and the most spend.',
goal: null,
metricInformation: '1,424 (10.9% of customer base)',
actions: [
{
children: 'Preview segment',
url: '#',
target: '_blank',
},
{
children: 'View report',
url: '#',
target: '_blank',
},
],
},
];

Expand Down
7 changes: 7 additions & 0 deletions packages/polaris-viz/src/components/Grid/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ export interface CellGroup {
secondaryValue: string;
value: string;
metricInformation?: string;
actions?: GroupAction[];
}

export interface GroupAction {
children: string;
url?: string;
target?: '_blank' | '_self' | '_parent' | '_top';
}

export interface TooltipInfo {
Expand Down
Loading

0 comments on commit bfcb018

Please sign in to comment.