From b04aeaca5b94e1d50a40c96ce4299ecde5b0b5f4 Mon Sep 17 00:00:00 2001
From: Giannis Kopanas <jkopanas@gmail.com>
Date: Wed, 11 Dec 2019 12:13:13 +0200
Subject: [PATCH] feat(menu): style menu, build tools

---
 editors/editoria/src/EditorConfig.js          |   3 +-
 editors/editoria/src/config/menu.js           |   7 +-
 wax-prosemirror-components/index.js           |   4 +-
 .../src/components/ImageUpload.js             |   2 +-
 wax-prosemirror-components/src/helpers.js     |  14 -
 .../src/mainMenuBar/MainMenuBar.js            |  46 ---
 .../src/mainMenuBar/MainMenuBarItems.js       | 263 ------------------
 .../src/sideMenuBar/SideMenuBar.js            |  45 ---
 .../src/sideMenuBar/SideMenuCommands.js       |  10 -
 .../src/sideMenuBar/SideMenuItems.js          | 145 ----------
 wax-prosemirror-core/src/Application.js       |  11 +
 wax-prosemirror-core/src/Config/Config.js     |   8 +-
 .../src/Config/defaultConfig.js               |  19 +-
 wax-prosemirror-core/src/PmPlugins.js         |  16 ++
 wax-prosemirror-core/src/Wax.js               |  25 +-
 wax-prosemirror-core/src/WaxView.js           |  54 ----
 wax-prosemirror-core/src/services/Service.js  |   2 +-
 .../src/layouts/EditoriaLayout.js             |  58 +++-
 wax-prosemirror-plugins/index.js              |   5 +
 wax-prosemirror-plugins/jsconfig.json         |   5 +
 .../src/AnnotationService/Annotation.js       |  47 ++++
 .../AnnotationService/AnnotationService.js    |  14 +
 .../src/AnnotationService/tools/Blockquote.js |  29 ++
 .../src/AnnotationService/tools/BulletList.js |  29 ++
 .../src/AnnotationService/tools/Code.js       |  23 ++
 .../src/AnnotationService/tools/Em.js         |  23 ++
 .../src/AnnotationService/tools/JoinUp.js     |  22 ++
 .../src/AnnotationService/tools/Lift.js       |  18 ++
 .../src/AnnotationService/tools/Link.js       |  35 +++
 .../AnnotationService/tools/OrderedList.js    |  29 ++
 .../src/AnnotationService/tools/SmallCaps.js  |  23 ++
 .../AnnotationService/tools/StrikeThrough.js  |  23 ++
 .../src/AnnotationService/tools/Strong.js     |  23 ++
 .../src/AnnotationService/tools/Subscript.js  |  23 ++
 .../AnnotationService/tools/Superscript.js    |  23 ++
 .../src/AnnotationService/tools/Table.js      |  22 ++
 .../tools/TableDropDownOptions.js             |  35 +++
 .../src/AnnotationService/tools/Underline.js  |  23 ++
 .../src/AnnotationService/tools/index.js      |  12 +
 .../src/ImageService/Image.js                 |  34 +++
 .../src/ImageService/ImageService.js          |  10 +
 .../src/ImageService/fileUpload.js            |  49 ++++
 .../src/LinkService/LinkService.js            |   1 -
 .../src/MenuService/Menu.js                   |   1 -
 .../src/MenuService/MenuService.js            |  25 +-
 .../PlaceholderService/PlaceholderService.js  |  11 +
 .../pmPlugins/placeholderPlugin.js            |  35 +++
 .../src/TextStyleService/TextStyle.js         |  39 +++
 .../src/TextStyleService/TextStyleService.js  |  14 +
 .../src/TextStyleService/tools/Author.js      |  21 ++
 .../TextStyleService/tools/EpigraphPoetry.js  |  21 ++
 .../TextStyleService/tools/EpigraphProse.js   |  21 ++
 .../src/TextStyleService/tools/Heading1.js    |  27 ++
 .../src/TextStyleService/tools/Heading2.js    |  27 ++
 .../src/TextStyleService/tools/Heading3.js    |  27 ++
 .../src/TextStyleService/tools/Plain.js       |  21 ++
 .../src/TextStyleService/tools/Subtitle.js    |  21 ++
 .../src/TextStyleService/tools/Title.js       |  22 ++
 .../src/TextStyleService/tools/index.js       |   9 +
 wax-prosemirror-plugins/src/lib/GroupTool.js  |  15 +-
 wax-prosemirror-plugins/src/lib/Tools.js      |  14 +-
 .../src/lib/Utils.js                          |   0
 .../src/menuBar/MenuBarPlugin.js              |  24 --
 63 files changed, 1063 insertions(+), 644 deletions(-)
 delete mode 100644 wax-prosemirror-components/src/helpers.js
 delete mode 100644 wax-prosemirror-components/src/mainMenuBar/MainMenuBar.js
 delete mode 100644 wax-prosemirror-components/src/mainMenuBar/MainMenuBarItems.js
 delete mode 100644 wax-prosemirror-components/src/sideMenuBar/SideMenuBar.js
 delete mode 100644 wax-prosemirror-components/src/sideMenuBar/SideMenuCommands.js
 delete mode 100644 wax-prosemirror-components/src/sideMenuBar/SideMenuItems.js
 create mode 100644 wax-prosemirror-core/src/PmPlugins.js
 create mode 100644 wax-prosemirror-plugins/jsconfig.json
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/Annotation.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/AnnotationService.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Blockquote.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/BulletList.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Code.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Em.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/JoinUp.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Lift.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Link.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/OrderedList.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/SmallCaps.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/StrikeThrough.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Strong.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Subscript.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Superscript.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Table.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/TableDropDownOptions.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/Underline.js
 create mode 100644 wax-prosemirror-plugins/src/AnnotationService/tools/index.js
 create mode 100644 wax-prosemirror-plugins/src/ImageService/Image.js
 create mode 100644 wax-prosemirror-plugins/src/ImageService/ImageService.js
 create mode 100644 wax-prosemirror-plugins/src/ImageService/fileUpload.js
 create mode 100644 wax-prosemirror-plugins/src/PlaceholderService/PlaceholderService.js
 create mode 100644 wax-prosemirror-plugins/src/PlaceholderService/pmPlugins/placeholderPlugin.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/TextStyle.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/TextStyleService.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/Author.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphPoetry.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphProse.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/Heading1.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/Heading2.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/Heading3.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/Plain.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/Subtitle.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/Title.js
 create mode 100644 wax-prosemirror-plugins/src/TextStyleService/tools/index.js
 rename wax-prosemirror-components/src/mainMenuBar/MainMenuCommands.js => wax-prosemirror-plugins/src/lib/Utils.js (100%)
 delete mode 100644 wax-prosemirror-plugins/src/menuBar/MenuBarPlugin.js

diff --git a/editors/editoria/src/EditorConfig.js b/editors/editoria/src/EditorConfig.js
index c0a25e94b..249b80c59 100644
--- a/editors/editoria/src/EditorConfig.js
+++ b/editors/editoria/src/EditorConfig.js
@@ -32,11 +32,10 @@ import {
   LinkToolTipPlugin,
   FindAndReplacePlugin,
   TrackChangePlugin,
-  MenuBarPlugin,
   LinkService
 } from "wax-prosemirror-plugins";
 
-import { MainMenuBar, SideMenuBar } from "wax-prosemirror-components";
+// import { MainMenuBar, SideMenuBar } from "wax-prosemirror-components";
 
 import { tableNodes, columnResizing, tableEditing } from "prosemirror-tables";
 import { EditoriaSchema } from "wax-prosemirror-schema";
diff --git a/editors/editoria/src/config/menu.js b/editors/editoria/src/config/menu.js
index c29b97c34..c2aac56d0 100644
--- a/editors/editoria/src/config/menu.js
+++ b/editors/editoria/src/config/menu.js
@@ -1,9 +1,12 @@
 export default {
   MenuService: [
     {
-      name: "top",
       templateArea: "topBar",
-      groupTools: [{ name: "RedoUndo", exclude: [] }]
+      groupTools: ["Annotation", { name: "RedoUndo", exclude: ["Redo"] }]
+    },
+    {
+      templateArea: "leftSideBar",
+      groupTools: ["TextStyle"]
     }
   ]
 };
diff --git a/wax-prosemirror-components/index.js b/wax-prosemirror-components/index.js
index 0e8075554..4ce7e5aa5 100644
--- a/wax-prosemirror-components/index.js
+++ b/wax-prosemirror-components/index.js
@@ -1,6 +1,6 @@
-export { default as MainMenuBar } from "./src/mainMenuBar/MainMenuBar";
-export { default as SideMenuBar } from "./src/sideMenuBar/SideMenuBar";
 export { default as InfoArea } from "./src/components/infoArea/InfoArea";
 export { default as Overlay } from "./src/components/Overlay";
 export { default as Button } from "./src/components/Button";
 export { default as icons } from "./src/icons/icons";
+export { default as TableDropDown } from "./src/components/TableDropDown";
+export { default as ImageUpload } from "./src/components/ImageUpload";
diff --git a/wax-prosemirror-components/src/components/ImageUpload.js b/wax-prosemirror-components/src/components/ImageUpload.js
index 1fcc22724..8c3995cb9 100644
--- a/wax-prosemirror-components/src/components/ImageUpload.js
+++ b/wax-prosemirror-components/src/components/ImageUpload.js
@@ -13,7 +13,7 @@ const UploadImage = styled.div`
     display: none;
   }
 `;
-const ImageUpload = ({ item, view: { state }, handle, fileUpload }) => (
+const ImageUpload = ({ item, fileUpload }) => (
   <UploadImage>
     <label
       className="custom-file-upload"
diff --git a/wax-prosemirror-components/src/helpers.js b/wax-prosemirror-components/src/helpers.js
deleted file mode 100644
index bdb81d6b4..000000000
--- a/wax-prosemirror-components/src/helpers.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const filtered = (menu, menuItems) =>
-  Object.keys(menu)
-    .filter(key => menuItems.includes(key))
-    .reduce((obj, key) => {
-      obj[key] = menu[key];
-      return obj;
-    }, {});
-
-const setMenuItems = (allMenuItems, menuItems) => {
-  if (menuItems.length === 0) return allMenuItems;
-  return filtered(allMenuItems, menuItems);
-};
-
-export { setMenuItems };
diff --git a/wax-prosemirror-components/src/mainMenuBar/MainMenuBar.js b/wax-prosemirror-components/src/mainMenuBar/MainMenuBar.js
deleted file mode 100644
index 088cccf57..000000000
--- a/wax-prosemirror-components/src/mainMenuBar/MainMenuBar.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-
-import { map } from "lodash";
-import MainMenuBarItems from "./MainMenuBarItems";
-import { setMenuItems } from "../helpers";
-
-const MainMenuContainer = styled.div`
-  background: #fff;
-  height: 52px;
-  line-height: 32px;
-  position: relative;
-  user-select: none;
-`;
-const MainMenuInner = styled.div`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  flex-direction: column;
-  left: 0;
-  position: absolute;
-  right: 0;
-  top: 0;
-  background: transparent;
-  z-index: 9999;
-`;
-const MainMenu = styled.div`
-  background: #fff;
-  padding: 2px 2px 2px 0;
-  position: relative;
-  background: transparent;
-`;
-
-const MainMenuBar = ({ menuItems = [], view, className, fileUpload }) => (
-  <MainMenuContainer>
-    <MainMenuInner>
-      <MainMenu>
-        {map(setMenuItems(MainMenuBarItems, menuItems), item =>
-          item.menu({ view, item, fileUpload })
-        )}
-      </MainMenu>
-    </MainMenuInner>
-  </MainMenuContainer>
-);
-
-export default MainMenuBar;
diff --git a/wax-prosemirror-components/src/mainMenuBar/MainMenuBarItems.js b/wax-prosemirror-components/src/mainMenuBar/MainMenuBarItems.js
deleted file mode 100644
index ff91f0c41..000000000
--- a/wax-prosemirror-components/src/mainMenuBar/MainMenuBarItems.js
+++ /dev/null
@@ -1,263 +0,0 @@
-import React from "react";
-import { v4 as uuid } from "uuid";
-import {
-  joinUp,
-  lift,
-  setBlockType,
-  toggleMark,
-  wrapIn,
-  selectParentNode
-} from "prosemirror-commands";
-
-import { addColumnBefore } from "prosemirror-tables";
-
-import { redo, undo } from "prosemirror-history";
-import { wrapInList } from "prosemirror-schema-list";
-
-import icons from "../icons/icons";
-//Components
-import Button from "../components/Button";
-import TableDropDown from "../components/TableDropDown";
-import ImageUpload from "../components/ImageUpload";
-import HeadingsDropDown from "../components/HeadingsDropDown";
-
-import {
-  markActive,
-  blockActive,
-  canInsert,
-  promptForURL,
-  createTable
-} from "./MainMenuCommands";
-
-import sideMenuBarItems from "../sideMenuBar/SideMenuItems";
-
-export default {
-  ...sideMenuBarItems,
-  undo: {
-    title: "Undo last change",
-    content: icons.undo,
-    enable: undo,
-    run: undo,
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  redo: {
-    title: "Redo last undone change",
-    content: icons.redo,
-    enable: redo,
-    run: redo,
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  em: {
-    title: "Toggle emphasis",
-    content: icons.em,
-    active: state => {
-      return markActive(state.config.schema.marks.em)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.em)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  strong: {
-    title: "Toggle strong",
-    content: icons.strong,
-    active: state => {
-      return markActive(state.config.schema.marks.strong)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.strong)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  code: {
-    title: "Toggle code",
-    content: icons.code,
-    active: state => {
-      return markActive(state.config.schema.marks.code)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.code)(state, dispatch);
-    },
-
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  small_caps: {
-    title: "Toggle Small Caps",
-    content: icons.small_caps,
-    active: state => {
-      return markActive(state.config.schema.marks.small_caps)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.small_caps)(state, dispatch);
-    },
-
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  subscript: {
-    title: "Toggle subscript",
-    content: icons.subscript,
-    active: state => {
-      return markActive(state.config.schema.marks.subscript)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.subscript)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  superscript: {
-    title: "Toggle superscript",
-    content: icons.superscript,
-    active: state => {
-      return markActive(state.config.schema.marks.superscript)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.superscript)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  underline: {
-    title: "Toggle underline",
-    content: icons.underline,
-    active: state => {
-      return markActive(state.config.schema.marks.underline)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.underline)(state, dispatch);
-    },
-
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  strikethrough: {
-    title: "Toggle strikethrough",
-    content: icons.strikethrough,
-    active: state => {
-      return markActive(state.config.schema.marks.strikethrough)(state);
-    },
-    run(state, dispatch) {
-      toggleMark(state.config.schema.marks.strikethrough)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  link: {
-    title: "Add or remove link",
-    content: icons.link,
-    active: state => {
-      return markActive(state.config.schema.marks.link)(state);
-    },
-    enable: state => !state.selection.empty,
-    run(state, dispatch) {
-      if (markActive(state.config.schema.marks.link)(state)) {
-        toggleMark(state.config.schema.marks.link)(state, dispatch);
-        return true;
-      }
-
-      const href = promptForURL();
-      if (!href) return false;
-
-      toggleMark(state.config.schema.marks.link, { href })(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  blockquote: {
-    title: "Wrap in block quote",
-    content: icons.blockquote,
-    active: state => {
-      return blockActive(state.config.schema.nodes.blockquote)(state);
-    },
-    enable: state => {
-      return wrapIn(state.config.schema.nodes.blockquote)(state);
-    },
-    run(state, dispatch) {
-      wrapIn(state.config.schema.nodes.blockquote)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  bullet_list: {
-    title: "Wrap in bullet list",
-    content: icons.bullet_list,
-    active: state => {
-      return blockActive(state.config.schema.nodes.bullet_list)(state);
-    },
-    enable: state => {
-      return wrapInList(state.config.schema.nodes.bullet_list)(state);
-    },
-    run(state, dispatch) {
-      wrapInList(state.config.schema.nodes.bullet_list)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  ordered_list: {
-    title: "Wrap in ordered list",
-    content: icons.ordered_list,
-    active: state => {
-      return blockActive(state.config.schema.nodes.ordered_list)(state);
-    },
-    enable: state => {
-      return wrapInList(state.config.schema.nodes.ordered_list)(state);
-    },
-    run(state, dispatch) {
-      wrapInList(state.config.schema.nodes.ordered_list)(state, dispatch);
-    },
-
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  lift: {
-    title: "Lift out of enclosing block",
-    content: icons.lift,
-    enable: lift,
-    run: lift,
-    select: state => lift(state),
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  join_up: {
-    title: "Join with above block",
-    content: icons.join_up,
-    select: state => joinUp(state),
-    enable: joinUp,
-    run: joinUp,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  image: {
-    title: "Insert image",
-    content: icons.image,
-    enable: state => {
-      return canInsert(state.config.schema.nodes.image)(state);
-    },
-    select: state => true,
-    run: option => true,
-    menu: props => <ImageUpload key={uuid()} {...props} />
-  },
-  table: {
-    title: "Insert table",
-    content: icons.table,
-    enable: state => {
-      return canInsert(state.config.schema.nodes.table)(state);
-    },
-    run: (state, dispatch) => {
-      return createTable(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  tableDropDownOptions: {
-    content: "table",
-    run: option => true,
-    title: "Select Options",
-    select: state => addColumnBefore(state),
-    menu: props => <TableDropDown key={uuid()} {...props} />
-  }
-};
diff --git a/wax-prosemirror-components/src/sideMenuBar/SideMenuBar.js b/wax-prosemirror-components/src/sideMenuBar/SideMenuBar.js
deleted file mode 100644
index 4b2abd2ce..000000000
--- a/wax-prosemirror-components/src/sideMenuBar/SideMenuBar.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from "react";
-import styled from "styled-components";
-import { map } from "lodash";
-import SideMenuItems from "./SideMenuItems";
-import { setMenuItems } from "../helpers";
-
-const SideMenuContainer = styled.div`
-  display: flex;
-  width: 12%;
-  height: 98%;
-`;
-
-const SideMenuInner = styled.div`
-  display: flex;
-  width: 100%;
-`;
-
-const SideMenu = styled.div`
-  flex: 1;
-  display: flex;
-  flex-direction: column;
-  justify-content: flex-start;
-  margin-top: 15px;
-  button {
-    display: flex;
-    flex-direction: column;
-    font-family: ${props => props.theme.fontInterface};
-    margin-left: 5%;
-    width: 90%;
-  }
-`;
-
-const SideMenuBar = ({ menuItems = [], view, className }) => (
-  <SideMenuContainer>
-    <SideMenuInner>
-      <SideMenu>
-        {map(setMenuItems(SideMenuItems, menuItems), item =>
-          item.menu({ view, item })
-        )}
-      </SideMenu>
-    </SideMenuInner>
-  </SideMenuContainer>
-);
-
-export default SideMenuBar;
diff --git a/wax-prosemirror-components/src/sideMenuBar/SideMenuCommands.js b/wax-prosemirror-components/src/sideMenuBar/SideMenuCommands.js
deleted file mode 100644
index b9620b658..000000000
--- a/wax-prosemirror-components/src/sideMenuBar/SideMenuCommands.js
+++ /dev/null
@@ -1,10 +0,0 @@
-const blockActive = (type, attrs = {}) => state => {
-  const { $from, to, node } = state.selection;
-
-  if (node) {
-    return node.hasMarkup(type, attrs);
-  }
-  return to <= $from.end() && $from.parent.hasMarkup(type, attrs);
-};
-
-export { blockActive };
diff --git a/wax-prosemirror-components/src/sideMenuBar/SideMenuItems.js b/wax-prosemirror-components/src/sideMenuBar/SideMenuItems.js
deleted file mode 100644
index efef95626..000000000
--- a/wax-prosemirror-components/src/sideMenuBar/SideMenuItems.js
+++ /dev/null
@@ -1,145 +0,0 @@
-import React from "react";
-import { v4 as uuid } from "uuid";
-import { setBlockType } from "prosemirror-commands";
-
-import Button from "../components/Button";
-import { blockActive } from "./SideMenuItems";
-export default {
-  title: {
-    title: "Change to Title",
-    content: "Title",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.title)(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.title)(state, dispatch);
-    },
-
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  subtitle: {
-    title: "Change to Subtilte",
-    content: "Subtilte",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.subtitle)(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.subtitle)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  author: {
-    title: "Change to Author",
-    content: "Author",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.author)(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.author)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  epigraphPoetry: {
-    title: "Change to Epigraph Poetry",
-    content: "Epigraph Poetry",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.epigraphPoetry)(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.epigraphPoetry)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  epigraphProse: {
-    title: "Change to Epigraph Prose",
-    content: "Epigraph Prose",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.epigraphProse)(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.epigraphProse)(state, dispatch);
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  plain: {
-    title: "Change to General Text",
-    content: "General Text",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.paragraph)(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.paragraph)(state, dispatch);
-    },
-
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  heading1: {
-    title: "Change to heading level 1",
-    content: "Heading 1",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.heading, {
-        level: 1,
-        track: []
-      })(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.heading, { level: 1 })(
-        state,
-        dispatch
-      );
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  heading2: {
-    title: "Change to heading level 2",
-    content: "Heading 2",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.heading, {
-        level: 2,
-        track: []
-      })(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.heading, { level: 2 })(
-        state,
-        dispatch
-      );
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  },
-  heading3: {
-    title: "Change to heading level 3",
-    content: "Heading 3",
-    group: "",
-    enable: state => {
-      return setBlockType(state.config.schema.nodes.heading, {
-        level: 3,
-        track: []
-      })(state);
-    },
-    run(state, dispatch) {
-      setBlockType(state.config.schema.nodes.heading, { level: 3 })(
-        state,
-        dispatch
-      );
-    },
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
-  }
-};
diff --git a/wax-prosemirror-core/src/Application.js b/wax-prosemirror-core/src/Application.js
index 8c77d71bd..aa4d328a6 100644
--- a/wax-prosemirror-core/src/Application.js
+++ b/wax-prosemirror-core/src/Application.js
@@ -2,12 +2,15 @@ import { Container } from "inversify";
 import "reflect-metadata";
 import Config from "./Config/Config";
 import defaultConfig from "./Config/defaultConfig";
+import PmPlugins from "./PmPlugins";
 
 export default class Application {
   container = {};
   config = {};
+  PmPlugins = {};
   constructor(container) {
     this.container = container;
+    this.PmPlugins = container.get("PmPlugins");
   }
 
   registerServices() {
@@ -40,6 +43,10 @@ export default class Application {
     });
   }
 
+  getPlugins() {
+    return this.PmPlugins.getAll();
+  }
+
   static create(config) {
     /*
     Create Container
@@ -49,6 +56,10 @@ export default class Application {
     /*
     Set base bindings for the App to work
     */
+    container
+      .bind("PmPlugins")
+      .to(PmPlugins)
+      .inSingletonScope();
     container.bind("Wax").toFactory(() => new Application(container));
     container.bind("config").toConstantValue(defaultConfig);
     container
diff --git a/wax-prosemirror-core/src/Config/Config.js b/wax-prosemirror-core/src/Config/Config.js
index 34f027839..d55a3be45 100644
--- a/wax-prosemirror-core/src/Config/Config.js
+++ b/wax-prosemirror-core/src/Config/Config.js
@@ -20,7 +20,13 @@ export default class Config {
   pushToArray(key, value) {
     let oldValue = this.get(key);
     if (oldValue) {
-      oldValue.push(value);
+      if (isArrayLikeObject(value)) {
+        value.forEach(v => {
+          oldValue.push(v);
+        });
+      } else {
+        oldValue.push(value);
+      }
     } else {
       oldValue = value;
     }
diff --git a/wax-prosemirror-core/src/Config/defaultConfig.js b/wax-prosemirror-core/src/Config/defaultConfig.js
index 3ecd95773..ea98d06c1 100644
--- a/wax-prosemirror-core/src/Config/defaultConfig.js
+++ b/wax-prosemirror-core/src/Config/defaultConfig.js
@@ -1,6 +1,21 @@
 import LayoutService from "../services/LayoutService/LayoutService";
-import { MenuService, RedoUndoService } from "wax-prosemirror-plugins";
+import {
+  MenuService,
+  AnnotationService,
+  RedoUndoService,
+  TextStyleService,
+  PlaceholderService,
+  ImageService
+} from "wax-prosemirror-plugins";
 
 export default {
-  services: [new LayoutService(), new MenuService(), new RedoUndoService()]
+  services: [
+    new LayoutService(),
+    new MenuService(),
+    new RedoUndoService(),
+    new AnnotationService(),
+    new TextStyleService(),
+    new PlaceholderService(),
+    new ImageService()
+  ]
 };
diff --git a/wax-prosemirror-core/src/PmPlugins.js b/wax-prosemirror-core/src/PmPlugins.js
new file mode 100644
index 000000000..ac5b5bf56
--- /dev/null
+++ b/wax-prosemirror-core/src/PmPlugins.js
@@ -0,0 +1,16 @@
+import { injectable } from "inversify";
+@injectable()
+export default class PmPlugins {
+  _plugins = new Map();
+  add(key, plugin) {
+    this._plugins.set(key, plugin);
+  }
+
+  getAll() {
+    return [...this._plugins.values()];
+  }
+
+  get(key) {
+    return this._plugins.get(key);
+  }
+}
diff --git a/wax-prosemirror-core/src/Wax.js b/wax-prosemirror-core/src/Wax.js
index e6cf49d29..1033c94cf 100644
--- a/wax-prosemirror-core/src/Wax.js
+++ b/wax-prosemirror-core/src/Wax.js
@@ -46,7 +46,8 @@ class Wax extends Component {
     super(props);
     const { config } = props;
     console.log("Appp Started", config);
-    this.application = Application.create(config);
+    debugger;
+    this.application = Application.create(props);
   }
 
   componentWillMount() {
@@ -54,21 +55,23 @@ class Wax extends Component {
     const { schema, plugins, keys, rules } = options;
     const WaxOnchange = onChange ? onChange : value => true;
 
-    const WaxShortCuts = keys
-      ? keys
-      : new CreateShortCuts({ schema: schema, shortCuts: {} });
+    // const WaxShortCuts = keys
+    //   ? keys
+    //   : new CreateShortCuts({ schema: schema, shortCuts: {} });
 
-    const WaxRules = new CreateRules({ schema: schema, rules: rules });
+    // const WaxRules = new CreateRules({ schema: schema, rules: rules });
 
     const editorContent = value ? value : "";
 
-    if (plugins) defaultPlugins.push(...plugins);
+    // if (plugins) defaultPlugins.push(...plugins);
 
-    const finalPlugins = defaultPlugins.concat([
-      placeholder({ content: this.props.placeholder }),
-      WaxShortCuts,
-      WaxRules
-    ]);
+    // const finalPlugins = defaultPlugins.concat([
+    //   placeholder({ content: this.props.placeholder }),
+    //   WaxShortCuts,
+    //   WaxRules
+    // ]);
+
+    const finalPlugins = this.application.getPlugins();
 
     this.WaxOptions = {
       schema,
diff --git a/wax-prosemirror-core/src/WaxView.js b/wax-prosemirror-core/src/WaxView.js
index afc9eb25d..c7698ddef 100644
--- a/wax-prosemirror-core/src/WaxView.js
+++ b/wax-prosemirror-core/src/WaxView.js
@@ -39,59 +39,6 @@ class WaxView extends Component {
     if (autoFocus) this.view.focus();
   }
 
-  uploadImage = file => {
-    const { state } = this.view;
-    const { findPlaceholder } = this;
-    const { fileUpload } = this.props;
-
-    // A fresh object to act as the ID for this upload
-    const id = {};
-
-    // Replace the selection with a placeholder
-    const { tr } = state;
-    if (!tr.selection.empty) tr.deleteSelection();
-
-    tr.setMeta(placeholderPlugin, {
-      add: { id, pos: tr.selection.from }
-    });
-
-    this.view.dispatch(tr);
-
-    fileUpload(file).then(
-      url => {
-        const pos = findPlaceholder(this.view.state, id);
-        // If the content around the placeholder has been deleted, drop
-        // the image
-        if (pos == null) {
-          return;
-        }
-        // Otherwise, insert it at the placeholder's position, and remove
-        // the placeholder
-        this.view.dispatch(
-          state.tr
-            .replaceWith(
-              pos,
-              pos,
-              this.view.state.schema.nodes.image.create({
-                src: url
-              })
-            )
-            .setMeta(placeholderPlugin, { remove: { id } })
-        );
-      },
-      () => {
-        // On failure, just clean up the placeholder
-        this.view.dispatch(tr.setMeta(placeholderPlugin, { remove: { id } }));
-      }
-    );
-  };
-
-  findPlaceholder = (state, id) => {
-    const decos = placeholderPlugin.getState(state);
-    const found = decos.find(null, null, spec => spec.id === id);
-    return found.length ? found[0].from : null;
-  };
-
   dispatchTransaction = transaction => {
     const { TrackChange } = this.props;
     const tr = TrackChange
@@ -107,7 +54,6 @@ class WaxView extends Component {
     const editor = <span ref={this.editorRef} />;
     return this.props.children({
       view: this.view,
-      fileUpload: this.uploadImage,
       editor
     });
   }
diff --git a/wax-prosemirror-core/src/services/Service.js b/wax-prosemirror-core/src/services/Service.js
index 03bf881d7..5f0daa326 100644
--- a/wax-prosemirror-core/src/services/Service.js
+++ b/wax-prosemirror-core/src/services/Service.js
@@ -9,6 +9,6 @@ export default class Service {
   }
 
   get config() {
-    return this.app.config.get(this.name);
+    return this.app.config.get(`config.${this.name}`);
   }
 }
diff --git a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js
index 334b6cef4..3569ee6e0 100644
--- a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js
+++ b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js
@@ -33,8 +33,52 @@ const WaxSurfaceScroll = styled.div`
   ${EditorElements};
 `;
 
+const MainMenuContainer = styled.div`
+  background: #fff;
+  height: 52px;
+  line-height: 32px;
+  position: relative;
+  user-select: none;
+`;
+const MainMenuInner = styled.div`
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  flex-direction: column;
+  left: 0;
+  position: absolute;
+  right: 0;
+  top: 0;
+  background: transparent;
+  z-index: 9999;
+`;
+
+const SideMenuContainer = styled.div`
+  display: flex;
+  width: 12%;
+  height: 98%;
+`;
+
+const SideMenuInner = styled.div`
+  display: flex;
+  width: 100%;
+  > div {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    justify-content: flex-start;
+    margin-top: 15px;
+    button {
+      display: flex;
+      flex-direction: column;
+      font-family: ${props => props.theme.fontInterface};
+      margin-left: 5%;
+      width: 90%;
+    }
+  }
+`;
+
 const EditoriaLayout = ({ editor, componentPlugin }) => {
-  console.log("1111111111111111111111");
   const LeftSideBar = componentPlugin("leftSideBar");
   const RightSideBar = componentPlugin("rightSideBar");
   const TopBar = componentPlugin("topBar");
@@ -43,9 +87,17 @@ const EditoriaLayout = ({ editor, componentPlugin }) => {
   return (
     <ThemeProvider theme={cokoTheme}>
       <LayoutWrapper>
-        <TopBar />
+        <MainMenuContainer>
+          <MainMenuInner>
+            <TopBar />
+          </MainMenuInner>
+        </MainMenuContainer>
         <WaxSurfaceContainer>
-          <LeftSideBar />
+          <SideMenuContainer>
+            <SideMenuInner>
+              <LeftSideBar />
+            </SideMenuInner>
+          </SideMenuContainer>
           <WaxSurfaceScroll className="wax-surface-scroll">
             {editor}
             <EditorOverlays />
diff --git a/wax-prosemirror-plugins/index.js b/wax-prosemirror-plugins/index.js
index a8d92ad8b..6c190ed4b 100644
--- a/wax-prosemirror-plugins/index.js
+++ b/wax-prosemirror-plugins/index.js
@@ -4,4 +4,9 @@ export { default as OverlayPlugin } from "./src/overlay/OverlayPlugin";
 export { default as LinkService } from "./src/LinkService/LinkService";
 export { default as MenuService } from "./src/MenuService/MenuService";
 export { default as RedoUndoService } from "./src/RedoUndoService/RedoUndoService";
+export { default as AnnotationService } from "./src/AnnotationService/AnnotationService";
+export { default as TextStyleService } from "./src/TextStyleService/TextStyleService";
+export { default as PlaceholderService } from "./src/PlaceholderService/PlaceholderService";
+export { default as ImageService } from "./src/ImageService/ImageService";
+
 export { default as Tool } from "./src/lib/Tools";
diff --git a/wax-prosemirror-plugins/jsconfig.json b/wax-prosemirror-plugins/jsconfig.json
new file mode 100644
index 000000000..504cd646e
--- /dev/null
+++ b/wax-prosemirror-plugins/jsconfig.json
@@ -0,0 +1,5 @@
+{
+  "compilerOptions": {
+    "experimentalDecorators": true
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/Annotation.js b/wax-prosemirror-plugins/src/AnnotationService/Annotation.js
new file mode 100644
index 000000000..0fc9dfd7d
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/Annotation.js
@@ -0,0 +1,47 @@
+import { injectable, inject } from "inversify";
+import GroupTool from "../lib/GroupTool";
+
+@injectable()
+export default class Annotation extends GroupTool {
+  tools = [];
+  constructor(
+    @inject("Code") code,
+    @inject("Em") em,
+    @inject("Link") link,
+    @inject("SmallCaps") smallcaps,
+    @inject("StrikeThrough") strikethrough,
+    @inject("Strong") strong,
+    @inject("Subscript") subscript,
+    @inject("Superscript") superscript,
+    @inject("Underline") underline,
+    @inject("Blockquote") blockquote,
+    @inject("Image") image,
+    @inject("Table") table,
+    @inject("TableDropDownOptions") tableDropDownOptions
+  ) {
+    super();
+    this.tools = [
+      code,
+      em,
+      link,
+      smallcaps,
+      strikethrough,
+      strong,
+      subscript,
+      superscript,
+      underline,
+      blockquote,
+      tableDropDownOptions,
+      image,
+      table
+    ];
+  }
+
+  renderTools(view) {
+    const tools = [];
+    this.tools.forEach(tool => {
+      tools.push(tool.renderTool(view));
+    });
+    return tools;
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/AnnotationService.js b/wax-prosemirror-plugins/src/AnnotationService/AnnotationService.js
new file mode 100644
index 000000000..56269cef3
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/AnnotationService.js
@@ -0,0 +1,14 @@
+import Annotation from "./Annotation";
+import Service from "wax-prosemirror-core/src/services/Service";
+import * as Tools from "./tools";
+
+export default class AnnotationService extends Service {
+  name = "AnnotationService";
+
+  register() {
+    this.container.bind("Annotation").to(Annotation);
+    Object.entries(Tools).forEach(([key, value]) => {
+      this.container.bind(key).to(value);
+    });
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Blockquote.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Blockquote.js
new file mode 100644
index 000000000..209dddbe2
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Blockquote.js
@@ -0,0 +1,29 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+import { wrapIn } from "prosemirror-commands";
+import { blockActive } from "../../lib/Utils";
+
+@injectable()
+export default class Blockquote extends Tools {
+  title = "Wrap in block quote";
+  content = icons.blockquote;
+
+  get run() {
+    return (state, dispatch) => {
+      wrapIn(state.config.schema.nodes.blockquote)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return wrapIn(state.config.schema.nodes.blockquote)(state);
+    };
+  }
+
+  get active() {
+    return state => {
+      return blockActive(state.config.schema.nodes.blockquote)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/BulletList.js b/wax-prosemirror-plugins/src/AnnotationService/tools/BulletList.js
new file mode 100644
index 000000000..8db01475c
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/BulletList.js
@@ -0,0 +1,29 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+import { wrapInList } from "prosemirror-commands";
+import { blockActive } from "../../lib/Utils";
+
+@injectable()
+export default class BulletList extends Tools {
+  title = "Wrap in bullet list";
+  content = icons.bullet_list;
+
+  get run() {
+    return (state, dispatch) => {
+      wrapInList(state.config.schema.nodes.bullet_list)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return wrapInList(state.config.schema.nodes.bullet_list)(state);
+    };
+  }
+
+  get active() {
+    return state => {
+      return blockActive(state.config.schema.nodes.bullet_list)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Code.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Code.js
new file mode 100644
index 000000000..61887249a
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Code.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Code extends Tools {
+  title = "Toggle code";
+  content = icons.code;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.code)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.code)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Em.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Em.js
new file mode 100644
index 000000000..8590d7004
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Em.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Em extends Tools {
+  title = "Toggle emphasis";
+  content = icons.em;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.em)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.em)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/JoinUp.js b/wax-prosemirror-plugins/src/AnnotationService/tools/JoinUp.js
new file mode 100644
index 000000000..0e5907bd1
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/JoinUp.js
@@ -0,0 +1,22 @@
+import { joinUp } from "prosemirror-commands";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class JoinUp extends Tools {
+  title = "Join with above block";
+  content = icons.join_up;
+
+  get run() {
+    return joinUp;
+  }
+
+  get enable() {
+    return joinUp;
+  }
+
+  select(state) {
+    return joinUp(state);
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Lift.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Lift.js
new file mode 100644
index 000000000..2bf470082
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Lift.js
@@ -0,0 +1,18 @@
+import { lift } from "prosemirror-commands";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Lift extends Tools {
+  title = "Lift out of enclosing block";
+  content = icons.lift;
+
+  get run() {
+    return lift;
+  }
+
+  get enable() {
+    return lift;
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Link.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Link.js
new file mode 100644
index 000000000..c8cc20bb0
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Link.js
@@ -0,0 +1,35 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive, promptForURL } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Link extends Tools {
+  title = "Add or remove link";
+  content = icons.link;
+
+  get run() {
+    return (state, dispatch) => {
+      if (markActive(state.config.schema.marks.link)(state)) {
+        toggleMark(state.config.schema.marks.link)(state, dispatch);
+        return true;
+      }
+
+      const href = promptForURL();
+      if (!href) return false;
+
+      toggleMark(state.config.schema.marks.link, { href })(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => !state.selection.empty;
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.link)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/OrderedList.js b/wax-prosemirror-plugins/src/AnnotationService/tools/OrderedList.js
new file mode 100644
index 000000000..2224e28cf
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/OrderedList.js
@@ -0,0 +1,29 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+import { wrapInList } from "prosemirror-commands";
+import { blockActive } from "../../lib/Utils";
+
+@injectable()
+export default class OrderedList extends Tools {
+  title = "Wrap in ordered list";
+  content = icons.ordered_list;
+
+  get run() {
+    return (state, dispatch) => {
+      wrapInList(state.config.schema.nodes.ordered_list)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return wrapInList(state.config.schema.nodes.ordered_list)(state);
+    };
+  }
+
+  get active() {
+    return state => {
+      return blockActive(state.config.schema.nodes.ordered_list)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/SmallCaps.js b/wax-prosemirror-plugins/src/AnnotationService/tools/SmallCaps.js
new file mode 100644
index 000000000..14a98887d
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/SmallCaps.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class SmallCaps extends Tools {
+  title = "Toggle Small Caps";
+  content = icons.small_caps;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.small_caps)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.small_caps)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/StrikeThrough.js b/wax-prosemirror-plugins/src/AnnotationService/tools/StrikeThrough.js
new file mode 100644
index 000000000..ef38b0a08
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/StrikeThrough.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class StrikeThrough extends Tools {
+  title = "Toggle strikethrough";
+  content = icons.strikethrough;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.strikethrough)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.strikethrough)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Strong.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Strong.js
new file mode 100644
index 000000000..c2f94db1e
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Strong.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Strong extends Tools {
+  title = "Toggle strong";
+  content = icons.strong;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.strong)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.strong)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Subscript.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Subscript.js
new file mode 100644
index 000000000..53ef5fc74
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Subscript.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Subscript extends Tools {
+  title = "Toggle subscript";
+  content = icons.subscript;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.subscript)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.subscript)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Superscript.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Superscript.js
new file mode 100644
index 000000000..9063597cd
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Superscript.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Superscript extends Tools {
+  title = "Toggle superscript";
+  content = icons.superscript;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.superscript)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.superscript)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Table.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Table.js
new file mode 100644
index 000000000..238c9084e
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Table.js
@@ -0,0 +1,22 @@
+import Tools from "../../lib/Tools";
+import { createTable, canInsert } from "../../lib/Utils";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Table extends Tools {
+  title = "Insert table";
+  content = icons.table;
+
+  get run() {
+    return (state, dispatch) => {
+      return createTable(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return canInsert(state.config.schema.nodes.table)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/TableDropDownOptions.js b/wax-prosemirror-plugins/src/AnnotationService/tools/TableDropDownOptions.js
new file mode 100644
index 000000000..9deea97f4
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/TableDropDownOptions.js
@@ -0,0 +1,35 @@
+import React from "react";
+import { v4 as uuid } from "uuid";
+import { canInsert } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { TableDropDown } from "wax-prosemirror-components";
+import { addColumnBefore } from "prosemirror-tables";
+
+@injectable()
+export default class TableDropDownOptions extends Tools {
+  title = "Select Options";
+  content = "table";
+
+  get run() {
+    return () => {
+      return true;
+    };
+  }
+
+  get enable() {
+    return state => {
+      return canInsert(state.config.schema.nodes.table)(state);
+    };
+  }
+
+  select(state) {
+    return addColumnBefore(state);
+  }
+
+  renderTool(view) {
+    return this._isEnabled ? (
+      <TableDropDown key={uuid()} item={this.toJSON()} {...view} />
+    ) : null;
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/Underline.js b/wax-prosemirror-plugins/src/AnnotationService/tools/Underline.js
new file mode 100644
index 000000000..1c1026b9c
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/Underline.js
@@ -0,0 +1,23 @@
+import { toggleMark } from "prosemirror-commands";
+import { markActive } from "../../lib/Utils";
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { icons } from "wax-prosemirror-components";
+
+@injectable()
+export default class Underline extends Tools {
+  title = "Toggle underline";
+  content = icons.underline;
+
+  get run() {
+    return (state, dispatch) => {
+      toggleMark(state.config.schema.marks.underline)(state, dispatch);
+    };
+  }
+
+  get active() {
+    return state => {
+      return markActive(state.config.schema.marks.underline)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/AnnotationService/tools/index.js b/wax-prosemirror-plugins/src/AnnotationService/tools/index.js
new file mode 100644
index 000000000..30b7c19b8
--- /dev/null
+++ b/wax-prosemirror-plugins/src/AnnotationService/tools/index.js
@@ -0,0 +1,12 @@
+export { default as Blockquote } from "./Blockquote";
+export { default as Em } from "./Em";
+export { default as Code } from "./Code";
+export { default as Link } from "./Link";
+export { default as SmallCaps } from "./SmallCaps";
+export { default as StrikeThrough } from "./StrikeThrough";
+export { default as Strong } from "./Strong";
+export { default as Subscript } from "./Subscript";
+export { default as Superscript } from "./Superscript";
+export { default as Underline } from "./Underline";
+export { default as Table } from "./Table";
+export { default as TableDropDownOptions } from "./TableDropDownOptions";
diff --git a/wax-prosemirror-plugins/src/ImageService/Image.js b/wax-prosemirror-plugins/src/ImageService/Image.js
new file mode 100644
index 000000000..cffe45b5c
--- /dev/null
+++ b/wax-prosemirror-plugins/src/ImageService/Image.js
@@ -0,0 +1,34 @@
+import React from "react";
+import { v4 as uuid } from "uuid";
+import Tools from "../lib/Tools";
+import { injectable } from "inversify";
+import { icons, ImageUpload } from "wax-prosemirror-components";
+import { canInsert } from "../lib/Utils";
+import fileUpload from "./fileUpload";
+
+@injectable()
+export default class Image extends Tools {
+  title = "Insert image";
+  content = icons.image;
+
+  get run() {
+    return () => true;
+  }
+
+  get enable() {
+    return state => {
+      return canInsert(state.config.schema.nodes.image)(state);
+    };
+  }
+
+  renderTool({ view }) {
+    const upload = fileUpload(
+      view,
+      this.config.get("fileUpload"),
+      this.pmplugins.get("placeHolder")
+    );
+    return this._isEnabled ? (
+      <ImageUpload key={uuid()} item={this.toJSON()} fileUpload={upload} />
+    ) : null;
+  }
+}
diff --git a/wax-prosemirror-plugins/src/ImageService/ImageService.js b/wax-prosemirror-plugins/src/ImageService/ImageService.js
new file mode 100644
index 000000000..b9534457d
--- /dev/null
+++ b/wax-prosemirror-plugins/src/ImageService/ImageService.js
@@ -0,0 +1,10 @@
+import Image from "./Image";
+import Service from "wax-prosemirror-core/src/services/Service";
+
+export default class ImageService extends Service {
+  name = "ImageService";
+
+  register() {
+    this.container.bind("Image").to(Image);
+  }
+}
diff --git a/wax-prosemirror-plugins/src/ImageService/fileUpload.js b/wax-prosemirror-plugins/src/ImageService/fileUpload.js
new file mode 100644
index 000000000..aa33a6a90
--- /dev/null
+++ b/wax-prosemirror-plugins/src/ImageService/fileUpload.js
@@ -0,0 +1,49 @@
+const findPlaceholder = (state, id, placeholderPlugin) => {
+  const decos = placeholderPlugin.getState(state);
+  const found = decos.find(null, null, spec => spec.id === id);
+  return found.length ? found[0].from : null;
+};
+
+export default (view, fileUpload, placeholderPlugin) => file => {
+  const { state } = view;
+
+  // A fresh object to act as the ID for this upload
+  const id = {};
+
+  // Replace the selection with a placeholder
+  const { tr } = state;
+  if (!tr.selection.empty) tr.deleteSelection();
+
+  tr.setMeta(placeholderPlugin, {
+    add: { id, pos: tr.selection.from }
+  });
+
+  view.dispatch(tr);
+  fileUpload(file).then(
+    url => {
+      const pos = findPlaceholder(view.state, id, placeholderPlugin);
+      // If the content around the placeholder has been deleted, drop
+      // the image
+      if (pos == null) {
+        return;
+      }
+      // Otherwise, insert it at the placeholder's position, and remove
+      // the placeholder
+      view.dispatch(
+        state.tr
+          .replaceWith(
+            pos,
+            pos,
+            view.state.schema.nodes.image.create({
+              src: url
+            })
+          )
+          .setMeta(placeholderPlugin, { remove: { id } })
+      );
+    },
+    () => {
+      // On failure, just clean up the placeholder
+      view.dispatch(tr.setMeta(placeholderPlugin, { remove: { id } }));
+    }
+  );
+};
diff --git a/wax-prosemirror-plugins/src/LinkService/LinkService.js b/wax-prosemirror-plugins/src/LinkService/LinkService.js
index 4574ce001..dd405e797 100644
--- a/wax-prosemirror-plugins/src/LinkService/LinkService.js
+++ b/wax-prosemirror-plugins/src/LinkService/LinkService.js
@@ -2,7 +2,6 @@ import LinkPlugin from "./LinkPlugin";
 import Service from "wax-prosemirror-core/src/services/Service";
 import find from "./pmPlugins/find";
 import placeholder from "./pmPlugins/placeholder";
-import { config } from "@fortawesome/fontawesome";
 
 export default class myLinkPluginService extends Service {
   name = "LinkPlugin";
diff --git a/wax-prosemirror-plugins/src/MenuService/Menu.js b/wax-prosemirror-plugins/src/MenuService/Menu.js
index 2848c41d2..520557a12 100644
--- a/wax-prosemirror-plugins/src/MenuService/Menu.js
+++ b/wax-prosemirror-plugins/src/MenuService/Menu.js
@@ -11,7 +11,6 @@ export default class Menu {
   constructor(config, createTools) {
     this.name = config.name;
     this.config = config;
-    console.log(this.config, "menu config");
     this.groupTools = createTools(this.config.groupTools);
 
     this.excludeIncludeTools();
diff --git a/wax-prosemirror-plugins/src/MenuService/MenuService.js b/wax-prosemirror-plugins/src/MenuService/MenuService.js
index 7afc254cd..074b315ff 100644
--- a/wax-prosemirror-plugins/src/MenuService/MenuService.js
+++ b/wax-prosemirror-plugins/src/MenuService/MenuService.js
@@ -31,17 +31,24 @@ export default class MenuService extends Service {
     this.container.bind("createTools").toFactory(context => {
       return configTools => {
         const tools = [];
+        debugger;
         configTools.forEach(tool => {
-          let tl = {};
-          if (isPlainObject(tool)) {
-            tl = context.container.get(tool.name);
-            tl.setGroupConfig(tool);
-          } else if (isFunction(tool)) {
-            tl = context.container.get(tool());
-          } else {
-            tl = context.container.get(tool);
+          try {
+            let tl = {};
+            if (isPlainObject(tool)) {
+              tl = context.container.get(tool.name);
+              tl.setGroupConfig(tool);
+            } else if (isFunction(tool)) {
+              tl = context.container.get(tool());
+            } else {
+              tl = context.container.get(tool);
+            }
+            tools.push(tl);
+          } catch (error) {
+            throw Error(
+              `Could not load Service ${tool.name}. Please configure service through config`
+            );
           }
-          tools.push(tl);
         });
         return tools;
       };
diff --git a/wax-prosemirror-plugins/src/PlaceholderService/PlaceholderService.js b/wax-prosemirror-plugins/src/PlaceholderService/PlaceholderService.js
new file mode 100644
index 000000000..691de1c17
--- /dev/null
+++ b/wax-prosemirror-plugins/src/PlaceholderService/PlaceholderService.js
@@ -0,0 +1,11 @@
+import Service from "wax-prosemirror-core/src/services/Service";
+import placeholderPlugin from "./pmPlugins/placeholderPlugin";
+const PLUGIN_KEY = "placeHolder";
+
+export default class PlaceholderService extends Service {
+  name = "PlaceholderService";
+
+  register() {
+    this.app.PmPlugins.add(PLUGIN_KEY, placeholderPlugin(PLUGIN_KEY));
+  }
+}
diff --git a/wax-prosemirror-plugins/src/PlaceholderService/pmPlugins/placeholderPlugin.js b/wax-prosemirror-plugins/src/PlaceholderService/pmPlugins/placeholderPlugin.js
new file mode 100644
index 000000000..d0918b9e0
--- /dev/null
+++ b/wax-prosemirror-plugins/src/PlaceholderService/pmPlugins/placeholderPlugin.js
@@ -0,0 +1,35 @@
+import { Plugin, PluginKey } from "prosemirror-state";
+import { Decoration, DecorationSet } from "prosemirror-view";
+
+export default key =>
+  new Plugin({
+    key: new PluginKey(key),
+    state: {
+      init: function init() {
+        return DecorationSet.empty;
+      },
+      apply: function apply(tr, set) {
+        // Adjust decoration positions to changes made by the transaction
+        set = set.map(tr.mapping, tr.doc);
+        // See if the transaction adds or removes any placeholders
+        const action = tr.getMeta(this);
+        if (action && action.add) {
+          const widget = document.createElement("placeholder");
+          const deco = Decoration.widget(action.add.pos, widget, {
+            id: action.add.id
+          });
+          set = set.add(tr.doc, [deco]);
+        } else if (action && action.remove) {
+          set = set.remove(
+            set.find(null, null, spec => spec.id === action.remove.id)
+          );
+        }
+        return set;
+      }
+    },
+    props: {
+      decorations: function decorations(state) {
+        return this.getState(state);
+      }
+    }
+  });
diff --git a/wax-prosemirror-plugins/src/TextStyleService/TextStyle.js b/wax-prosemirror-plugins/src/TextStyleService/TextStyle.js
new file mode 100644
index 000000000..553d0061a
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/TextStyle.js
@@ -0,0 +1,39 @@
+import { injectable, inject } from "inversify";
+import GroupTool from "../lib/GroupTool";
+
+@injectable()
+export default class Annotation extends GroupTool {
+  tools = [];
+  constructor(
+    @inject("Author") author,
+    @inject("EpigraphPoetry") epigraphPoetry,
+    @inject("EpigraphProse") epigraphProse,
+    @inject("Heading1") heading1,
+    @inject("Heading2") heading2,
+    @inject("Heading3") heading3,
+    @inject("Plain") plain,
+    @inject("Subtitle") subtitle,
+    @inject("Title") title
+  ) {
+    super();
+    this.tools = [
+      author,
+      epigraphPoetry,
+      epigraphProse,
+      heading1,
+      heading2,
+      heading3,
+      plain,
+      subtitle,
+      title
+    ];
+  }
+
+  renderTools(view) {
+    const tools = [];
+    this.tools.forEach(tool => {
+      tools.push(tool.renderTool(view));
+    });
+    return tools;
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/TextStyleService.js b/wax-prosemirror-plugins/src/TextStyleService/TextStyleService.js
new file mode 100644
index 000000000..a50ea79a3
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/TextStyleService.js
@@ -0,0 +1,14 @@
+import TextStyle from "./TextStyle";
+import Service from "wax-prosemirror-core/src/services/Service";
+import * as Tools from "./tools";
+
+export default class TextStyleService extends Service {
+  name = "TextStyleService";
+
+  register() {
+    this.container.bind("TextStyle").to(TextStyle);
+    Object.entries(Tools).forEach(([key, value]) => {
+      this.container.bind(key).to(value);
+    });
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/Author.js b/wax-prosemirror-plugins/src/TextStyleService/tools/Author.js
new file mode 100644
index 000000000..6be138dd8
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/Author.js
@@ -0,0 +1,21 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class Author extends Tools {
+  title = "Change to Author";
+  content = "Author";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.author)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.author)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphPoetry.js b/wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphPoetry.js
new file mode 100644
index 000000000..a778ad348
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphPoetry.js
@@ -0,0 +1,21 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class EpigraphyPoetry extends Tools {
+  title = "Change to Epigraph Poetry";
+  content = "Epigraph Poetry";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.epigraphyPoetry)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.epigraphyPoetry)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphProse.js b/wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphProse.js
new file mode 100644
index 000000000..4f51b29a1
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/EpigraphProse.js
@@ -0,0 +1,21 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class EpigraphyProse extends Tools {
+  title = "Change to Epigraph Prose";
+  content = "Epigraph Prose";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.epigraphyProse)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.epigraphyProse)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/Heading1.js b/wax-prosemirror-plugins/src/TextStyleService/tools/Heading1.js
new file mode 100644
index 000000000..8ad2dc681
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/Heading1.js
@@ -0,0 +1,27 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class Heading1 extends Tools {
+  title = "Change to heading level 1";
+  content = "Heading 1";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.heading, { level: 1 })(
+        state,
+        dispatch
+      );
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.heading, {
+        level: 1,
+        track: []
+      })(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/Heading2.js b/wax-prosemirror-plugins/src/TextStyleService/tools/Heading2.js
new file mode 100644
index 000000000..80a7b88e8
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/Heading2.js
@@ -0,0 +1,27 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class Heading2 extends Tools {
+  title = "Change to heading level 2";
+  content = "Heading 2";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.heading, { level: 2 })(
+        state,
+        dispatch
+      );
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.heading, {
+        level: 2,
+        track: []
+      })(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/Heading3.js b/wax-prosemirror-plugins/src/TextStyleService/tools/Heading3.js
new file mode 100644
index 000000000..8163289fb
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/Heading3.js
@@ -0,0 +1,27 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class Heading3 extends Tools {
+  title = "Change to heading level 3";
+  content = "Heading 3";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.heading, { level: 3 })(
+        state,
+        dispatch
+      );
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.heading, {
+        level: 3,
+        track: []
+      })(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/Plain.js b/wax-prosemirror-plugins/src/TextStyleService/tools/Plain.js
new file mode 100644
index 000000000..d985a2f0b
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/Plain.js
@@ -0,0 +1,21 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class Plain extends Tools {
+  title = "Change to General Text";
+  content = "General Text";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.paragraph)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.paragraph)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/Subtitle.js b/wax-prosemirror-plugins/src/TextStyleService/tools/Subtitle.js
new file mode 100644
index 000000000..b29ea855c
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/Subtitle.js
@@ -0,0 +1,21 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+
+@injectable()
+export default class Subtitle extends Tools {
+  title = "Change to Subtitle";
+  content = "Subtitle";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.subtitle)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.subtitle)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/Title.js b/wax-prosemirror-plugins/src/TextStyleService/tools/Title.js
new file mode 100644
index 000000000..94c85205f
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/Title.js
@@ -0,0 +1,22 @@
+import Tools from "../../lib/Tools";
+import { injectable } from "inversify";
+import { setBlockType } from "prosemirror-commands";
+import { blockActive } from "../../lib/Utils";
+
+@injectable()
+export default class Title extends Tools {
+  title = "Change to Title";
+  content = "Title";
+
+  get run() {
+    return (state, dispatch) => {
+      setBlockType(state.config.schema.nodes.title)(state, dispatch);
+    };
+  }
+
+  get enable() {
+    return state => {
+      return setBlockType(state.config.schema.nodes.title)(state);
+    };
+  }
+}
diff --git a/wax-prosemirror-plugins/src/TextStyleService/tools/index.js b/wax-prosemirror-plugins/src/TextStyleService/tools/index.js
new file mode 100644
index 000000000..52ce53fe7
--- /dev/null
+++ b/wax-prosemirror-plugins/src/TextStyleService/tools/index.js
@@ -0,0 +1,9 @@
+export { default as Author } from "./Author";
+export { default as EpigraphPoetry } from "./EpigraphPoetry";
+export { default as EpigraphProse } from "./EpigraphProse";
+export { default as Heading1 } from "./Heading1";
+export { default as Heading2 } from "./Heading2";
+export { default as Heading3 } from "./Heading3";
+export { default as Plain } from "./Plain";
+export { default as Title } from "./Title";
+export { default as Subtitle } from "./Subtitle";
diff --git a/wax-prosemirror-plugins/src/lib/GroupTool.js b/wax-prosemirror-plugins/src/lib/GroupTool.js
index 19885aaa4..0719d2215 100644
--- a/wax-prosemirror-plugins/src/lib/GroupTool.js
+++ b/wax-prosemirror-plugins/src/lib/GroupTool.js
@@ -7,23 +7,32 @@ export default class GroupTool {
   setGroupConfig(config) {
     this._config = config;
   }
+
   excludeIncludeTools() {
     const { exclude = [], include = [] } = this._config;
 
     if (include.length > 0) {
       this.tools.map(tool => {
         if (include.includes(tool.constructor.name)) {
-          tool.enable();
+          tool.enableTool();
         } else {
-          tool.disable();
+          tool.disableTool();
         }
       });
     } else {
       this.tools.map(tool => {
         if (exclude.includes(tool.constructor.name)) {
-          tool.disable();
+          tool.disableTool();
         }
       });
     }
   }
+
+  renderTools(view) {
+    const tools = [];
+    this.tools.forEach(tool => {
+      tools.push(tool.renderTool(view));
+    });
+    return tools;
+  }
 }
diff --git a/wax-prosemirror-plugins/src/lib/Tools.js b/wax-prosemirror-plugins/src/lib/Tools.js
index 79eaadb92..39827106b 100644
--- a/wax-prosemirror-plugins/src/lib/Tools.js
+++ b/wax-prosemirror-plugins/src/lib/Tools.js
@@ -1,14 +1,20 @@
 import React from "react";
 import { v4 as uuid } from "uuid";
-import { injectable } from "inversify";
+import { injectable, inject } from "inversify";
 import { Button } from "wax-prosemirror-components";
 
 @injectable()
 export default class Tools {
   title = "title";
   content = "content";
-
   _isEnabled = true;
+  config = {};
+  pmplugins = {};
+
+  constructor(@inject("Config") config, @inject("PmPlugins") pmplugins) {
+    this.config = config;
+    this.pmplugins = pmplugins;
+  }
 
   get run() {
     return true;
@@ -38,11 +44,11 @@ export default class Tools {
     ) : null;
   }
 
-  disable() {
+  disableTool() {
     this._isEnabled = false;
   }
 
-  enable() {
+  enableTool() {
     this._isEnabled = true;
   }
 }
diff --git a/wax-prosemirror-components/src/mainMenuBar/MainMenuCommands.js b/wax-prosemirror-plugins/src/lib/Utils.js
similarity index 100%
rename from wax-prosemirror-components/src/mainMenuBar/MainMenuCommands.js
rename to wax-prosemirror-plugins/src/lib/Utils.js
diff --git a/wax-prosemirror-plugins/src/menuBar/MenuBarPlugin.js b/wax-prosemirror-plugins/src/menuBar/MenuBarPlugin.js
deleted file mode 100644
index 16c434580..000000000
--- a/wax-prosemirror-plugins/src/menuBar/MenuBarPlugin.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import React from "react";
-import { Plugin, PluginKey } from "prosemirror-state";
-
-const MenuBarPlugin = ({ renderArea, menuItems, Component }) => {
-  const MenuBarKey = new PluginKey(renderArea);
-  return new Plugin({
-    key: MenuBarKey,
-    state: {
-      init() {
-        return {
-          renderArea,
-          component: props => {
-            return <Component menuItems={menuItems} {...props} />;
-          }
-        };
-      },
-      apply(tr, oldState, newState) {
-        return this.getState(newState);
-      }
-    }
-  });
-};
-
-export default MenuBarPlugin;
-- 
GitLab