feat: tooltips for tool settings (#5586)
This commit is contained in:
parent
e0d74a6674
commit
411553ee91
@ -36,6 +36,7 @@ export type ButtonOptions = {
|
|||||||
id: string;
|
id: string;
|
||||||
type: 'range' | 'radio' | 'double-range' | 'custom' | 'checkbox' | 'select' | 'button';
|
type: 'range' | 'radio' | 'double-range' | 'custom' | 'checkbox' | 'select' | 'button';
|
||||||
name?: string;
|
name?: string;
|
||||||
|
tooltip?: string;
|
||||||
min?: number;
|
min?: number;
|
||||||
max?: number;
|
max?: number;
|
||||||
step?: number;
|
step?: number;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Numeric from '../Numeric';
|
import Numeric from '../Numeric';
|
||||||
import { cn } from '../../lib/utils';
|
import { cn } from '../../lib/utils';
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from '../Tooltip';
|
||||||
|
|
||||||
interface RowDoubleRangeProps {
|
interface RowDoubleRangeProps {
|
||||||
values: [number, number];
|
values: [number, number];
|
||||||
@ -10,6 +11,7 @@ interface RowDoubleRangeProps {
|
|||||||
step: number;
|
step: number;
|
||||||
showLabel?: boolean;
|
showLabel?: boolean;
|
||||||
label?: string;
|
label?: string;
|
||||||
|
tooltip?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,8 +23,28 @@ const RowDoubleRange: React.FC<RowDoubleRangeProps> = ({
|
|||||||
step,
|
step,
|
||||||
showLabel = false,
|
showLabel = false,
|
||||||
label = '',
|
label = '',
|
||||||
|
tooltip,
|
||||||
className,
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
|
const renderLabel = () => {
|
||||||
|
if (!showLabel || !label) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelNode = <Numeric.Label showValue>{label}</Numeric.Label>;
|
||||||
|
|
||||||
|
if (!tooltip) {
|
||||||
|
return labelNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>{labelNode}</TooltipTrigger>
|
||||||
|
<TooltipContent side="top">{tooltip}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Numeric.Container
|
<Numeric.Container
|
||||||
mode="doubleRange"
|
mode="doubleRange"
|
||||||
@ -33,7 +55,7 @@ const RowDoubleRange: React.FC<RowDoubleRangeProps> = ({
|
|||||||
step={step}
|
step={step}
|
||||||
className={cn('flex flex-col space-y-2', className)}
|
className={cn('flex flex-col space-y-2', className)}
|
||||||
>
|
>
|
||||||
{showLabel && <Numeric.Label showValue>{label}</Numeric.Label>}
|
{renderLabel()}
|
||||||
<Numeric.DoubleRange showNumberInputs />
|
<Numeric.DoubleRange showNumberInputs />
|
||||||
</Numeric.Container>
|
</Numeric.Container>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { Label } from '../Label';
|
import { Label } from '../Label';
|
||||||
import { Tabs, TabsList, TabsTrigger } from '../Tabs';
|
import { Tabs, TabsList, TabsTrigger } from '../Tabs';
|
||||||
import { cn } from '../../lib/utils';
|
import { cn } from '../../lib/utils';
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from '../Tooltip';
|
||||||
|
|
||||||
interface RadioValue {
|
interface RadioValue {
|
||||||
value: string;
|
value: string;
|
||||||
@ -14,6 +15,7 @@ interface RadioOption {
|
|||||||
value: string;
|
value: string;
|
||||||
values: RadioValue[];
|
values: RadioValue[];
|
||||||
onChange?: (val: string) => void;
|
onChange?: (val: string) => void;
|
||||||
|
tooltip?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RowSegmentedControlProps {
|
interface RowSegmentedControlProps {
|
||||||
@ -38,7 +40,18 @@ export const RowSegmentedControl: React.FC<RowSegmentedControlProps> = ({
|
|||||||
className={cn('flex items-center justify-between text-[13px]', className)}
|
className={cn('flex items-center justify-between text-[13px]', className)}
|
||||||
key={option.id}
|
key={option.id}
|
||||||
>
|
>
|
||||||
<Label className="mr-2">{option.name}</Label>
|
<Label className="mr-2">
|
||||||
|
{option.tooltip ? (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<span className="cursor-help">{option.name}</span>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top">{option.tooltip}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
option.name
|
||||||
|
)}
|
||||||
|
</Label>
|
||||||
<div className="max-w-1/2">
|
<div className="max-w-1/2">
|
||||||
<Tabs
|
<Tabs
|
||||||
value={option.value}
|
value={option.value}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { Checkbox } from '../Checkbox/Checkbox';
|
|||||||
import { Label } from '../Label';
|
import { Label } from '../Label';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../Select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../Select';
|
||||||
import { Switch } from '../Switch';
|
import { Switch } from '../Switch';
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from '../Tooltip';
|
||||||
|
|
||||||
const SETTING_TYPES = {
|
const SETTING_TYPES = {
|
||||||
RANGE: 'range',
|
RANGE: 'range',
|
||||||
@ -61,13 +62,32 @@ function ToolSettings({ options }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderLabelWithTooltip = (label: React.ReactNode, tooltip?: string) => {
|
||||||
|
if (!label) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tooltip) {
|
||||||
|
return <span>{label}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<span className="cursor-help">{label}</span>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top">{tooltip}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const renderRangeSetting = option => {
|
const renderRangeSetting = option => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="flex items-center"
|
className="flex items-center"
|
||||||
key={option.id}
|
key={option.id}
|
||||||
>
|
>
|
||||||
<div className="w-1/3 text-[13px]">{option.name}</div>
|
<div className="w-1/3 text-[13px]">{renderLabelWithTooltip(option.name, option.tooltip)}</div>
|
||||||
<div
|
<div
|
||||||
className="w-2/3"
|
className="w-2/3"
|
||||||
data-cy={option.id}
|
data-cy={option.id}
|
||||||
@ -98,15 +118,25 @@ const renderRadioSetting = option => {
|
|||||||
|
|
||||||
function renderDoubleRangeSetting(option) {
|
function renderDoubleRangeSetting(option) {
|
||||||
return (
|
return (
|
||||||
<RowDoubleRange
|
<div
|
||||||
|
className="flex items-center"
|
||||||
key={option.id}
|
key={option.id}
|
||||||
|
>
|
||||||
|
<div className="w-1/3 text-[13px]">
|
||||||
|
{renderLabelWithTooltip(option.name, option.tooltip)}
|
||||||
|
</div>
|
||||||
|
<div className="w-2/3">
|
||||||
|
<RowDoubleRange
|
||||||
values={option.value}
|
values={option.value}
|
||||||
onChange={option.onChange}
|
onChange={option.onChange}
|
||||||
minValue={option.min}
|
minValue={option.min}
|
||||||
maxValue={option.max}
|
maxValue={option.max}
|
||||||
step={option.step}
|
step={option.step}
|
||||||
showLabel={false}
|
showLabel={false}
|
||||||
|
tooltip={option.tooltip}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,15 +149,38 @@ const renderCustomSetting = option => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderButtonSetting = option => {
|
const renderButtonSetting = option => {
|
||||||
return (
|
const button = (
|
||||||
<Button
|
<Button
|
||||||
key={option.id}
|
key={option.id}
|
||||||
variant="ghost"
|
variant={option.variant || 'ghost'}
|
||||||
|
className={option.className || ''}
|
||||||
onClick={() => option.onChange()}
|
onClick={() => option.onChange()}
|
||||||
>
|
>
|
||||||
{option.name}
|
{option.name}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (option.tooltip) {
|
||||||
|
return (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
||||||
|
<TooltipContent side="top">{option.tooltip}</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return button;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCheckboxLabel = option => {
|
||||||
|
return (
|
||||||
|
<Label
|
||||||
|
htmlFor={option.id}
|
||||||
|
className="cursor-pointer"
|
||||||
|
>
|
||||||
|
{renderLabelWithTooltip(option.name, option.tooltip)}
|
||||||
|
</Label>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderCheckboxSetting = option => {
|
const renderCheckboxSetting = option => {
|
||||||
@ -143,12 +196,7 @@ const renderCheckboxSetting = option => {
|
|||||||
option.onChange?.(checked);
|
option.onChange?.(checked);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label
|
{renderCheckboxLabel(option)}
|
||||||
htmlFor={option.id}
|
|
||||||
className="cursor-pointer"
|
|
||||||
>
|
|
||||||
{option.name}
|
|
||||||
</Label>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -166,20 +214,22 @@ const renderSwitchSetting = option => {
|
|||||||
option.onChange?.(checked);
|
option.onChange?.(checked);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label
|
{renderCheckboxLabel(option)}
|
||||||
htmlFor={option.id}
|
|
||||||
className="cursor-pointer"
|
|
||||||
>
|
|
||||||
{option.name}
|
|
||||||
</Label>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderSelectSetting = option => {
|
const renderSelectSetting = option => {
|
||||||
return (
|
return (
|
||||||
<Select
|
<div
|
||||||
|
className="flex items-center"
|
||||||
key={option.id}
|
key={option.id}
|
||||||
|
>
|
||||||
|
<div className="w-1/3 text-[13px]">
|
||||||
|
{renderLabelWithTooltip(option.name, option.tooltip)}
|
||||||
|
</div>
|
||||||
|
<div className="w-2/3">
|
||||||
|
<Select
|
||||||
onValueChange={value => option.onChange?.(value)}
|
onValueChange={value => option.onChange?.(value)}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
>
|
>
|
||||||
@ -197,6 +247,8 @@ const renderSelectSetting = option => {
|
|||||||
))}
|
))}
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user