mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
fix: Use singleton for tooltips, ensures that only one is visible at a time. (#8069)
* fix: Use singleton for tooltips, ensures that only one is visible at a time and animations are shared * fix: give toolbar menu its own context * Remove duplicate props
This commit is contained in:
@@ -144,12 +144,7 @@ function DocumentCard(props: Props) {
|
||||
</Heading>
|
||||
<DocumentMeta size="xsmall">
|
||||
<Clock size={18} />
|
||||
<Time
|
||||
dateTime={document.updatedAt}
|
||||
tooltipDelay={500}
|
||||
addSuffix
|
||||
shorten
|
||||
/>
|
||||
<Time dateTime={document.updatedAt} addSuffix shorten />
|
||||
</DocumentMeta>
|
||||
</div>
|
||||
</Content>
|
||||
|
||||
@@ -111,11 +111,7 @@ function DocumentListItem(
|
||||
<Badge yellow>{t("New")}</Badge>
|
||||
)}
|
||||
{document.isDraft && showDraft && (
|
||||
<Tooltip
|
||||
content={t("Only visible to you")}
|
||||
delay={500}
|
||||
placement="top"
|
||||
>
|
||||
<Tooltip content={t("Only visible to you")} placement="top">
|
||||
<Badge>{t("Draft")}</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
@@ -140,7 +140,6 @@ const EventListItem = ({ event, latest, document, ...rest }: Props) => {
|
||||
title={
|
||||
<Time
|
||||
dateTime={event.createdAt}
|
||||
tooltipDelay={500}
|
||||
format={{
|
||||
en_US: "MMM do, h:mm a",
|
||||
fr_FR: "'Le 'd MMMM 'à' H:mm",
|
||||
|
||||
@@ -23,7 +23,6 @@ function eachMinute(fn: () => void) {
|
||||
export type Props = {
|
||||
children?: React.ReactNode;
|
||||
dateTime: string;
|
||||
tooltipDelay?: number;
|
||||
addSuffix?: boolean;
|
||||
shorten?: boolean;
|
||||
relative?: boolean;
|
||||
@@ -37,7 +36,6 @@ const LocaleTime: React.FC<Props> = ({
|
||||
shorten,
|
||||
format,
|
||||
relative,
|
||||
tooltipDelay,
|
||||
}: Props) => {
|
||||
const userLocale = useUserLocale();
|
||||
const dateFormatLong: Record<string, string> = {
|
||||
@@ -82,7 +80,7 @@ const LocaleTime: React.FC<Props> = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<Tooltip content={tooltipContent} delay={tooltipDelay} placement="bottom">
|
||||
<Tooltip content={tooltipContent} placement="bottom">
|
||||
<time dateTime={dateTime}>{children || content}</time>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -52,11 +52,7 @@ function NotificationListItem({ notification, onNavigate }: Props) {
|
||||
<Text weight="bold">{notification.subject}</Text>
|
||||
</Text>
|
||||
<Text type="tertiary" size="xsmall">
|
||||
<Time
|
||||
dateTime={notification.createdAt}
|
||||
tooltipDelay={1000}
|
||||
addSuffix
|
||||
/>{" "}
|
||||
<Time dateTime={notification.createdAt} addSuffix />{" "}
|
||||
{collection && <>· {collection.name}</>}
|
||||
</Text>
|
||||
{notification.comment && (
|
||||
|
||||
@@ -60,7 +60,7 @@ function Notifications(
|
||||
</Text>
|
||||
<Flex gap={8}>
|
||||
{notifications.approximateUnreadCount > 0 && (
|
||||
<Tooltip delay={500} content={t("Mark all as read")}>
|
||||
<Tooltip content={t("Mark all as read")}>
|
||||
<Button action={markNotificationsAsRead} context={context}>
|
||||
<MarkAsReadIcon />
|
||||
</Button>
|
||||
|
||||
@@ -128,7 +128,7 @@ const Reaction: React.FC<Props> = ({
|
||||
);
|
||||
|
||||
return tooltipContent ? (
|
||||
<Tooltip content={tooltipContent} delay={250} placement="bottom">
|
||||
<Tooltip content={tooltipContent} placement="bottom">
|
||||
{DisplayedEmoji}
|
||||
</Tooltip>
|
||||
) : (
|
||||
|
||||
@@ -98,12 +98,7 @@ const ReactionPicker: React.FC<Props> = ({
|
||||
<>
|
||||
<PopoverDisclosure {...popover}>
|
||||
{(props) => (
|
||||
<Tooltip
|
||||
content={t("Add reaction")}
|
||||
placement="top"
|
||||
delay={500}
|
||||
hideOnClick
|
||||
>
|
||||
<Tooltip content={t("Add reaction")} placement="top" hideOnClick>
|
||||
<NudeButton
|
||||
{...props}
|
||||
aria-label={t("Reaction picker")}
|
||||
|
||||
@@ -119,7 +119,7 @@ function PublicAccess({ document, share, sharedParent }: Props) {
|
||||
: share?.url ?? "";
|
||||
|
||||
const copyButton = (
|
||||
<Tooltip content={t("Copy public link")} delay={500} placement="top">
|
||||
<Tooltip content={t("Copy public link")} placement="top">
|
||||
<CopyToClipboard text={shareUrl} onCopy={handleCopied}>
|
||||
<NudeButton type="button" disabled={!share} style={{ marginRight: 3 }}>
|
||||
<CopyIcon color={theme.placeholder} size={18} />
|
||||
|
||||
@@ -31,7 +31,7 @@ export function CopyLinkButton({
|
||||
}, [onCopy, t]);
|
||||
|
||||
return (
|
||||
<Tooltip content={t("Copy link")} delay={500} placement="top">
|
||||
<Tooltip content={t("Copy link")} placement="top">
|
||||
<CopyToClipboard text={url} onCopy={handleCopied}>
|
||||
<NudeButton type="button">
|
||||
<LinkIcon size={20} />
|
||||
|
||||
@@ -80,7 +80,6 @@ function AppSidebar() {
|
||||
<Tooltip
|
||||
content={t("Toggle sidebar")}
|
||||
shortcut={`${metaDisplay}+.`}
|
||||
delay={500}
|
||||
>
|
||||
<ToggleButton
|
||||
position="bottom"
|
||||
|
||||
@@ -42,11 +42,7 @@ function SettingsSidebar() {
|
||||
image={<StyledBackIcon />}
|
||||
onClick={returnToApp}
|
||||
>
|
||||
<Tooltip
|
||||
content={t("Toggle sidebar")}
|
||||
shortcut={`${metaDisplay}+.`}
|
||||
delay={500}
|
||||
>
|
||||
<Tooltip content={t("Toggle sidebar")} shortcut={`${metaDisplay}+.`}>
|
||||
<ToggleButton
|
||||
position="bottom"
|
||||
image={<SidebarIcon />}
|
||||
|
||||
@@ -81,11 +81,7 @@ const ToggleSidebar = () => {
|
||||
const { ui } = useStores();
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={t("Toggle sidebar")}
|
||||
shortcut={`${metaDisplay}+.`}
|
||||
delay={500}
|
||||
>
|
||||
<Tooltip content={t("Toggle sidebar")} shortcut={`${metaDisplay}+.`}>
|
||||
<ToggleButton
|
||||
position="bottom"
|
||||
image={<SidebarIcon />}
|
||||
|
||||
@@ -278,7 +278,7 @@ function InnerDocumentLink(
|
||||
!isDraggingAnyDocument ? (
|
||||
<Fade>
|
||||
{can.createChildDocument && (
|
||||
<Tooltip content={t("New doc")} delay={500}>
|
||||
<Tooltip content={t("New doc")}>
|
||||
<NudeButton
|
||||
type={undefined}
|
||||
aria-label={t("New nested document")}
|
||||
|
||||
@@ -43,12 +43,12 @@ function HistoryNavigation(props: React.ComponentProps<typeof Flex>) {
|
||||
|
||||
return (
|
||||
<Navigation gap={4} {...props}>
|
||||
<Tooltip content={t("Go back")} delay={500}>
|
||||
<Tooltip content={t("Go back")}>
|
||||
<NudeButton onClick={() => Desktop.bridge?.goBack()}>
|
||||
<Back $active={back} />
|
||||
</NudeButton>
|
||||
</Tooltip>
|
||||
<Tooltip content={t("Go forward")} delay={500}>
|
||||
<Tooltip content={t("Go forward")}>
|
||||
<NudeButton onClick={() => Desktop.bridge?.goForward()}>
|
||||
<Forward $active={forward} />
|
||||
</NudeButton>
|
||||
|
||||
@@ -22,7 +22,7 @@ function Time({ onClick, ...props }: Props) {
|
||||
<time dateTime={props.dateTime}>{props.children || content}</time>
|
||||
}
|
||||
>
|
||||
<LocaleTime tooltipDelay={250} {...props} />
|
||||
<LocaleTime {...props} />
|
||||
</React.Suspense>
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import Tippy, { TippyProps } from "@tippyjs/react";
|
||||
import * as React from "react";
|
||||
import styled, { createGlobalStyle } from "styled-components";
|
||||
import { roundArrow } from "tippy.js";
|
||||
import { s } from "@shared/styles";
|
||||
import useMobile from "~/hooks/useMobile";
|
||||
import { useTooltipContext } from "./TooltipContext";
|
||||
|
||||
export type Props = Omit<TippyProps, "content" | "theme"> & {
|
||||
/** The content to display in the tooltip. */
|
||||
@@ -12,8 +12,9 @@ export type Props = Omit<TippyProps, "content" | "theme"> & {
|
||||
shortcut?: React.ReactNode;
|
||||
};
|
||||
|
||||
function Tooltip({ shortcut, content: tooltip, delay = 50, ...rest }: Props) {
|
||||
function Tooltip({ shortcut, content: tooltip, delay = 500, ...rest }: Props) {
|
||||
const isMobile = useMobile();
|
||||
const singleton = useTooltipContext();
|
||||
|
||||
let content = <>{tooltip}</>;
|
||||
|
||||
@@ -30,15 +31,7 @@ function Tooltip({ shortcut, content: tooltip, delay = 50, ...rest }: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<Tippy
|
||||
arrow={roundArrow}
|
||||
animation="shift-away"
|
||||
content={content}
|
||||
delay={delay}
|
||||
duration={[200, 150]}
|
||||
inertia
|
||||
{...rest}
|
||||
/>
|
||||
<Tippy content={content} delay={delay} singleton={singleton} {...rest} />
|
||||
);
|
||||
}
|
||||
|
||||
@@ -132,7 +125,7 @@ export const TooltipStyles = createGlobalStyle`
|
||||
padding:5px 9px;
|
||||
z-index:1
|
||||
}
|
||||
|
||||
|
||||
/* Arrow Styles */
|
||||
.tippy-box[data-placement^=top]>.tippy-svg-arrow{
|
||||
bottom:0
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import Tippy, { useSingleton, TippyProps } from "@tippyjs/react";
|
||||
import * as React from "react";
|
||||
import { roundArrow } from "tippy.js";
|
||||
|
||||
export const TooltipContext =
|
||||
React.createContext<TippyProps["singleton"]>(undefined);
|
||||
|
||||
export function useTooltipContext() {
|
||||
return React.useContext(TooltipContext);
|
||||
}
|
||||
|
||||
type Props = {
|
||||
children: React.ReactNode;
|
||||
tippyProps?: TippyProps;
|
||||
};
|
||||
|
||||
export function TooltipProvider({ children, tippyProps }: Props) {
|
||||
const [source, target] = useSingleton();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tippy
|
||||
delay={500}
|
||||
arrow={roundArrow}
|
||||
animation="shift-away"
|
||||
singleton={source}
|
||||
duration={[200, 150]}
|
||||
inertia
|
||||
{...tippyProps}
|
||||
/>
|
||||
<TooltipContext.Provider value={target}>
|
||||
{children}
|
||||
</TooltipContext.Provider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -286,7 +286,6 @@ export default function FindAndReplace({
|
||||
<Tooltip
|
||||
content={t("Previous match")}
|
||||
shortcut="shift+enter"
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<ButtonLarge
|
||||
@@ -296,12 +295,7 @@ export default function FindAndReplace({
|
||||
<CaretUpIcon />
|
||||
</ButtonLarge>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
content={t("Next match")}
|
||||
shortcut="enter"
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Tooltip content={t("Next match")} shortcut="enter" placement="bottom">
|
||||
<ButtonLarge
|
||||
disabled={disabled}
|
||||
onClick={() => editor.commands.nextSearchMatch()}
|
||||
@@ -336,7 +330,6 @@ export default function FindAndReplace({
|
||||
<Tooltip
|
||||
content={t("Match case")}
|
||||
shortcut={`${altDisplay}+${metaDisplay}+c`}
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<ButtonSmall onClick={handleCaseSensitive}>
|
||||
@@ -348,7 +341,6 @@ export default function FindAndReplace({
|
||||
<Tooltip
|
||||
content={t("Enable regex")}
|
||||
shortcut={`${altDisplay}+${metaDisplay}+r`}
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<ButtonSmall onClick={handleRegex}>
|
||||
@@ -361,11 +353,7 @@ export default function FindAndReplace({
|
||||
</StyledInput>
|
||||
{navigation}
|
||||
{!readOnly && (
|
||||
<Tooltip
|
||||
content={t("Replace options")}
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Tooltip content={t("Replace options")} placement="bottom">
|
||||
<ButtonLarge onClick={handleMore}>
|
||||
<ReplaceIcon color={theme.textSecondary} />
|
||||
</ButtonLarge>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { TippyProps } from "@tippyjs/react";
|
||||
import * as React from "react";
|
||||
import { useMenuState } from "reakit";
|
||||
import { MenuButton } from "reakit/Menu";
|
||||
@@ -7,6 +8,7 @@ import { MenuItem } from "@shared/editor/types";
|
||||
import { s } from "@shared/styles";
|
||||
import ContextMenu from "~/components/ContextMenu";
|
||||
import Template from "~/components/ContextMenu/Template";
|
||||
import { TooltipProvider } from "~/components/TooltipContext";
|
||||
import { MenuItem as TMenuItem } from "~/types";
|
||||
import { useEditor } from "./EditorContext";
|
||||
import ToolbarButton from "./ToolbarButton";
|
||||
@@ -75,6 +77,8 @@ function ToolbarDropdown(props: { active: boolean; item: MenuItem }) {
|
||||
);
|
||||
}
|
||||
|
||||
const tippyProps = { placement: "top" } as TippyProps;
|
||||
|
||||
function ToolbarMenu(props: Props) {
|
||||
const { commands, view } = useEditor();
|
||||
const { items } = props;
|
||||
@@ -91,36 +95,38 @@ function ToolbarMenu(props: Props) {
|
||||
};
|
||||
|
||||
return (
|
||||
<FlexibleWrapper>
|
||||
{items.map((item, index) => {
|
||||
if (item.name === "separator" && item.visible !== false) {
|
||||
return <ToolbarSeparator key={index} />;
|
||||
}
|
||||
if (item.visible === false || !item.icon) {
|
||||
return null;
|
||||
}
|
||||
const isActive = item.active ? item.active(state) : false;
|
||||
<TooltipProvider tippyProps={tippyProps}>
|
||||
<FlexibleWrapper>
|
||||
{items.map((item, index) => {
|
||||
if (item.name === "separator" && item.visible !== false) {
|
||||
return <ToolbarSeparator key={index} />;
|
||||
}
|
||||
if (item.visible === false || !item.icon) {
|
||||
return null;
|
||||
}
|
||||
const isActive = item.active ? item.active(state) : false;
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={item.label === item.tooltip ? undefined : item.tooltip}
|
||||
key={index}
|
||||
>
|
||||
{item.children ? (
|
||||
<ToolbarDropdown active={isActive && !item.label} item={item} />
|
||||
) : (
|
||||
<ToolbarButton
|
||||
onClick={handleClick(item)}
|
||||
active={isActive && !item.label}
|
||||
>
|
||||
{item.label && <Label>{item.label}</Label>}
|
||||
{item.icon}
|
||||
</ToolbarButton>
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</FlexibleWrapper>
|
||||
return (
|
||||
<Tooltip
|
||||
content={item.label === item.tooltip ? undefined : item.tooltip}
|
||||
key={index}
|
||||
>
|
||||
{item.children ? (
|
||||
<ToolbarDropdown active={isActive && !item.label} item={item} />
|
||||
) : (
|
||||
<ToolbarButton
|
||||
onClick={handleClick(item)}
|
||||
active={isActive && !item.label}
|
||||
>
|
||||
{item.label && <Label>{item.label}</Label>}
|
||||
{item.icon}
|
||||
</ToolbarButton>
|
||||
)}
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</FlexibleWrapper>
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,18 @@ type Props = {
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
const WrappedTooltip: React.FC<Props> = ({ children, content }: Props) => (
|
||||
<Tooltip offset={[0, 16]} delay={150} content={content} placement="top">
|
||||
const WrappedTooltip: React.FC<Props> = ({
|
||||
children,
|
||||
content,
|
||||
...rest
|
||||
}: Props) => (
|
||||
<Tooltip
|
||||
offset={[0, 16]}
|
||||
delay={150}
|
||||
content={content}
|
||||
placement="top"
|
||||
{...rest}
|
||||
>
|
||||
<TooltipContent>{children}</TooltipContent>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
+18
-15
@@ -20,6 +20,7 @@ import { initI18n } from "~/utils/i18n";
|
||||
import Desktop from "./components/DesktopEventHandler";
|
||||
import LazyPolyfill from "./components/LazyPolyfills";
|
||||
import PageScroll from "./components/PageScroll";
|
||||
import { TooltipProvider } from "./components/TooltipContext";
|
||||
import Routes from "./routes";
|
||||
import Logger from "./utils/Logger";
|
||||
import { PluginManager } from "./utils/PluginManager";
|
||||
@@ -55,21 +56,23 @@ if (element) {
|
||||
<Theme>
|
||||
<ErrorBoundary showTitle>
|
||||
<KBarProvider actions={[]} options={commandBarOptions}>
|
||||
<LazyPolyfill>
|
||||
<LazyMotion features={loadFeatures}>
|
||||
<Router history={history}>
|
||||
<PageScroll>
|
||||
<PageTheme />
|
||||
<ScrollToTop>
|
||||
<Routes />
|
||||
</ScrollToTop>
|
||||
<Toasts />
|
||||
<Dialogs />
|
||||
<Desktop />
|
||||
</PageScroll>
|
||||
</Router>
|
||||
</LazyMotion>
|
||||
</LazyPolyfill>
|
||||
<TooltipProvider>
|
||||
<LazyPolyfill>
|
||||
<LazyMotion features={loadFeatures}>
|
||||
<Router history={history}>
|
||||
<PageScroll>
|
||||
<PageTheme />
|
||||
<ScrollToTop>
|
||||
<Routes />
|
||||
</ScrollToTop>
|
||||
<Toasts />
|
||||
<Dialogs />
|
||||
<Desktop />
|
||||
</PageScroll>
|
||||
</Router>
|
||||
</LazyMotion>
|
||||
</LazyPolyfill>
|
||||
</TooltipProvider>
|
||||
</KBarProvider>
|
||||
</ErrorBoundary>
|
||||
</Theme>
|
||||
|
||||
@@ -19,12 +19,7 @@ function NewDocumentMenu() {
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={t("New document")}
|
||||
shortcut="n"
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Tooltip content={t("New document")} shortcut="n" placement="bottom">
|
||||
<Button as={Link} to={newDocumentPath()} icon={<PlusIcon />}>
|
||||
{t("New doc")}
|
||||
</Button>
|
||||
|
||||
@@ -27,7 +27,6 @@ function Actions({ collection }: Props) {
|
||||
<Tooltip
|
||||
content={t("New document")}
|
||||
shortcut="n"
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button
|
||||
|
||||
@@ -316,7 +316,7 @@ function CommentForm({
|
||||
{t("Cancel")}
|
||||
</ButtonSmall>
|
||||
</Flex>
|
||||
<Tooltip delay={500} content={t("Upload image")} placement="top">
|
||||
<Tooltip content={t("Upload image")} placement="top">
|
||||
<NudeButton onClick={handleImageUpload}>
|
||||
<ImageIcon color={theme.textTertiary} />
|
||||
</NudeButton>
|
||||
|
||||
@@ -197,21 +197,12 @@ function CommentThreadItem({
|
||||
{showAuthor && <em>{comment.createdBy.name}</em>}
|
||||
{showAuthor && showTime && <> · </>}
|
||||
{showTime && (
|
||||
<Time
|
||||
dateTime={comment.createdAt}
|
||||
tooltipDelay={500}
|
||||
addSuffix
|
||||
shorten
|
||||
/>
|
||||
<Time dateTime={comment.createdAt} addSuffix shorten />
|
||||
)}
|
||||
{showEdited && (
|
||||
<>
|
||||
{" "}
|
||||
(
|
||||
<Time dateTime={comment.updatedAt} tooltipDelay={500}>
|
||||
{t("edited")}
|
||||
</Time>
|
||||
)
|
||||
(<Time dateTime={comment.updatedAt}>{t("edited")}</Time>)
|
||||
</>
|
||||
)}
|
||||
</Meta>
|
||||
@@ -304,12 +295,7 @@ const ResolveButton = ({
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={t("Mark as resolved")}
|
||||
placement="top"
|
||||
delay={500}
|
||||
hideOnClick
|
||||
>
|
||||
<Tooltip content={t("Mark as resolved")} placement="top" hideOnClick>
|
||||
<Action
|
||||
as={NudeButton}
|
||||
context={context}
|
||||
|
||||
@@ -133,7 +133,6 @@ function DocumentHeader({
|
||||
: `${t("Show contents")} (${t("available when headings are added")})`
|
||||
}
|
||||
shortcut={`ctrl+${altDisplay}+h`}
|
||||
delay={250}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button
|
||||
@@ -151,7 +150,6 @@ function DocumentHeader({
|
||||
noun: document.noun,
|
||||
})}
|
||||
shortcut="e"
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button
|
||||
@@ -171,7 +169,6 @@ function DocumentHeader({
|
||||
content={
|
||||
resolvedTheme === "light" ? t("Switch to dark") : t("Switch to light")
|
||||
}
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button
|
||||
@@ -290,7 +287,6 @@ function DocumentHeader({
|
||||
<Tooltip
|
||||
content={t("Save")}
|
||||
shortcut={`${metaDisplay}+enter`}
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button
|
||||
@@ -323,7 +319,6 @@ function DocumentHeader({
|
||||
<Tooltip
|
||||
content={t("New document")}
|
||||
shortcut="n"
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Button icon={<PlusIcon />} {...props} neutral>
|
||||
@@ -336,11 +331,7 @@ function DocumentHeader({
|
||||
)}
|
||||
{revision && revision.createdAt !== document.updatedAt && (
|
||||
<Action>
|
||||
<Tooltip
|
||||
content={t("Restore version")}
|
||||
delay={500}
|
||||
placement="bottom"
|
||||
>
|
||||
<Tooltip content={t("Restore version")} placement="bottom">
|
||||
<Button
|
||||
action={restoreRevision}
|
||||
context={context}
|
||||
|
||||
@@ -23,7 +23,7 @@ function KeyboardShortcutsButton() {
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip content={t("Keyboard shortcuts")} shortcut="?" delay={500}>
|
||||
<Tooltip content={t("Keyboard shortcuts")} shortcut="?">
|
||||
<Button onClick={handleOpenKeyboardShortcuts} $hidden={isEditingFocus}>
|
||||
<KeyboardIcon />
|
||||
</Button>
|
||||
|
||||
@@ -32,7 +32,7 @@ function SidebarLayout({ title, onClose, children, scrollable = true }: Props) {
|
||||
<>
|
||||
<Header>
|
||||
<Title>{title}</Title>
|
||||
<Tooltip content={t("Close")} shortcut="Esc" delay={500}>
|
||||
<Tooltip content={t("Close")} shortcut="Esc">
|
||||
<Button
|
||||
icon={<ForwardIcon />}
|
||||
onClick={onClose}
|
||||
|
||||
@@ -17,7 +17,7 @@ export function DocumentFilter(props: Props) {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tooltip content={t("Remove document filter")} delay={350}>
|
||||
<Tooltip content={t("Remove document filter")}>
|
||||
<StyledButton onClick={props.onClick} icon={<CloseIcon />} neutral>
|
||||
{props.document.title}
|
||||
</StyledButton>
|
||||
|
||||
@@ -33,7 +33,7 @@ function RecentSearchListItem({ searchQuery }: Props) {
|
||||
{...rovingTabIndex}
|
||||
>
|
||||
{searchQuery.query}
|
||||
<Tooltip content={t("Remove search")} delay={150}>
|
||||
<Tooltip content={t("Remove search")}>
|
||||
<RemoveButton
|
||||
aria-label={t("Remove search")}
|
||||
onClick={async (ev) => {
|
||||
|
||||
Reference in New Issue
Block a user