diff --git a/webapp/channels/src/components/advanced_text_editor/send_button/send_post_options/index.tsx b/webapp/channels/src/components/advanced_text_editor/send_button/send_post_options/index.tsx
index 5951a22d87..aa6453ae13 100644
--- a/webapp/channels/src/components/advanced_text_editor/send_button/send_post_options/index.tsx
+++ b/webapp/channels/src/components/advanced_text_editor/send_button/send_post_options/index.tsx
@@ -64,7 +64,6 @@ export function SendPostOptions({disabled, onSelect, channelId}: Props) {
return (
{
barContent = (
{barContent}
diff --git a/webapp/channels/src/components/announcement_bar/default_announcement_bar/default_announcement_bar.scss b/webapp/channels/src/components/announcement_bar/default_announcement_bar/default_announcement_bar.scss
index 46205a5e2f..4315f1e327 100644
--- a/webapp/channels/src/components/announcement_bar/default_announcement_bar/default_announcement_bar.scss
+++ b/webapp/channels/src/components/announcement_bar/default_announcement_bar/default_announcement_bar.scss
@@ -1,5 +1,5 @@
.announcementBarTooltip {
min-width: 50vw;
- max-width: 100vw;
+ max-width: 90vw;
pointer-events: auto;
}
diff --git a/webapp/channels/src/components/channel_bookmarks/channel_bookmarks_menu.tsx b/webapp/channels/src/components/channel_bookmarks/channel_bookmarks_menu.tsx
index bffc4047c4..2e2d031e81 100644
--- a/webapp/channels/src/components/channel_bookmarks/channel_bookmarks_menu.tsx
+++ b/webapp/channels/src/components/channel_bookmarks/channel_bookmarks_menu.tsx
@@ -82,7 +82,6 @@ function BookmarksMenu({
id: 'channelBookmarksPlusMenuDropdown',
}}
menuButtonTooltip={addBookmarkTooltipText ? {
- id: 'channelBookmarksPlusMenuButtonTooltip',
text: addBookmarkTooltipText,
} : undefined}
>
diff --git a/webapp/channels/src/components/dot_menu/__snapshots__/dot_menu.test.tsx.snap b/webapp/channels/src/components/dot_menu/__snapshots__/dot_menu.test.tsx.snap
index 264cf3fa55..c87388ca68 100644
--- a/webapp/channels/src/components/dot_menu/__snapshots__/dot_menu.test.tsx.snap
+++ b/webapp/channels/src/components/dot_menu/__snapshots__/dot_menu.test.tsx.snap
@@ -352,7 +352,6 @@ exports[`components/dot_menu/DotMenu should match snapshot, on Center 1`] = `
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "PostDotMenu-ButtonTooltip-post_id_1",
"text": "More",
}
}
diff --git a/webapp/channels/src/components/dot_menu/dot_menu.tsx b/webapp/channels/src/components/dot_menu/dot_menu.tsx
index 4637fa6083..791f2aecb7 100644
--- a/webapp/channels/src/components/dot_menu/dot_menu.tsx
+++ b/webapp/channels/src/components/dot_menu/dot_menu.tsx
@@ -507,7 +507,6 @@ export class DotMenuClass extends React.PureComponent {
onToggle: this.handleMenuToggle,
}}
menuButtonTooltip={{
- id: `PostDotMenu-ButtonTooltip-${this.props.post.id}`,
text: formatMessage({id: 'post_info.dot_menu.tooltip.more', defaultMessage: 'More'}),
class: 'hidden-xs',
}}
diff --git a/webapp/channels/src/components/menu/menu.tsx b/webapp/channels/src/components/menu/menu.tsx
index 06c0d29b86..76f0a8d2a1 100644
--- a/webapp/channels/src/components/menu/menu.tsx
+++ b/webapp/channels/src/components/menu/menu.tsx
@@ -44,7 +44,6 @@ type MenuButtonProps = {
}
type MenuButtonTooltipProps = {
- id: string;
isVertical?: boolean;
class?: string;
text: string;
diff --git a/webapp/channels/src/components/profile_popover/profile_popover_controller.tsx b/webapp/channels/src/components/profile_popover/profile_popover_controller.tsx
index 4f873b5dad..133c32ece8 100644
--- a/webapp/channels/src/components/profile_popover/profile_popover_controller.tsx
+++ b/webapp/channels/src/components/profile_popover/profile_popover_controller.tsx
@@ -85,13 +85,7 @@ export function ProfilePopoverController
middleware: [autoPlacement()],
});
- const {isMounted, styles: transitionStyles} = useTransitionStyles(floatingContext, {
- duration: {
- open: OverlaysTimings.FADE_IN_DURATION,
- close: OverlaysTimings.FADE_OUT_DURATION,
- },
- initial: OverlayTransitionStyles.START,
- });
+ const {isMounted, styles: transitionStyles} = useTransitionStyles(floatingContext, TRANSITION_STYLE_PROPS);
const clickInteractions = useClick(floatingContext);
const dismissInteraction = useDismiss(floatingContext);
@@ -154,3 +148,11 @@ export function ProfilePopoverController
>
);
}
+
+const TRANSITION_STYLE_PROPS = {
+ duration: {
+ open: OverlaysTimings.FADE_IN_DURATION,
+ close: OverlaysTimings.FADE_OUT_DURATION,
+ },
+ initial: OverlayTransitionStyles.START,
+};
diff --git a/webapp/channels/src/components/sidebar/sidebar_category/__snapshots__/sidebar_category_sorting_menu.test.tsx.snap b/webapp/channels/src/components/sidebar/sidebar_category/__snapshots__/sidebar_category_sorting_menu.test.tsx.snap
index 168253624a..e94e02383f 100644
--- a/webapp/channels/src/components/sidebar/sidebar_category/__snapshots__/sidebar_category_sorting_menu.test.tsx.snap
+++ b/webapp/channels/src/components/sidebar/sidebar_category/__snapshots__/sidebar_category_sorting_menu.test.tsx.snap
@@ -25,7 +25,6 @@ exports[`components/sidebar/sidebar_category/sidebar_category_sorting_menu shoul
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarCategorySortingMenu-ButtonTooltip-category_id",
"text": "Category options",
}
}
diff --git a/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_menu/sidebar_category_generic_menu.tsx b/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_menu/sidebar_category_generic_menu.tsx
index 6f778997ea..5806f84792 100644
--- a/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_menu/sidebar_category_generic_menu.tsx
+++ b/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_menu/sidebar_category_generic_menu.tsx
@@ -47,7 +47,6 @@ const SidebarCategoryGenericMenu = ({
children: ,
}}
menuButtonTooltip={{
- id: `SidebarCategoryMenu-ButtonTooltip-${id}`,
text: formatMessage({id: 'sidebar_left.sidebar_category_menu.editCategory', defaultMessage: 'Category options'}),
class: 'hidden-xs',
}}
diff --git a/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_sorting_menu.tsx b/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_sorting_menu.tsx
index 5ca3ad11f7..293ab78f01 100644
--- a/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_sorting_menu.tsx
+++ b/webapp/channels/src/components/sidebar/sidebar_category/sidebar_category_sorting_menu.tsx
@@ -198,7 +198,6 @@ const SidebarCategorySortingMenu = ({
children: ,
}}
menuButtonTooltip={{
- id: `SidebarCategorySortingMenu-ButtonTooltip-${category.id}`,
text: formatMessage({id: 'sidebar_left.sidebar_category_menu.editCategory', defaultMessage: 'Category options'}),
class: 'hidden-xs',
}}
diff --git a/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/__snapshots__/sidebar_channel_menu.test.tsx.snap b/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/__snapshots__/sidebar_channel_menu.test.tsx.snap
index e46d135600..067f2bffcf 100644
--- a/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/__snapshots__/sidebar_channel_menu.test.tsx.snap
+++ b/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/__snapshots__/sidebar_channel_menu.test.tsx.snap
@@ -22,7 +22,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should match sn
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -168,7 +167,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should match sn
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -314,7 +312,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should match sn
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -460,7 +457,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should show cor
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -574,7 +570,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should show cor
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -703,7 +698,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should show cor
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -849,7 +843,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should show cor
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -995,7 +988,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should show cor
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -1141,7 +1133,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should show cor
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
@@ -1287,7 +1278,6 @@ exports[`components/sidebar/sidebar_channel/sidebar_channel_menu should show cor
menuButtonTooltip={
Object {
"class": "hidden-xs",
- "id": "SidebarChannelMenu-ButtonTooltip-channel_id",
"text": "Channel options",
}
}
diff --git a/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/sidebar_channel_menu.tsx b/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/sidebar_channel_menu.tsx
index 6687733201..14c4ace952 100644
--- a/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/sidebar_channel_menu.tsx
+++ b/webapp/channels/src/components/sidebar/sidebar_channel/sidebar_channel_menu/sidebar_channel_menu.tsx
@@ -297,7 +297,6 @@ const SidebarChannelMenu = ({
children: ,
}}
menuButtonTooltip={{
- id: `SidebarChannelMenu-ButtonTooltip-${channel.id}`,
class: 'hidden-xs',
text: formatMessage({id: 'sidebar_left.sidebar_channel_menu.editChannel', defaultMessage: 'Channel options'}),
}}
diff --git a/webapp/channels/src/components/user_group_popover/user_group_popover.scss b/webapp/channels/src/components/user_group_popover/user_group_popover.scss
index 928860c4c5..2a1ba96858 100644
--- a/webapp/channels/src/components/user_group_popover/user_group_popover.scss
+++ b/webapp/channels/src/components/user_group_popover/user_group_popover.scss
@@ -1,8 +1,9 @@
+@use 'utils/variables';
+
#user-group-popover .popover-content {
padding: 0;
}
.user-group-popover-floating-overlay {
- // 99 being the z-index of the global header
- z-index: 1060;
+ z-index: variables.$z-index-user-group-popover;
}
diff --git a/webapp/channels/src/components/with_tooltip/index.tsx b/webapp/channels/src/components/with_tooltip/index.tsx
index a9785359dd..4f2decbfcf 100644
--- a/webapp/channels/src/components/with_tooltip/index.tsx
+++ b/webapp/channels/src/components/with_tooltip/index.tsx
@@ -24,21 +24,17 @@ import type {ReactElement, ReactNode} from 'react';
import type {MessageDescriptor} from 'react-intl';
import {defineMessage} from 'react-intl';
-import {Constants} from 'utils/constants';
+import {OverlayArrow, OverlaysTimings, OverlayTransitionStyles, RootHtmlPortalId} from 'utils/constants';
import TooltipContent from './tooltip_content';
import type {ShortcutDefinition} from './tooltip_shortcut';
-import './tooltip.scss';
-
-const ARROW_WIDTH = 10; // in px
-const ARROW_HEIGHT = 6; // in px
-const ARROW_OFFSET = 8; // in px
-
-const TOOLTIP_REST_TIME_BEFORE_OPEN = 400; // in ms
-const TOOLTIP_APPEAR_DURATION = 250; // in ms
-const TOOLTIP_DISAPPEAR_DURATION = 200; // in ms
+import './with_tooltip.scss';
+/**
+ * Shortcut keys map to translations that can be used in the tooltip
+ * when shortcut definition is provided
+ */
export const ShortcutKeys = {
alt: defineMessage({
id: 'shortcuts.generic.alt',
@@ -68,7 +64,17 @@ interface Props {
* This doesn't always guarantee the tooltip will be vertical, it just determines the initial placement and fallback placements
*/
isVertical?: boolean;
- tooltipContentContainerClassName?: string;
+
+ /**
+ * If closing of the tooltip should be delayed,
+ * Useful if tooltips contains links that need to be clicked
+ */
+ delayClose?: boolean;
+
+ /**
+ * Additional class name to be added to the tooltip container
+ */
+ className?: string;
disabled?: boolean;
/**
@@ -79,7 +85,7 @@ interface Props {
children: ReactElement;
}
-function WithTooltip({
+export default function WithTooltip({
children,
title,
emoji,
@@ -87,7 +93,8 @@ function WithTooltip({
hint,
shortcut,
isVertical = true,
- tooltipContentContainerClassName,
+ delayClose = false,
+ className,
onOpen,
disabled,
}: Props) {
@@ -116,13 +123,13 @@ function WithTooltip({
return {initial, fallback};
}, [isVertical]);
- const {refs: {setReference, setFloating}, floatingStyles, context} = useFloating({
+ const {refs: {setReference, setFloating}, floatingStyles, context: floatingContext} = useFloating({
open: disabled ? false : open,
onOpenChange: handleChange,
whileElementsMounted: autoUpdate,
placement: placements.initial,
middleware: [
- offset(ARROW_OFFSET),
+ offset(OverlayArrow.OFFSET),
flip({
fallbackPlacements: placements.fallback,
}),
@@ -132,75 +139,61 @@ function WithTooltip({
],
});
- const hover = useHover(context, {
- restMs: TOOLTIP_REST_TIME_BEFORE_OPEN,
+ const {isMounted, styles: transitionStyles} = useTransitionStyles(floatingContext, TRANSITION_STYLE_PROPS);
+
+ const hover = useHover(floatingContext, {
+ restMs: OverlaysTimings.CURSOR_REST_TIME_BEFORE_OPEN,
delay: {
- open: Constants.OVERLAY_TIME_DELAY,
+ open: OverlaysTimings.CURSOR_MOUSEOVER_TO_OPEN,
+ close: delayClose ? OverlaysTimings.CURSOR_MOUSEOUT_TO_CLOSE_WITH_DELAY : OverlaysTimings.CURSOR_MOUSEOUT_TO_CLOSE,
},
});
- const focus = useFocus(context);
- const dismiss = useDismiss(context);
- const role = useRole(context, {role: 'tooltip'});
+ const focus = useFocus(floatingContext);
+ const dismiss = useDismiss(floatingContext);
+ const role = useRole(floatingContext, {role: 'tooltip'});
const {getReferenceProps, getFloatingProps} = useInteractions([hover, focus, dismiss, role]);
- const {isMounted, styles: transitionStyles} = useTransitionStyles(context, {
- duration: {
- open: TOOLTIP_APPEAR_DURATION,
- close: TOOLTIP_DISAPPEAR_DURATION,
- },
- initial: {
- opacity: 0,
- },
- common: {
- opacity: 1,
- },
- });
if (!isValidElement(children)) {
// eslint-disable-next-line no-console
console.error('Children must be a valid React element for WithTooltip');
}
- const mergedRefs = useMergeRefs([(children as any)?.ref, setReference]);
+ const mergedRefs = useMergeRefs([setReference, (children as any)?.ref]);
- const trigger = cloneElement(children, {
- ...getReferenceProps({
+ const trigger = cloneElement(
+ children,
+ getReferenceProps({
ref: mergedRefs,
...children.props,
}),
- });
+ );
return (
<>
{trigger}
+
{isMounted && (
-
+
)}
@@ -208,4 +201,10 @@ function WithTooltip({
);
}
-export default WithTooltip;
+const TRANSITION_STYLE_PROPS = {
+ duration: {
+ open: OverlaysTimings.FADE_IN_DURATION,
+ close: OverlaysTimings.FADE_OUT_DURATION,
+ },
+ initial: OverlayTransitionStyles.START,
+};
diff --git a/webapp/channels/src/components/with_tooltip/tooltip.scss b/webapp/channels/src/components/with_tooltip/tooltip.scss
deleted file mode 100644
index 5508d1f971..0000000000
--- a/webapp/channels/src/components/with_tooltip/tooltip.scss
+++ /dev/null
@@ -1,70 +0,0 @@
-.tooltipContainer {
- z-index: 1070;
-
- > .tooltipContentContainer {
- z-index: 1070;
- max-width: 220px;
- padding: 4px 8px;
- border-radius: 4px;
- background: rgba(0, 0, 0, 1);
- box-shadow: 0 6px 14px rgba(0, 0, 0, 0.12);
- line-height: 18px;
- pointer-events: none;
- text-align: center;
- word-break: break-word;
-
- > .tooltipContent {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- font-family: "Open Sans", sans-serif;
-
- > .tooltipContentTitleContainer {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- gap: 6px;
-
- &.isEmojiLarge {
- flex-direction: column;
- gap: 2px;
-
- > .tooltipContentEmoji {
- padding-top: 1px;
- }
- }
-
- > .tooltipContentEmoji {
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- > .tooltipContentTitle {
- color: #ffffff;
- font-size: 12px;
- font-weight: 600;
- line-height: 15px;
- }
- }
-
- > .tooltipContentShortcut {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- padding: 4px 0;
- gap: 2px;
- }
-
- > .tooltipContentHint {
- color: rgba(255, 255, 255, 0.64);
- font-size: 11px;
- font-weight: 600;
- line-height: 16px;
- }
- }
- }
-}
diff --git a/webapp/channels/src/components/with_tooltip/with_tooltip.scss b/webapp/channels/src/components/with_tooltip/with_tooltip.scss
new file mode 100644
index 0000000000..78b18ea455
--- /dev/null
+++ b/webapp/channels/src/components/with_tooltip/with_tooltip.scss
@@ -0,0 +1,68 @@
+@use 'utils/variables';
+
+.tooltipContainer {
+ z-index: variables.$z-index-popover;
+ max-width: 220px;
+ padding: 4px 8px;
+ border-radius: 4px;
+ background: rgba(0, 0, 0, 1);
+ box-shadow: 0 6px 14px rgba(0, 0, 0, 0.12);
+ line-height: 18px;
+ pointer-events: none;
+ text-align: center;
+ word-break: break-word;
+
+ > .tooltipContent {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-family: "Open Sans", sans-serif;
+
+ > .tooltipContentTitleContainer {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ gap: 6px;
+
+ &.isEmojiLarge {
+ flex-direction: column;
+ gap: 2px;
+
+ > .tooltipContentEmoji {
+ padding-top: 1px;
+ }
+ }
+
+ > .tooltipContentEmoji {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ > .tooltipContentTitle {
+ color: #ffffff;
+ font-size: 12px;
+ font-weight: 600;
+ line-height: 15px;
+ }
+ }
+
+ > .tooltipContentShortcut {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ padding: 4px 0;
+ gap: 2px;
+ }
+
+ > .tooltipContentHint {
+ color: rgba(255, 255, 255, 0.64);
+ font-size: 11px;
+ font-weight: 600;
+ line-height: 16px;
+ }
+ }
+}
diff --git a/webapp/channels/src/sass/utils/_variables.scss b/webapp/channels/src/sass/utils/_variables.scss
index 1a74907c7b..ac823ea3bc 100644
--- a/webapp/channels/src/sass/utils/_variables.scss
+++ b/webapp/channels/src/sass/utils/_variables.scss
@@ -36,3 +36,9 @@ $elevation-3: var(--elevation-3);
$elevation-4: var(--elevation-4);
$elevation-5: var(--elevation-5);
$elevation-6: var(--elevation-6);
+
+// Z-Index
+// Central place to manage z-index values for the app, providing a consistent way to manage stacking order.
+$z-index-popover: 1070;
+$z-index-user-group-popover: 1060;
+$z-index-global-header: 99;
diff --git a/webapp/channels/src/utils/constants.tsx b/webapp/channels/src/utils/constants.tsx
index b2da43fe4e..9e5c8f02b6 100644
--- a/webapp/channels/src/utils/constants.tsx
+++ b/webapp/channels/src/utils/constants.tsx
@@ -2240,6 +2240,9 @@ export const RootHtmlPortalId = 'root-portal';
export const OverlaysTimings = {
CURSOR_REST_TIME_BEFORE_OPEN: 400, // in ms
+ CURSOR_MOUSEOVER_TO_OPEN: 400, // in ms
+ CURSOR_MOUSEOUT_TO_CLOSE: 0,
+ CURSOR_MOUSEOUT_TO_CLOSE_WITH_DELAY: 200, // in ms
FADE_IN_DURATION: 250, // in ms
FADE_OUT_DURATION: 150, // in ms
};
@@ -2250,5 +2253,10 @@ export const OverlayTransitionStyles = {
},
};
-export default Constants;
+export const OverlayArrow = {
+ WIDTH: 10, // in px
+ HEIGHT: 6, // in px
+ OFFSET: 8, // in px
+};
+export default Constants;