--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/client/src/components/SlateEditor/CategoryButton.js Fri Nov 16 11:19:13 2018 +0100
@@ -0,0 +1,82 @@
+import React from 'react';
+import * as R from 'ramda';
+import { PortalWithState } from 'react-portal';
+import CategoriesTooltip from './CategoriesTooltip';
+import { defaultAnnotationsCategories } from '../../constants';
+
+/**
+ * Render a category toolbar button.
+ *
+ * @param {String} type
+ * @param {String} icon
+ * @return {Element}
+ */
+export default class CategoryButton extends React.Component {
+
+ constructor(props) {
+ super(props);
+
+ this.hoveringMenuRef = React.createRef();
+ }
+
+ get hoveringMenu() {
+ if(this.hoveringMenuRef) {
+ return this.hoveringMenuRef.current;
+ }
+ return null;
+ }
+
+ updateMenu = () => {
+
+ const hoveringMenu = this.hoveringMenu;
+
+ if (!hoveringMenu) return
+
+ const selection = window.getSelection()
+
+ if (selection.isCollapsed) {
+ return
+ }
+
+ const range = selection.getRangeAt(0)
+ const rect = range.getBoundingClientRect()
+
+ hoveringMenu.style.opacity = 1
+ hoveringMenu.style.top = `${rect.top + rect.height + window.scrollY + hoveringMenu.offsetHeight}px`
+ hoveringMenu.style.left = `${rect.left + window.scrollX - hoveringMenu.offsetWidth / 2 + rect.width / 2}px`
+ }
+
+ render = () => {
+ const isActive = this.props.isActive;
+ const onClickCategoryButton = this.props.onClickCategoryButton;
+ const onCategoryClick = this.props.onCategoryClick;
+ const annotationCategories = this.props.annotationCategories;
+
+ const markActivation = "button sticky-top" + ((!isActive)?" text-primary":" text-dark");
+
+ return (
+ <PortalWithState
+ // closeOnOutsideClick
+ closeOnEsc
+ onOpen={this.updateMenu}
+ >
+ {({ openPortal, closePortal, isOpen, portal }) => {
+ const onMouseDown = R.partial(onClickCategoryButton, [openPortal, closePortal, isOpen]);
+ const onCategoryClickHandler = R.partial(onCategoryClick, [closePortal,]);
+ return (
+ <React.Fragment>
+ <span className={markActivation} onMouseDown={onMouseDown} data-active={isActive}>
+ <span className="material-icons">label</span>
+ </span>
+ {portal(
+ <div className="hovering-menu" ref={this.hoveringMenuRef}>
+ <CategoriesTooltip categories={annotationCategories || defaultAnnotationsCategories} onCategoryClick={onCategoryClickHandler} />
+ </div>
+ )}
+ </React.Fragment>
+ )}
+ }
+ </PortalWithState>
+ )
+ }
+}