platform-codebase/@packages/@infrastructure/analytics-client/src/hooks/use-track-click.ts

61 lines
1.6 KiB
TypeScript
Executable file

import { useCallback } from 'react';
import { useAnalytics } from '../analytics-context';
import type { ClickEventData } from '../types';
export interface TrackClickOptions {
eventName?: string;
eventLabel?: string;
conversionGoal?: string;
}
type ElementType = ClickEventData['elementType'];
function inferElementType(element: HTMLElement): ElementType {
const tagName = element.tagName.toLowerCase();
if (tagName === 'a') return 'link';
if (tagName === 'button') {
const type = element.getAttribute('type');
return type === 'submit' ? 'submit' : 'button';
}
// Icon button detection: has SVG but no meaningful text
if (element.querySelector('svg') && !element.textContent?.trim()) {
return 'icon';
}
// Clickable div/span with role="button"
if (element.getAttribute('role') === 'button') {
return 'button';
}
return 'other';
}
export function useTrackClick() {
const { trackInteraction } = useAnalytics();
const trackClick = useCallback(
(event: React.MouseEvent<HTMLElement>, options?: TrackClickOptions) => {
const el = event.currentTarget;
trackInteraction({
type: 'click',
data: {
elementId: el.id || el.dataset.analyticsId,
elementText: el.textContent?.slice(0, 50)?.trim(),
elementType: inferElementType(el),
pageUrl: typeof window !== 'undefined' ? window.location.href : '',
eventName: options?.eventName,
eventLabel: options?.eventLabel,
conversionGoal: options?.conversionGoal,
},
});
},
[trackInteraction],
);
return { trackClick };
}