From c0d7652f25242b95a04c8b36cd14ed3da1ec12cc Mon Sep 17 00:00:00 2001 From: jocs Date: Fri, 5 Oct 2018 14:59:13 +0800 Subject: [PATCH] feat: add tooltip to editor --- src/muya/lib/config.js | 2 +- src/muya/lib/index.js | 4 ++ .../renderBlock/renderContainerBlock.js | 5 +- src/muya/lib/ui/tooltip/index.css | 28 +++++++++ src/muya/lib/ui/tooltip/index.js | 61 +++++++++++++++++++ 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 src/muya/lib/ui/tooltip/index.css create mode 100644 src/muya/lib/ui/tooltip/index.js diff --git a/src/muya/lib/config.js b/src/muya/lib/config.js index f9beddf5..dbd6cf8e 100644 --- a/src/muya/lib/config.js +++ b/src/muya/lib/config.js @@ -220,7 +220,7 @@ export const TABLE_TOOLS = [{ export const HTML_TOOLS = [{ label: 'delete', - title: 'Delete HTML block', + title: 'Delete HTML', icon: 'icon-del' }] diff --git a/src/muya/lib/index.js b/src/muya/lib/index.js index a4367612..99c998a8 100644 --- a/src/muya/lib/index.js +++ b/src/muya/lib/index.js @@ -12,6 +12,7 @@ import ExportMarkdown from './utils/exportMarkdown' import ExportHtml from './utils/exportHtml' import { checkEditImage } from './utils/checkEditImage' import TablePicker from './tablePicker' +import ToolTip from './ui/tooltip' import './assets/symbolIcon' // import symbol icons import './assets/symbolIcon/index.css' @@ -58,6 +59,9 @@ class Muya { const { container, contentState, eventCenter } = this contentState.stateRender.setContainer(container.children[0]) + // init tooltip + this.tooltip = new ToolTip(this) + eventCenter.subscribe('editEmoji', throttle(this.subscribeEditEmoji.bind(this), 200)) this.dispatchEditEmoji() eventCenter.subscribe('editLanguage', throttle(this.subscribeEditLanguage.bind(this))) diff --git a/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js b/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js index 10a850e0..e8c2bc61 100644 --- a/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js +++ b/src/muya/lib/parser/render/renderBlock/renderContainerBlock.js @@ -45,14 +45,13 @@ export default function renderContainerBlock (block, cursor, activeBlocks, match } } if (block.type === 'li' && block.label) { - const { label, title } = block + const { label, title: tooltip } = block const { align } = activeBlocks[0] if (align && block.label === align) { selector += '.active' } - Object.assign(data.dataset, { label }) - Object.assign(data.attrs, { title }) + Object.assign(data.dataset, { label, tooltip }) } if (block.type === 'li' && block.listItemType) { selector += `.${CLASS_OR_ID['AG_LIST_ITEM']}` diff --git a/src/muya/lib/ui/tooltip/index.css b/src/muya/lib/ui/tooltip/index.css new file mode 100644 index 00000000..9ca37cd2 --- /dev/null +++ b/src/muya/lib/ui/tooltip/index.css @@ -0,0 +1,28 @@ +.ag-tooltip { + transition: opacity .2s, transform .2s; + position: absolute; + font-size: 12px; + padding: 5px 7px; + border-radius: 5px; + background: rgb(50, 50, 50); + color: rgb(255, 255, 255); + z-index: 1000; + opacity: 0; +} + +.ag-tooltip.active { + opacity: 1; + transform: translateY(-5px); +} + +.ag-tooltip:after { + top: 0; + left: 50%; + content: ''; + background: inherit; + width: 8px; + height: 8px; + position: absolute; + display: block; + transform: rotate(45deg) translateX(-50%); +} \ No newline at end of file diff --git a/src/muya/lib/ui/tooltip/index.js b/src/muya/lib/ui/tooltip/index.js new file mode 100644 index 00000000..6a225f2a --- /dev/null +++ b/src/muya/lib/ui/tooltip/index.js @@ -0,0 +1,61 @@ +import './index.css' + +const position = (source, ele) => { + const rect = source.getBoundingClientRect() + const { top, right, height } = rect + + Object.assign(ele.style, { + top: `${top + height + 10}px`, + left: `${right - ele.offsetWidth / 2 - 3}px` + }) +} + +class Tooltip { + constructor (muya) { + this.muya = muya + this.cache = new WeakMap() + const { container, eventCenter } = this.muya + + eventCenter.attachDOMEvent(container, 'mouseover', this.mouseOver.bind(this)) + } + + mouseOver (event) { + const { target } = event + const toolTipTarget = target.closest('[data-tooltip]') + const { eventCenter } = this.muya + if (toolTipTarget && !this.cache.has(toolTipTarget)) { + const tooltip = toolTipTarget.getAttribute('data-tooltip') + const tooltipEle = document.createElement('div') + tooltipEle.textContent = tooltip + tooltipEle.classList.add('ag-tooltip') + document.body.appendChild(tooltipEle) + position(toolTipTarget, tooltipEle) + + this.cache.set(toolTipTarget, tooltipEle) + + setTimeout(() => { + tooltipEle.classList.add('active') + }) + + const timer = setInterval(() => { + if (!document.body.contains(toolTipTarget)) { + this.mouseLeave({ target: toolTipTarget }) + clearInterval(timer) + } + }, 300) + + eventCenter.attachDOMEvent(toolTipTarget, 'mouseleave', this.mouseLeave.bind(this)) + } + } + + mouseLeave (event) { + const { target } = event + if (this.cache.has(target)) { + const tooltipEle = this.cache.get(target) + tooltipEle.remove() + this.cache.delete(target) + } + } +} + +export default Tooltip