feat: add tooltips to editor buttons (#4934)

Co-authored-by: Anthony Cooper <antcoop096@gmail.com>
Co-authored-by: aarohee-he <aarohee-he@users.noreply.github.com>
Co-authored-by: Mishti Gala <mishtigala19@gmail.com>
pull/4969/head
aarohee-he 2 months ago committed by GitHub
parent 13957472eb
commit 0f2390a0b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -13,6 +13,7 @@ import { extractUserIdFromName } from "@/store/common";
import { Memo, MemoRelation_Memo, MemoRelation_Type } from "@/types/proto/api/v1/memo_service"; import { Memo, MemoRelation_Memo, MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
import { useTranslate } from "@/utils/i18n"; import { useTranslate } from "@/utils/i18n";
import { MemoEditorContext } from "../types"; import { MemoEditorContext } from "../types";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
const AddMemoRelationPopover = () => { const AddMemoRelationPopover = () => {
const t = useTranslate(); const t = useTranslate();
@ -95,11 +96,20 @@ const AddMemoRelationPopover = () => {
return ( return (
<Popover open={popoverOpen} onOpenChange={setPopoverOpen}> <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
<PopoverTrigger asChild> <TooltipProvider>
<Button variant="ghost" size="icon"> <Tooltip>
<LinkIcon className="size-5" /> <TooltipTrigger asChild>
</Button> <PopoverTrigger asChild>
</PopoverTrigger> <Button variant="ghost" size="icon">
<LinkIcon className="size-5" />
</Button>
</PopoverTrigger>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>{t("tooltip.link-memo")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<PopoverContent align="center"> <PopoverContent align="center">
<div className="w-[16rem] p-1 flex flex-col justify-start items-start"> <div className="w-[16rem] p-1 flex flex-col justify-start items-start">
{/* Search and selection interface */} {/* Search and selection interface */}

@ -8,6 +8,7 @@ import { Input } from "@/components/ui/input";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Location } from "@/types/proto/api/v1/memo_service"; import { Location } from "@/types/proto/api/v1/memo_service";
import { useTranslate } from "@/utils/i18n"; import { useTranslate } from "@/utils/i18n";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
interface Props { interface Props {
location?: Location; location?: Location;
@ -94,19 +95,32 @@ const LocationSelector = (props: Props) => {
return ( return (
<Popover open={popoverOpen} onOpenChange={setPopoverOpen}> <Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
<PopoverTrigger asChild> <TooltipProvider>
<Button variant="ghost" size={props.location ? undefined : "icon"}> <Tooltip>
<MapPinIcon className="size-5 shrink-0" /> <TooltipTrigger asChild>
{props.location && ( <PopoverTrigger asChild>
<> <Button variant="ghost" size={props.location ? undefined : "icon"}>
<span className="ml-0.5 text-sm text-ellipsis whitespace-nowrap overflow-hidden max-w-28">{props.location.placeholder}</span> <MapPinIcon className="size-5 shrink-0" />
<span className="cursor-pointer hover:text-primary" onClick={removeLocation}> {props.location && (
<XIcon className="size-4 shrink-0" /> <>
</span> <span className="ml-0.5 text-sm text-ellipsis whitespace-nowrap overflow-hidden max-w-28">
</> {props.location.placeholder}
</span>
<span className="ml-1 cursor-pointer hover:text-primary" onClick={removeLocation}>
<XIcon className="size-4 shrink-0" />
</span>
</>
)}
</Button>
</PopoverTrigger>
</TooltipTrigger>
{!props.location && (
<TooltipContent side="bottom">
<p>{t("tooltip.select-location")}</p>
</TooltipContent>
)} )}
</Button> </Tooltip>
</PopoverTrigger> </TooltipProvider>
<PopoverContent align="center"> <PopoverContent align="center">
<div className="min-w-80 sm:w-lg p-1 flex flex-col justify-start items-start"> <div className="min-w-80 sm:w-lg p-1 flex flex-col justify-start items-start">
<LeafletMap key={JSON.stringify(state.initilized)} latlng={state.position} onChange={onPositionChanged} /> <LeafletMap key={JSON.stringify(state.initilized)} latlng={state.position} onChange={onPositionChanged} />

@ -3,6 +3,8 @@ import { Button } from "@/components/ui/button";
import { useTranslate } from "@/utils/i18n"; import { useTranslate } from "@/utils/i18n";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../ui/dropdown-menu"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../../ui/dropdown-menu";
import { EditorRefActions } from "../Editor"; import { EditorRefActions } from "../Editor";
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@/components/ui/tooltip";
interface Props { interface Props {
editorRef: React.RefObject<EditorRefActions>; editorRef: React.RefObject<EditorRefActions>;
@ -61,11 +63,20 @@ const MarkdownMenu = (props: Props) => {
return ( return (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <TooltipProvider>
<Button variant="ghost" size="icon"> <Tooltip>
<SquareSlashIcon className="size-5" /> <TooltipTrigger asChild>
</Button> <DropdownMenuTrigger asChild>
</DropdownMenuTrigger> <Button variant="ghost" size="icon">
<SquareSlashIcon className="size-5" />
</Button>
</DropdownMenuTrigger>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>{t("tooltip.markdown-menu")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<DropdownMenuContent align="start"> <DropdownMenuContent align="start">
<DropdownMenuItem onClick={handleCodeBlockClick}> <DropdownMenuItem onClick={handleCodeBlockClick}>
<Code2Icon className="w-4 h-auto text-muted-foreground" /> <Code2Icon className="w-4 h-auto text-muted-foreground" />

@ -6,6 +6,7 @@ import { userStore } from "@/store";
import { useTranslate } from "@/utils/i18n"; import { useTranslate } from "@/utils/i18n";
import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover"; import { Popover, PopoverContent, PopoverTrigger } from "../../ui/popover";
import { EditorRefActions } from "../Editor"; import { EditorRefActions } from "../Editor";
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from "@/components/ui/tooltip";
interface Props { interface Props {
editorRef: React.RefObject<EditorRefActions>; editorRef: React.RefObject<EditorRefActions>;
@ -34,11 +35,20 @@ const TagSelector = observer((props: Props) => {
return ( return (
<Popover> <Popover>
<PopoverTrigger asChild> <TooltipProvider>
<Button variant="ghost" size="icon"> <Tooltip>
<HashIcon className="size-5" /> <TooltipTrigger asChild>
</Button> <PopoverTrigger asChild>
</PopoverTrigger> <Button variant="ghost" size="icon">
<HashIcon className="size-5" />
</Button>
</PopoverTrigger>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>{t("tooltip.tags")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
<PopoverContent align="start" sideOffset={2}> <PopoverContent align="start" sideOffset={2}>
{tags.length > 0 ? ( {tags.length > 0 ? (
<div className="flex flex-row justify-start items-start flex-wrap px-2 max-w-48 h-auto max-h-48 overflow-y-auto gap-x-2"> <div className="flex flex-row justify-start items-start flex-wrap px-2 max-w-48 h-auto max-h-48 overflow-y-auto gap-x-2">

@ -6,6 +6,8 @@ import { Button } from "@/components/ui/button";
import { attachmentStore } from "@/store"; import { attachmentStore } from "@/store";
import { Attachment } from "@/types/proto/api/v1/attachment_service"; import { Attachment } from "@/types/proto/api/v1/attachment_service";
import { MemoEditorContext } from "../types"; import { MemoEditorContext } from "../types";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { t } from "i18next";
interface Props { interface Props {
isUploading?: boolean; isUploading?: boolean;
@ -73,19 +75,28 @@ const UploadAttachmentButton = observer((props: Props) => {
const isUploading = state.uploadingFlag || props.isUploading; const isUploading = state.uploadingFlag || props.isUploading;
return ( return (
<Button className="relative" variant="ghost" size="icon" disabled={isUploading}> <TooltipProvider>
{isUploading ? <LoaderIcon className="size-5 animate-spin" /> : <PaperclipIcon className="size-5" />} <Tooltip>
<input <TooltipTrigger asChild>
className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" <Button className="relative" variant="ghost" size="icon" disabled={isUploading}>
ref={fileInputRef} {isUploading ? <LoaderIcon className="size-5 animate-spin" /> : <PaperclipIcon className="size-5" />}
disabled={isUploading} <input
onChange={handleFileInputChange} className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
type="file" ref={fileInputRef}
id="files" disabled={isUploading}
multiple={true} onChange={handleFileInputChange}
accept="*" type="file"
/> id="files"
</Button> multiple={true}
accept="*"
/>
</Button>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>{t("tooltip.upload-attachment")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
); );
}); });

@ -2,6 +2,7 @@ import VisibilityIcon from "@/components/VisibilityIcon";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Visibility } from "@/types/proto/api/v1/memo_service"; import { Visibility } from "@/types/proto/api/v1/memo_service";
import { useTranslate } from "@/utils/i18n"; import { useTranslate } from "@/utils/i18n";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; // ⬅️ ADD this line
interface Props { interface Props {
value: Visibility; value: Visibility;
@ -26,19 +27,28 @@ const VisibilitySelector = (props: Props) => {
}; };
return ( return (
<Select value={value.toString()} onValueChange={onChange} onOpenChange={handleOpenChange}> <TooltipProvider>
<SelectTrigger size="xs" className="!bg-background"> <Tooltip>
<SelectValue /> <TooltipTrigger asChild>
</SelectTrigger> <Select value={value.toString()} onValueChange={onChange} onOpenChange={handleOpenChange}>
<SelectContent align="end"> <SelectTrigger size="xs" className="!bg-background">
{visibilityOptions.map((option) => ( <SelectValue />
<SelectItem key={option.value} value={option.value.toString()}> </SelectTrigger>
<VisibilityIcon className="size-3.5" visibility={option.value} /> <SelectContent align="end">
{option.label} {visibilityOptions.map((option) => (
</SelectItem> <SelectItem key={option.value} value={option.value.toString()}>
))} <VisibilityIcon className="size-3.5" visibility={option.value} />
</SelectContent> {option.label}
</Select> </SelectItem>
))}
</SelectContent>
</Select>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>{t("tooltip.select-visibility")}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
); );
}; };

@ -443,5 +443,13 @@
"rename-success": "Renamed tag successfully", "rename-success": "Renamed tag successfully",
"rename-tag": "Rename tag", "rename-tag": "Rename tag",
"rename-tip": "All your memos with this tag will be updated." "rename-tip": "All your memos with this tag will be updated."
},
"tooltip": {
"link-memo": "Link Memo",
"markdown-menu": "Markdown",
"select-location": "Location",
"select-visibility": "Visibility",
"tags": "Tags",
"upload-attachment": "Upload Attachment(s)"
} }
} }

Loading…
Cancel
Save