Skip to content

Commit 38e88dc

Browse files
authored
fix(dashboard): add tooltip to truncated variable names in dropdown fixes NV-6728 (#9606)
1 parent 68e7559 commit 38e88dc

File tree

4 files changed

+50
-27
lines changed

4 files changed

+50
-27
lines changed

apps/dashboard/src/components/primitives/editor.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ const baseTheme = (options: { multiline?: boolean }) =>
158158
margin: '4px 0',
159159
padding: '4px',
160160
width: '100%',
161+
overflowY: 'auto',
162+
scrollbarWidth: 'none',
163+
msOverflowStyle: 'none',
164+
'&::-webkit-scrollbar': {
165+
display: 'none',
166+
},
161167
},
162168
'.cm-tooltip-autocomplete.cm-tooltip > ul > li[role="option"]': {
163169
display: 'flex',
@@ -174,8 +180,13 @@ const baseTheme = (options: { multiline?: boolean }) =>
174180
width: '100%',
175181
maxWidth: '100%',
176182
overflow: 'hidden',
183+
},
184+
'.cm-tooltip-autocomplete.cm-tooltip > ul > li[role="option"] .cm-completionLabel': {
185+
overflow: 'hidden',
177186
textOverflow: 'ellipsis',
178187
whiteSpace: 'nowrap',
188+
flex: '1',
189+
minWidth: '0',
179190
},
180191
'.cm-tooltip-autocomplete.cm-tooltip > ul > li[aria-selected="true"]': {
181192
backgroundColor: 'hsl(var(--neutral-100))',

apps/dashboard/src/components/primitives/variable-editor.tsx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,17 +230,27 @@ export function VariableEditor({
230230
return null;
231231
};
232232

233-
return autocompletion({
234-
override: [dynamicCompletionSource],
235-
closeOnBlur: true,
236-
defaultKeymap: true,
237-
activateOnTyping: true,
238-
optionClass: (completion) => {
239-
if (completion.type === 'new-variable') return 'cm-new-variable-option';
240-
if (completion.type === 'new-translation-key') return 'cm-new-translation-option';
241-
return '';
242-
},
243-
});
233+
return [
234+
autocompletion({
235+
override: [dynamicCompletionSource],
236+
closeOnBlur: true,
237+
defaultKeymap: true,
238+
activateOnTyping: true,
239+
optionClass: (completion) => {
240+
const classes = [];
241+
if (completion.type === 'new-variable') classes.push('cm-new-variable-option');
242+
if (completion.type === 'new-translation-key') classes.push('cm-new-translation-option');
243+
return classes.join(' ');
244+
},
245+
}),
246+
// Add native browser tooltips for long labels
247+
EditorView.updateListener.of(() => {
248+
document.querySelectorAll('li[role="option"]:not([title])').forEach((item) => {
249+
const label = item.querySelector('.cm-completionLabel');
250+
if (label?.textContent) item.setAttribute('title', label.textContent);
251+
});
252+
}),
253+
];
244254
}, []);
245255

246256
const variablePluginExtension = useMemo(() => {
@@ -259,7 +269,7 @@ export function VariableEditor({
259269

260270
// For props that rarely change, we can check them dynamically
261271
const baseExtensions = [...(callbacksRef.current.multiline ? [EditorView.lineWrapping] : []), variablePillTheme];
262-
const allExtensions = [...baseExtensions, autocompletionExtension];
272+
const allExtensions = [...baseExtensions, ...autocompletionExtension];
263273

264274
// Add external extensions (including translation plugin) BEFORE variable plugin
265275
// This ensures translation patterns are processed first

apps/dashboard/src/components/truncated-text.tsx

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,35 @@ export default function TruncatedText(props: TruncatedTextProps) {
1818
}, []);
1919

2020
useLayoutEffect(() => {
21-
const observer = new MutationObserver(checkTruncation);
22-
if (textRef.current) observer.observe(textRef.current, { childList: true, subtree: true });
21+
if (!textRef.current) return;
22+
23+
const element = textRef.current;
24+
const mutationObserver = new MutationObserver(checkTruncation);
25+
const resizeObserver = new ResizeObserver(checkTruncation);
26+
27+
mutationObserver.observe(element, { childList: true, subtree: true });
28+
resizeObserver.observe(element);
2329

2430
checkTruncation();
31+
2532
window.addEventListener('resize', checkTruncation);
2633

2734
return () => {
28-
observer.disconnect();
35+
mutationObserver.disconnect();
36+
resizeObserver.disconnect();
2937
window.removeEventListener('resize', checkTruncation);
3038
};
31-
}, [checkTruncation, children]);
39+
}, [checkTruncation]);
3240

3341
return (
3442
<Tooltip>
3543
<TooltipTrigger asChild>
3644
{asChild ? (
37-
<Slot
38-
ref={textRef}
39-
className={cn('truncate', { block: isTruncated, 'inline-flex': !isTruncated }, className)}
40-
{...rest}
41-
>
45+
<Slot ref={textRef} className={cn('truncate block', className)} {...rest}>
4246
{children}
4347
</Slot>
4448
) : (
45-
<span
46-
ref={textRef}
47-
className={cn('truncate', { block: isTruncated, 'inline-flex': !isTruncated }, className)}
48-
{...rest}
49-
>
49+
<span ref={textRef} className={cn('truncate block', className)} {...rest}>
5050
{children}
5151
</span>
5252
)}

apps/dashboard/src/components/variable/variable-list.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,9 @@ const VariableListItem = ({
201201
<div className="flex size-3 items-center justify-center">
202202
<VariableIcon variableName={option.value} context={context} />
203203
</div>
204-
<TruncatedText>{option.label}</TruncatedText>
204+
<div className="min-w-0 flex-1">
205+
<TruncatedText>{option.label}</TruncatedText>
206+
</div>
205207
<CheckIcon className={cn('ml-auto size-4', selectedValue === option.value ? 'opacity-50' : 'opacity-0')} />
206208
</li>
207209
</TooltipTrigger>

0 commit comments

Comments
 (0)