[NEW] Tooltips (#18399)

Co-authored-by: Gabriel Henriques <gabriel.henriques@rocket.chat>
pull/17973/head^2
Guilherme Gazzo 6 years ago committed by GitHub
parent 9b49a44d1e
commit 0afa7f451e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/apps/client/gameCenter/gameCenter.html
  2. 2
      app/livechat/client/views/app/analytics/livechatAnalytics.html
  3. 2
      app/message-attachments/client/messageAttachment.html
  4. 88
      app/theme/client/imports/components/tooltip.css
  5. 1
      app/theme/client/main.css
  6. 2
      app/threads/client/components/ThreadComponent.js
  7. 2
      app/tokenpass/client/tokenpassChannelSettings.html
  8. 8
      app/ui-flextab/client/flexTabBar.html
  9. 22
      app/ui-message/client/message.html
  10. 4
      app/ui-message/client/messageBox/messageBox.html
  11. 6
      app/ui-message/client/messageThread.html
  12. 2
      app/ui-sidenav/client/sidebarHeader.html
  13. 2
      app/ui-utils/client/lib/modal.html
  14. 8
      app/ui/client/components/header/headerRoom.html
  15. 1
      app/ui/client/index.js
  16. 55
      app/ui/client/lib/Tooltip.js
  17. 16
      app/ui/client/lib/TooltipComponent.js
  18. 2
      app/ui/client/views/app/createChannel.html
  19. 4
      app/webdav/client/webdavFilePicker.html
  20. 2
      client/account/preferences/PreferencesSoundSection.js
  21. 4
      client/components/basic/VerticalBar.js

@ -46,7 +46,7 @@
<td>
<div class="rc-table-wrapper">
<div class="rc-table-info">
<button class="rc-tooltip game-center__invite-players js-invite" aria-label="Invite Friends">
<button class="game-center__invite-players js-invite" title="Invite Friends">
{{> icon block="game-center__invite-players-icon" icon="plus"}}
</button>
</div>

@ -38,7 +38,7 @@
<i class="icon-left-circled"></i>
</button>
{{/if}}
<button class="rc-tooltip rc-tooltip--down js-button lc-date-picker-btn">
<button class="js-button lc-date-picker-btn">
{{#with daterange}}
<span class="lc-datarange-from">{{from}}</span>
<span class="fade">{{_ "to" }}</span>

@ -57,7 +57,7 @@
{{#if title_link}}
<a href="{{getURL title_link}}" target="_blank" rel="noopener noreferrer">{{title}}</a>
{{#if title_link_download}}
<a class="attachment-download-icon rc-tooltip" aria-label="{{_ 'Download'}}" href="{{getURL title_link}}?download" target="_blank" download="{{title}}" rel="noopener noreferrer">{{> icon icon="download"}}</a>
<a class="attachment-download-icon" title="{{_ 'Download'}}" href="{{getURL title_link}}?download" target="_blank" download="{{title}}" rel="noopener noreferrer">{{> icon icon="download"}}</a>
{{/if}}
{{else}}
{{title}}

@ -1,88 +0,0 @@
.rc-tooltip {
position: relative;
--translation-x: -50%;
&::before,
&::after {
position: absolute;
z-index: 1000;
bottom: 100%;
left: 50%;
transition: all 0.18s ease-out 0.18s;
transform: translate(var(--translation-x), 10px);
transform-origin: top;
pointer-events: none;
opacity: 0;
}
&::after {
bottom: 100%;
margin: 11px 0;
padding: 0.5em 1em;
content: attr(aria-label) attr(label);
white-space: nowrap;
color: var(--tooltip-text-color);
border-radius: var(--tooltip-radius);
background: var(--tooltip-background);
font-size: var(--tooltip-text-size);
}
&::before {
width: 0;
height: 0;
margin-bottom: 6px;
content: "";
border-width: 6px 6px 0;
border-style: solid;
border-color: var(--tooltip-background) transparent transparent transparent;
}
&--down {
&::after {
top: 100%;
bottom: initial;
}
&::before {
top: 100%;
bottom: initial;
border-width: 6px;
border-color: transparent transparent var(--tooltip-background) transparent;
}
}
&--start,
.rtl &--end {
--translation-x: -10%;
}
&--end,
.rtl &--start {
--translation-x: -90%;
}
}
@media (min-width: 501px) {
.rc-tooltip[aria-label] {
&:hover::before,
&:hover::after,
&:focus::before,
&:focus::after {
transform: translate(var(--translation-x), 0);
pointer-events: auto;
opacity: 1;
}
}
}

@ -40,7 +40,6 @@
@import 'imports/components/alerts.css';
@import 'imports/components/popout.css';
@import 'imports/components/modal.css';
@import 'imports/components/tooltip.css';
@import 'imports/components/slider.css';
@import 'imports/components/chip.css';
@import 'imports/components/messages.css';

@ -91,7 +91,7 @@ export default function ThreadComponent({ mid, rid, jump, room, ...props }) {
<VerticalBar.Text dangerouslySetInnerHTML={{ __html: headerTitle }} />
<VerticalBar.Action aria-label={expandLabel} onClick={handleExpandButton} name={expandIcon}/>
<VerticalBar.Action aria-label={actionLabel} onClick={handleFollowButton} name={button}/>
<VerticalBar.Close aria-label={t('Close')} onClick={handleClose}/>
<VerticalBar.Close onClick={handleClose}/>
</VerticalBar.Header>
<VerticalBar.Content paddingInline={0} flexShrink={1} flexGrow={1} ref={ref}/>
</VerticalBar>

@ -21,7 +21,7 @@
{{#if list}}
<ul class="chip-container">
{{#each list}}
<li class="js-remove rc-tooltip" aria-label="balance: {{balance}}" title="{{token}} {{balance}}">{{#if editing}}<i class="icon-cancel-circled"></i>{{/if}}{{token}}</li>
<li class="js-remove" title="balance: {{balance}}" aria-label="{{token}} {{balance}}">{{#if editing}}<i class="icon-cancel-circled"></i>{{/if}}{{token}}</li>
{{/each}}
</ul>
{{/if}}

@ -35,7 +35,7 @@
<div class="rc-room-actions iframe-toolbar">
{{#each .}}
<div class="rc-room-actions__action tab-button {{active}} {{visible}} {{class}} js-iframe-action" data-id="{{id}}">
<button class="rc-tooltip rc-tooltip--down rc-tooltip--end rc-room-actions__button" aria-label="{{title}}">
<button class="rc-room-actions__button" title="{{title}}">
{{> icon block="tab-button-icon" icon=icon }}
</button>
</div>
@ -48,14 +48,14 @@
{{#with badge}}
<span class="rc-badge {{class}}">{{body}}</span>
{{/with}}
<button class="rc-tooltip rc-tooltip--down rc-tooltip--end rc-room-actions__button" aria-label="{{title}}">
<button class="rc-room-actions__button" title="{{title}}">
{{> icon block="tab-button-icon" icon=icon }}
</button>
</div>
{{/each}}
{{# with moreButtons}}
<div class="rc-room-actions__action {{opened}}">
<button class="rc-tooltip rc-tooltip--down rc-tooltip--end rc-room-actions__button js-more" aria-label="{{_ 'More'}}">
<button class="rc-room-actions__button js-more" title="{{_ 'More'}}">
{{> icon block="tab-button-icon" icon="menu" }}
</button>
</div>
@ -74,7 +74,7 @@
<!-- <div class=""> -->
{{#each buttons}}
<div class="rc-room-actions__more-action tab-button {{active}} {{visible}} {{class}} js-action" title="{{title}}">
<button class="rc-tooltip rc-room-actions__button">
<button class="rc-room-actions__button">
{{> icon block="tab-button-icon" icon=icon }}
</button>
<span class="rc-room-actions__description">{{title}}</span>

@ -43,7 +43,7 @@
{{getName}}{{#if showUsername}} <span class="message-alias border-component-color color-info-font-color">@{{msg.u.username}}</span>{{/if}}
</button>
{{#if getStatus}}
<button class="message-custom-status rc-tooltip rc-tooltip--up rc-tooltip--start" aria-label="{{getStatus}}">💬</button>
<button class="message-custom-status" title="{{getStatus}}">💬</button>
{{/if}}
<span class="info border-component-color color-info-font-color"></span>
{{# if showRoles }}
@ -57,28 +57,28 @@
<time class="time" title='{{date}} {{time}}' datetime='{{date}} {{time}}'>{{time}}</time>
{{#if showTranslated}}
<span class="translated">
<i class="icon-language {{#if msg.autoTranslateFetching}}loading{{/if}}" aria-label="{{_ "Translated"}}"></i>
<i class="icon-language {{#if msg.autoTranslateFetching}}loading{{/if}}" title="{{_ "Translated"}}"></i>
<span class="translation-provider">{{ translationProvider }}</span>
</span>
{{/if}}
{{#if msg.sentByEmail}}
<span class="sent-by-email">
<i class="icon-mail" title='{{_ "Message_sent_by_email"}}' aria-label='{{_ "Message_sent_by_email"}}'></i>
<i class="icon-mail" title='{{_ "Message_sent_by_email"}}'></i>
</span>
{{/if}}
{{#if edited}}
<span class="edited" title='{{_ "edited"}} {{_ "at"}} {{editTime}} {{_ "by"}} {{editedBy}}'>
<i class="icon-pencil{{#if $neq editedBy msg.u.username}} error-color{{/if}}" aria-label="{{_ "Edited"}}"></i>
<i class="icon-pencil{{#if $neq editedBy msg.u.username}} error-color{{/if}}" title="{{_ "Edited"}}"></i>
</span>
{{/if}}
{{#if msg.pinned}}
<span aria-label="{{_ "Message_has_been_pinned"}}" class="pinned rc-tooltip rc-tooltip--up rc-tooltip--start"><i class="icon-pin"></i></span>
<span title="{{_ "Message_has_been_pinned"}}" class="pinned"><i class="icon-pin"></i></span>
{{/if}}
{{#if showStar}}
<span aria-label="{{_ "Message_has_been_starred"}}" class="starred rc-tooltip rc-tooltip--up rc-tooltip--start"><i class="icon-star"></i></span>
<span title="{{_ "Message_has_been_starred"}}" class="starred"><i class="icon-star"></i></span>
{{/if}}
{{#if msg.alert}}
<div aria-label="{{_ msg.alert }}" class="rc-tooltip message-unread"></div>
<div title="{{_ msg.alert }}" class="message-unread"></div>
{{/if}}
{{#if msg.private}}
<span class="private">{{_ "Only_you_can_see_this_message"}}</span>
@ -135,7 +135,7 @@
{{/if}}
<span class="discussion-reply-lm">{{ formatDateAndTime msg.dlm }}</span>
{{# if unread }}
<div aria-label="{{_ 'Unread' }}" class="rc-tooltip message-unread"></div>
<div title="{{_ 'Unread' }}" class="message-unread"></div>
{{/if}}
</div>
{{/if}}
@ -148,14 +148,14 @@
<span class='reply-counter'>{{_ i18nReplyCounter counter=msg.tcount }}</span>
<span class="discussion-reply-lm">{{ formatDateAndTime msg.tlm}}</span>
{{# if unread }}
<div aria-label="{{_ 'Unread' }}" class="rc-tooltip message-unread {{class}}"></div>
<div title="{{_ 'Unread' }}" class="message-unread {{class}}"></div>
{{/if}}
{{# if following }}
<div role="button" class="rc-tooltip js-unfollow-thread" aria-label="{{_ "Following"}}">
<div role="button" class="js-unfollow-thread" title="{{_ "Following"}}">
{{> icon icon="bell" block="thread-icons"}}
</div>
{{else}}
<div role="button" class="rc-tooltip js-follow-thread" aria-label="{{_ "Not_following"}}">
<div role="button" class="js-follow-thread" title="{{_ "Not_following"}}">
{{> icon icon="bell-off" block="thread-icons"}}
</div>
{{/if}}

@ -68,11 +68,11 @@
<div class="rc-message-box__toolbar-formatting">
{{#each formattingButton in formattingButtons}}
{{#if formattingButton.icon}}
<button class="rc-message-box__toolbar-formatting-item rc-tooltip js-format" data-id="{{formattingButton.label}}" aria-label="{{_ formattingButton.label}}">
<button class="rc-message-box__toolbar-formatting-item js-format" data-id="{{formattingButton.label}}" title="{{_ formattingButton.label}}">
{{> icon block="rc-message-box__toolbar-formatting-icon" icon=formattingButton.icon }}
</button>
{{else}}
<span class="rc-message-box__toolbar-formatting-item rc-tooltip" aria-label="{{_ formattingButton.label}}">
<span class="rc-message-box__toolbar-formatting-item" title="{{_ formattingButton.label}}">
<a href="{{formattingButton.link}}" target="_blank" rel="noopener noreferrer" class="rc-message-box__toolbar-formatting-link">{{formattingButton.text}}</a>
</span>
{{/if}}

@ -1,12 +1,12 @@
<template name="messageThread">
<q role="button" aria-label="{{_ " Open_thread "}}" class="thread-quote js-open-thread">
<q role="button" title="{{_ " Open_thread "}}" class="thread-quote js-open-thread">
{{> icon icon="thread" block="thread-icons"}} <div class="thread-quote__message "><span class="message-body--unstyled">{{{parentMessage}}}</span></div>
{{# if following }}
<div role="button" class="rc-tooltip js-unfollow-thread" aria-label="{{_ "Following"}}">
<div role="button" class="js-unfollow-thread" title="{{_ "Following"}}">
{{> icon icon="bell" block="thread-icons"}}
</div>
{{else}}
<div role="button" class="rc-tooltip js-follow-thread" aria-label="{{_ "Not_following"}}">
<div role="button" class="js-follow-thread" title="{{_ "Not_following"}}">
{{> icon icon="bell-off" block="thread-icons"}}
</div>
{{/if}}

@ -7,7 +7,7 @@
</div>
<div class="sidebar__toolbar">
{{#each toolbarButtons}}
<button class="sidebar__toolbar-button rc-tooltip rc-tooltip--down js-button" aria-label="{{name}}" aria-haspopup="{{hasPopup}}">
<button class="sidebar__toolbar-button js-button" title="{{name}}" aria-haspopup="{{hasPopup}}">
{{> icon block="sidebar__toolbar-button-icon" icon=icon }}
</button>
{{/each}}

@ -16,7 +16,7 @@
{{title}}
{{/if}}
</h1>
<button aria-label="{{_ "Close"}}" class="rc-tooltip contextual-bar__close js-close">
<button title="{{_ "Close"}}" class="contextual-bar__close js-close">
{{> icon classes="rc-modal__close" icon="plus"}}
</button>
</header>

@ -7,14 +7,14 @@
</div>
{{#if isDiscussion}}
<div class="rc-header__block rc-header__block--action js-open-parent-channel rc-tooltip rc-tooltip--down rc-tooltip--start" aria-label={{_ "Back_to_room"}}>
<div class="rc-header__block rc-header__block--action js-open-parent-channel" title={{_ "Back_to_room"}}>
<span class="rc-header__first-icon">{{> icon block="rc-header__icon rc-header__icon" icon="back"}}</span>
</div>
{{/if}}
{{#if isToggleFavoriteButtonVisible}}
<div class="rc-header__block rc-header__favorite rc-header__block--action">
<button aria-label="{{toggleFavoriteButtonIconLabel}}" type="button" class="rc-header__toggle-favorite {{#if isToggleFavoriteButtonChecked}}rc-header__toggle-favorite--checked{{/if}} rc-header__first-icon rc-tooltip rc-tooltip--down rc-tooltip--start js-favorite">
<button title="{{toggleFavoriteButtonIconLabel}}" type="button" class="rc-header__toggle-favorite {{#if isToggleFavoriteButtonChecked}}rc-header__toggle-favorite--checked{{/if}} rc-header__first-icon js-favorite">
{{> icon block="rc-header__icon" icon=toggleFavoriteButtonIcon}}
</button>
</div>
@ -55,7 +55,7 @@
<span class="sentiment">{{sentimentSmile}}</span>
{{/if}}
{{#if isTranslated}}
<i class="icon-language" aria-label="{{_ "Translated"}}"></i>
<i class="icon-language" title="{{_ "Translated"}}"></i>
{{/if}}
</div>
@ -65,7 +65,7 @@
{{#if encryptionState}}
<div class="rc-header__block rc-header__block-action rc-header__encryption">
<div class="rc-room-actions">
<button aria-label="{{_ 'E2E_Enabled'}}" class="rc-tooltip rc-tooltip--down rc-room-actions__action tab-button rc-header__toggle-encryption js-toggle-encryption {{encryptionState}}">{{> icon icon="key"}}</button>
<button title="{{_ 'E2E_Enabled'}}" class="rc-room-actions__action tab-button rc-header__toggle-encryption js-toggle-encryption {{encryptionState}}">{{> icon icon="key"}}</button>
</div>
</div>
{{/if}}

@ -57,6 +57,7 @@ import './components/header/headerRoom';
import './components/contextualBar.html';
import './components/contextualBar';
import './components/tooltip';
import './lib/Tooltip';
export { ChatMessages } from './lib/chatMessages';
export { fileUpload } from './lib/fileUpload';

@ -0,0 +1,55 @@
import { Tracker } from 'meteor/tracker';
import { createEphemeralPortal } from '../../../../client/reactAdapters';
const Dep = new Tracker.Dependency();
let state;
let dom;
let unregister;
const createAchor = () => {
const div = document.createElement('div');
div.id = 'react-tooltip';
document.body.appendChild(div);
return div;
};
const props = () => {
Dep.depend();
return state;
};
export const closeTooltip = () => {
if (!dom) {
return;
}
unregister = unregister && unregister();
};
export const openToolTip = async (title, anchor) => {
dom = dom || createAchor();
state = {
title,
anchor,
};
Dep.changed();
unregister = unregister || await createEphemeralPortal(() => import('./TooltipComponent'), props, dom);
};
document.body.addEventListener('mouseover', (() => {
let timeout;
return (e) => {
timeout = timeout && clearTimeout(timeout);
timeout = setTimeout(() => {
const element = e.target.title || e.dataset?.title ? e.target : e.target.closest('[title], [data-title]');
if (element) {
element.dataset.title = element.dataset.title || element.title;
element.removeAttribute('title');
openToolTip(element.dataset.title, element);
}
}, 1000);
closeTooltip();
};
})());

@ -0,0 +1,16 @@
import React, { useRef } from 'react';
import { Tooltip, PositionAnimated, AnimatedVisibility } from '@rocket.chat/fuselage';
export const TooltipComponent = ({ title, anchor }) => {
const ref = useRef(anchor);
return <PositionAnimated
anchor={ref}
placement='top-middle'
margin={8}
visible={AnimatedVisibility.UNHIDING}
children={title}
><Tooltip>{title}</Tooltip></PositionAnimated>;
};
export default TooltipComponent;

@ -211,7 +211,7 @@
<template name='tagToken'>
<span class="rc-tags__tag">
<span class="rc-tags__tag-text rc-tooltip" aria-label="balance: {{balance}}">{{token}}</span>
<span class="rc-tags__tag-text" title="balance: {{balance}}">{{token}}</span>
{{> icon block="rc-tags__tag-icon" icon="cross"}}
</span>
</template>

@ -19,7 +19,7 @@
<div class="webdav-header-spacer"></div>
<div class="webdav-search">
<form class="webdav__search-form js-search-form" role="form">
<span class="webdav-search-icon js-webdav-search-icon rc-tooltip rc-tooltip--down" aria-label="Search">
<span class="webdav-search-icon js-webdav-search-icon" title="Search">
<i class="icon-search"></i>
</span>
<input
@ -30,7 +30,7 @@
autocomplete="off">
</form>
</div>
<div class="list-grid-mode js-list-grid-mode rc-tooltip rc-tooltip--down" aria-label="{{#if listMode}}Grid{{else}}List{{/if}} View">
<div class="list-grid-mode js-list-grid-mode" title="{{#if listMode}}Grid{{else}}List{{/if}} View">
<i class="icon-{{#if listMode}}th{{else}}list{{/if}}"></i>
</div>
</div>

@ -65,7 +65,7 @@ const PreferencesSoundSection = ({ onChange, ...props }) => {
</Field.Label>
<Field.Row >
<Box is='input' flexGrow={1} type='range' value={notificationsSoundVolume} onChange={onChangeNotificationsSoundVolume} min='0' max='100'/>
<Tooltip arrowPosition='left' mis='x8'>{notificationsSoundVolume}</Tooltip>
<Tooltip placement='right-middle' mis='x8'>{notificationsSoundVolume}</Tooltip>
</Field.Row>
</Field>, [notificationsSoundVolume, onChangeNotificationsSoundVolume, t])}
</FieldGroup>

@ -2,6 +2,7 @@ import { Box, Button, Icon, Margins, Skeleton } from '@rocket.chat/fuselage';
import { useDebouncedValue, useMediaQuery } from '@rocket.chat/fuselage-hooks';
import React from 'react';
import { useTranslation } from '../../contexts/TranslationContext';
import Page from './Page';
function VerticalBar({ children, ...props }) {
@ -47,7 +48,8 @@ function VerticalBarIcon(props) {
}
function VerticalBarClose(props) {
return <VerticalBarAction {...props} name='cross' />;
const t = useTranslation();
return <VerticalBarAction {...props} title={t('Close')} name='cross' />;
}
const VerticalBarContent = React.forwardRef(function VerticalBarContent(props, ref) {

Loading…
Cancel
Save