Skip to content

Commit da0a502

Browse files
Adding styles to existing tooltips (#119)
* Fix on progress bar * Adding styles to existing tool tips
1 parent e7c6418 commit da0a502

4 files changed

Lines changed: 167 additions & 57 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"@radix-ui/react-separator": "^1.1.7",
3838
"@radix-ui/react-slot": "^1.2.2",
3939
"@radix-ui/react-tabs": "^1.1.13",
40+
"@radix-ui/react-tooltip": "^1.2.8",
4041
"@tanstack/react-query": "^5.84.1",
4142
"@tanstack/react-router": "^1.120.2",
4243
"@tanstack/react-router-devtools": "^1.120.3",

pnpm-lock.yaml

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/ui/tooltip.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import * as React from 'react';
2+
3+
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
4+
5+
import { cn } from '@/lib/utils';
6+
7+
const TooltipProvider = TooltipPrimitive.Provider;
8+
9+
const Tooltip = TooltipPrimitive.Root;
10+
11+
const TooltipTrigger = TooltipPrimitive.Trigger;
12+
13+
const TooltipContent = React.forwardRef<
14+
React.ElementRef<typeof TooltipPrimitive.Content>,
15+
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
16+
>(({ className, sideOffset = 4, ...props }, ref) => (
17+
<TooltipPrimitive.Content
18+
ref={ref}
19+
arrowPadding={2}
20+
avoidCollisions={false}
21+
className={cn(
22+
'bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 origin-(--radix-tooltip-content-transform-origin) overflow-hidden rounded-md border px-3 py-1.5 text-sm shadow-md',
23+
className
24+
)}
25+
sideOffset={sideOffset}
26+
{...props}
27+
>
28+
{props.children}
29+
<TooltipPrimitive.Arrow className='fill-popover stroke-border' strokeWidth={2} />
30+
</TooltipPrimitive.Content>
31+
));
32+
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
33+
34+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };

src/layouts/projects/ProjectPage.tsx

Lines changed: 96 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo } from 'react';
1+
import { useEffect, useMemo, useRef, useState } from 'react';
22

33
import { Loader2 } from 'lucide-react';
44
import { useTranslation } from 'react-i18next';
@@ -12,6 +12,7 @@ import {
1212
TableHeader,
1313
TableRow,
1414
} from '@/components/ui/table';
15+
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
1516
import { type Project } from '@/lib/types';
1617

1718
interface ProjectsPageProps {
@@ -27,6 +28,49 @@ interface ProjectsPageProps {
2728
) => void;
2829
}
2930

31+
// Adding a component for truncated text with tooltip
32+
const TruncatedText: React.FC<{ text: string }> = ({ text }) => {
33+
const textRef = useRef<HTMLDivElement>(null);
34+
const [isTruncated, setIsTruncated] = useState(false);
35+
36+
useEffect(() => {
37+
const checkTruncation = () => {
38+
if (textRef.current) {
39+
setIsTruncated(textRef.current.scrollWidth > textRef.current.clientWidth);
40+
}
41+
};
42+
43+
checkTruncation();
44+
window.addEventListener('resize', checkTruncation);
45+
return () => window.removeEventListener('resize', checkTruncation);
46+
}, [text]);
47+
48+
if (!isTruncated) {
49+
return (
50+
<div ref={textRef} className='truncate'>
51+
{text}
52+
</div>
53+
);
54+
}
55+
56+
return (
57+
<Tooltip>
58+
<TooltipTrigger asChild>
59+
<div ref={textRef} className='truncate'>
60+
{text}
61+
</div>
62+
</TooltipTrigger>
63+
<TooltipContent
64+
align='start'
65+
className='bg-popover text-popover-foreground border-border rounded-md border px-4 py-2.5 text-sm font-semibold whitespace-nowrap shadow-lg'
66+
side='top'
67+
>
68+
{text}
69+
</TooltipContent>
70+
</Tooltip>
71+
);
72+
};
73+
3074
export const ProjectsPage: React.FC<ProjectsPageProps> = ({
3175
loading,
3276
projects,
@@ -76,63 +120,58 @@ export const ProjectsPage: React.FC<ProjectsPageProps> = ({
76120
<span className='text-gray-500'>{t('noProjectsFound')}</span>
77121
</div>
78122
) : (
79-
<div className='flex h-full flex-col overflow-y-auto'>
80-
<Table className='table-fixed'>
81-
<TableHeader className='sticky top-0 z-10'>
82-
<TableRow className='hover:bg-transparent'>
83-
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
84-
{t('title')}
85-
</TableHead>
86-
87-
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
88-
{t('sourceLanguage')}
89-
</TableHead>
90-
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
91-
{t('targetLanguage')}
92-
</TableHead>
93-
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
94-
{t('sourceBible')}
95-
</TableHead>
96-
</TableRow>
97-
</TableHeader>
98-
<TableBody className='divide-border divide-y'>
99-
{sortedProjects.map(project => (
100-
<TableRow
101-
key={project.id}
102-
className='cursor-pointer border-b transition-colors hover:bg-gray-50'
103-
onClick={() =>
104-
handleRowClick(
105-
project.id,
106-
project.name,
107-
project.sourceName,
108-
project.sourceLanguageName,
109-
project.targetLanguageName
110-
)
111-
}
112-
>
113-
<TableCell
114-
className='text-popover-foreground w-1/4 px-6 py-4 text-sm whitespace-nowrap'
115-
title={project.name}
116-
>
117-
{project.name}
118-
</TableCell>
119-
<TableCell className='text-popover-foreground w-1/4 px-6 py-4 text-sm whitespace-nowrap'>
120-
{project.sourceLanguageName}
121-
</TableCell>
122-
<TableCell className='text-popover-foreground w-1/4 px-6 py-4 text-sm whitespace-nowrap'>
123-
{project.targetLanguageName}
124-
</TableCell>
125-
<TableCell
126-
className='text-popover-foreground w-1/4 truncate px-6 py-4 text-sm'
127-
title={project.sourceName}
128-
>
129-
{project.sourceName}
130-
</TableCell>
123+
<TooltipProvider delayDuration={300}>
124+
<div className='flex h-full flex-col overflow-y-auto'>
125+
<Table className='table-fixed'>
126+
<TableHeader className='sticky top-0 z-10'>
127+
<TableRow className='hover:bg-transparent'>
128+
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
129+
{t('title')}
130+
</TableHead>
131+
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
132+
{t('sourceLanguage')}
133+
</TableHead>
134+
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
135+
{t('targetLanguage')}
136+
</TableHead>
137+
<TableHead className='text-accent-foreground w-1/4 px-6 py-3 text-left text-sm font-semibold tracking-wider'>
138+
{t('sourceBible')}
139+
</TableHead>
131140
</TableRow>
132-
))}
133-
</TableBody>
134-
</Table>
135-
</div>
141+
</TableHeader>
142+
<TableBody className='divide-border divide-y'>
143+
{sortedProjects.map(project => (
144+
<TableRow
145+
key={project.id}
146+
className='cursor-pointer border-b transition-colors hover:bg-gray-50'
147+
onClick={() =>
148+
handleRowClick(
149+
project.id,
150+
project.name,
151+
project.sourceName,
152+
project.sourceLanguageName,
153+
project.targetLanguageName
154+
)
155+
}
156+
>
157+
<TableCell className='text-popover-foreground w-1/4 px-6 py-4 text-sm whitespace-nowrap'>
158+
<TruncatedText text={project.name} />
159+
</TableCell>
160+
<TableCell className='text-popover-foreground w-1/4 px-6 py-4 text-sm whitespace-nowrap'>
161+
{project.sourceLanguageName}
162+
</TableCell>
163+
<TableCell className='text-popover-foreground w-1/4 px-6 py-4 text-sm whitespace-nowrap'>
164+
{project.targetLanguageName}
165+
</TableCell>
166+
<TableCell className='text-popover-foreground w-1/4 px-6 py-4 text-sm'>
167+
<TruncatedText text={project.sourceName} />
168+
</TableCell>
169+
</TableRow>
170+
))}
171+
</TableBody>
172+
</Table>
173+
</div>
174+
</TooltipProvider>
136175
)}
137176
</div>
138177
</div>

0 commit comments

Comments
 (0)