diff --git a/package-lock.json b/package-lock.json index b43c4bbee..4797203cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,6 +42,7 @@ "lodash.kebabcase": "^4.1.1", "moment": "^2.29.4", "normalizr": "^3.6.2", + "rc-tooltip": "^5.3.1", "react": "^17.0.2", "react-collapsible": "^2.10.0", "react-dom": "^17.0.2", @@ -12368,8 +12369,9 @@ } }, "node_modules/classnames": { - "version": "2.3.1", - "license": "MIT" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "node_modules/clean-css": { "version": "4.2.4", @@ -14240,6 +14242,11 @@ "version": "0.5.14", "license": "MIT" }, + "node_modules/dom-align": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==" + }, "node_modules/dom-converter": { "version": "0.2.0", "license": "MIT", @@ -26720,6 +26727,82 @@ "rc": "cli.js" } }, + "node_modules/rc-align": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.15.tgz", + "integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "rc-util": "^5.26.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-motion": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.6.3.tgz", + "integrity": "sha512-xFLkes3/7VL/J+ah9jJruEW/Akbx5F6jVa2wG5o/ApGKQKSOd5FR3rseHLL9+xtJg4PmCwo6/1tqhDO/T+jFHA==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.21.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tooltip": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.3.1.tgz", + "integrity": "sha512-e6H0dMD38EPaSPD2XC8dRfct27VvT2TkPdoBSuNl3RRZ5tspiY/c5xYEmGC0IrABvMBgque4Mr2SMZuliCvoiQ==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.3.1", + "rc-trigger": "^5.3.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-trigger": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.3.4.tgz", + "integrity": "sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.19.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.27.2.tgz", + "integrity": "sha512-8XHRbeJOWlTR2Hk1K2xLaPOf7lZu+3taskAGuqOPccA676vB3ygrz3ZgdrA3wml40CzR9RlIEHDWwI7FZT3wBQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^16.12.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", "dev": true, @@ -28130,6 +28213,11 @@ "version": "4.1.5", "license": "MIT" }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.18.1", "license": "MIT", @@ -41662,7 +41750,9 @@ } }, "classnames": { - "version": "2.3.1" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", + "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" }, "clean-css": { "version": "4.2.4", @@ -42886,6 +42976,11 @@ "dom-accessibility-api": { "version": "0.5.14" }, + "dom-align": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==" + }, "dom-converter": { "version": "0.2.0", "requires": { @@ -50967,6 +51062,59 @@ } } }, + "rc-align": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.15.tgz", + "integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "dom-align": "^1.7.0", + "rc-util": "^5.26.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-motion": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.6.3.tgz", + "integrity": "sha512-xFLkes3/7VL/J+ah9jJruEW/Akbx5F6jVa2wG5o/ApGKQKSOd5FR3rseHLL9+xtJg4PmCwo6/1tqhDO/T+jFHA==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.21.0" + } + }, + "rc-tooltip": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.3.1.tgz", + "integrity": "sha512-e6H0dMD38EPaSPD2XC8dRfct27VvT2TkPdoBSuNl3RRZ5tspiY/c5xYEmGC0IrABvMBgque4Mr2SMZuliCvoiQ==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "^2.3.1", + "rc-trigger": "^5.3.1" + } + }, + "rc-trigger": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.3.4.tgz", + "integrity": "sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==", + "requires": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.6", + "rc-align": "^4.0.0", + "rc-motion": "^2.0.0", + "rc-util": "^5.19.2" + } + }, + "rc-util": { + "version": "5.27.2", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.27.2.tgz", + "integrity": "sha512-8XHRbeJOWlTR2Hk1K2xLaPOf7lZu+3taskAGuqOPccA676vB3ygrz3ZgdrA3wml40CzR9RlIEHDWwI7FZT3wBQ==", + "requires": { + "@babel/runtime": "^7.18.3", + "react-is": "^16.12.0" + } + }, "react": { "version": "17.0.2", "requires": { @@ -51902,6 +52050,11 @@ "reselect": { "version": "4.1.5" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.18.1", "requires": { diff --git a/package.json b/package.json index e23fc3d7e..7c7628fd6 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "lodash.kebabcase": "^4.1.1", "moment": "^2.29.4", "normalizr": "^3.6.2", + "rc-tooltip": "^5.3.1", "react": "^17.0.2", "react-collapsible": "^2.10.0", "react-dom": "^17.0.2", diff --git a/src/_variables.scss b/src/_variables.scss index 24fabf676..2a99f04d4 100644 --- a/src/_variables.scss +++ b/src/_variables.scss @@ -1,3 +1,4 @@ $font-size-small: 12px; +$font-size-medium: 14px; $font-size-large: 16px; $font-size-xl: 20px; diff --git a/src/components/tooltip/index.test.tsx b/src/components/tooltip/index.test.tsx new file mode 100644 index 000000000..b28b4940a --- /dev/null +++ b/src/components/tooltip/index.test.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import Tooltip, { Properties } from './'; +import { default as ReactTooltip } from 'rc-tooltip'; + +const OVERLAY_TEST = 'overlay-test'; +const CHILDREN_TEST = 'children'; + +describe('Tooltip', () => { + const subject = (props: Partial) => { + const allProps: Properties = { + overlay: OVERLAY_TEST, + ...props, + }; + + return shallow( + + <>{CHILDREN_TEST} + + ); + }; + + it('render', function () { + const wrapper = subject({}); + + expect(wrapper.find(ReactTooltip).exists()).toBe(true); + }); + + it('renders all props', function () { + const wrapper = subject({}); + + expect(wrapper.find(ReactTooltip).props()).toEqual({ + children: children, + destroyTooltipOnHide: true, + mouseEnterDelay: 0.1, + mouseLeaveDelay: 0.2, + overlay: 'overlay-test', + overlayClassName: 'tooltip', + showArrow: false, + }); + }); +}); diff --git a/src/components/tooltip/index.tsx b/src/components/tooltip/index.tsx new file mode 100644 index 000000000..41fddd534 --- /dev/null +++ b/src/components/tooltip/index.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import classNames from 'classnames'; +import { default as ReactTooltip } from 'rc-tooltip'; +import { TooltipProps } from 'rc-tooltip/lib/Tooltip'; +import './styles.scss'; + +export interface Properties extends TooltipProps { + className?: string; +} + +export default class Tooltip extends React.Component { + render() { + return ( + + {this.props.children} + + ); + } +} diff --git a/src/components/tooltip/styles.scss b/src/components/tooltip/styles.scss new file mode 100644 index 000000000..30e7dd15a --- /dev/null +++ b/src/components/tooltip/styles.scss @@ -0,0 +1,21 @@ +@use '../../shared-components/theme-engine/theme' as theme; +@import 'rc-tooltip/assets/bootstrap.css'; +@import '../../variables'; + +.tooltip { + .rc-tooltip-inner { + color: #ccc; + border-radius: 4px; + box-shadow: 2px 4px 5px 0 rgb(0 0 0 / 50%); + background: theme.$background-color-primary; + padding: 5px; + min-height: unset; + font-size: $font-size-medium; + font-weight: 400; + text-align: center; + } + + &.rc-tooltip-placement-left { + padding: 0; + } +} diff --git a/src/platform-apps/channels/direct-message-members/index.test.tsx b/src/platform-apps/channels/direct-message-members/index.test.tsx index 8552f1e2c..a5fd9eae8 100644 --- a/src/platform-apps/channels/direct-message-members/index.test.tsx +++ b/src/platform-apps/channels/direct-message-members/index.test.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { Container as DirectMessageChat, Properties } from './'; import { DIRECT_MESSAGES_TEST } from '../../../store/direct-messages/saga.test'; +import Tooltip from '../../../components/tooltip'; describe('direct-message-members', () => { const subject = (props: Partial) => { @@ -36,7 +37,7 @@ describe('direct-message-members', () => { expect(displayChatNames).toStrictEqual([ 'Charles Diya, Eric', - 'Eric', + 'daily chat', ]); }); @@ -76,4 +77,53 @@ describe('direct-message-members', () => { expect(wrapper.find('.direct-message-members__user-unread-count').text()).toEqual(unreadCount.toString()); }); + + describe('tooltip', () => { + let wrapper; + + beforeEach(() => { + wrapper = subject({}); + }); + + afterEach(() => { + wrapper = null; + }); + + const getFirstTooltip = () => { + return wrapper.find(Tooltip).first(); + }; + + it('renders', function () { + expect(getFirstTooltip().exists()).toBe(true); + }); + + it('renders placement to left', function () { + const placement = 'left'; + + expect(getFirstTooltip().prop('placement')).toEqual(placement); + }); + + it('renders class name', function () { + const className = 'direct-message-members__user-tooltip'; + + expect(getFirstTooltip().prop('className')).toEqual(className); + }); + + it('renders align prop', function () { + const align = { + offset: [ + 10, + 0, + ], + }; + + expect(getFirstTooltip().prop('align')).toEqual(align); + }); + + it('renders content', function () { + const content = 'Charles Diya, Eric'; + + expect(getFirstTooltip().prop('overlay')).toEqual(content); + }); + }); }); diff --git a/src/platform-apps/channels/direct-message-members/index.tsx b/src/platform-apps/channels/direct-message-members/index.tsx index d3e14320a..81d8251d6 100644 --- a/src/platform-apps/channels/direct-message-members/index.tsx +++ b/src/platform-apps/channels/direct-message-members/index.tsx @@ -4,6 +4,7 @@ import { RootState } from '../../../store'; import { DirectMessage } from '../../../store/direct-messages/types'; import { User } from '../../../store/channels'; import { fetch as fetchDirectMessages, setActiveDirectMessageId } from '../../../store/direct-messages'; +import Tooltip from '../../../components/tooltip'; import './styles.scss'; @@ -52,19 +53,38 @@ export class Container extends React.Component { .trim(); } + tooltipContent(directMessage: DirectMessage): string { + return this.renderMemberName(directMessage.otherMembers); + } + renderMember = (directMessage: DirectMessage): JSX.Element => { return ( -
-
-
{this.renderMemberName(directMessage.otherMembers)}
- {directMessage.unreadCount !== 0 && ( -
{directMessage.unreadCount}
- )} -
+
+
+
+ {directMessage.name || this.renderMemberName(directMessage.otherMembers)} +
+ {directMessage.unreadCount !== 0 && ( +
{directMessage.unreadCount}
+ )} +
+ ); }; diff --git a/src/platform-apps/channels/direct-message-members/styles.scss b/src/platform-apps/channels/direct-message-members/styles.scss index 38ba6f450..67b699424 100644 --- a/src/platform-apps/channels/direct-message-members/styles.scss +++ b/src/platform-apps/channels/direct-message-members/styles.scss @@ -29,6 +29,10 @@ } } + &-tooltip { + max-width: 200px; + } + &-unread-count { background-color: theme.$accent-color; color: theme.$font-color-primary; diff --git a/src/store/direct-messages/direct-messages-fixture.json b/src/store/direct-messages/direct-messages-fixture.json index 21de492b3..ee46416b3 100644 --- a/src/store/direct-messages/direct-messages-fixture.json +++ b/src/store/direct-messages/direct-messages-fixture.json @@ -48,6 +48,7 @@ "isVideoEnabled": false }, { + "name": "daily chat", "id": "292444273_1588d50c49b8f44110050328fbb8a01eb2105044", "url": "sendbird_group_channel_292444273_1588d50c49b8f44110050328fbb8a01eb2105044", "icon": "https://static.sendbird.com/sample/cover/cover_13.jpg",