diff --git a/packages/common/index.js b/packages/common/index.js
index 8353b6006ac7b7fce9f83fe0e6e3335bee42f6cc..f254e4ba780c4a90239e4936fd76830972dbbcd6 100644
--- a/packages/common/index.js
+++ b/packages/common/index.js
@@ -8,6 +8,7 @@ import {InlineNotification} from './src/inline-notification.js';
 import {Translated} from './src/translated';
 import {Translation} from './src/translation';
 import {AdapterLitElement} from './src/adapter-lit-element.js';
+import {Modal} from "./src/modal";
 
 export {EventBus, createLinkedAbortController, createTimeoutAbortSignal};
 export {getIconSVGURL, getIconCSS, Icon};
@@ -19,3 +20,4 @@ export {Translated, Translation};
 export * from './src/logger.js';
 export * from './src/utils.js';
 export {AdapterLitElement};
+export {Modal};
diff --git a/packages/common/src/i18n/de/translation.json b/packages/common/src/i18n/de/translation.json
index 51cf793c6cb4108b18d8cab47b63959663ec8590..77e2d98f7db0ea59726f31e315f991b86fe4c1f1 100644
--- a/packages/common/src/i18n/de/translation.json
+++ b/packages/common/src/i18n/de/translation.json
@@ -7,5 +7,9 @@
         "api-documentation-server": "Verbindung zum apiDocumentation API Server {{apiDocUrl}} fehlgeschlagen!",
         "error-api-server": "Verbindung zum API Server {{apiUrl}} fehlgeschlagen!",
         "error-hydra-documentation-url-not-set": "Hydra apiDocumentation URL wurden für server {{apiUrl}} nicht gesetzt!"
+    },
+
+    "dbp-modal": {
+        "close": "Schließen"
     }
 }
diff --git a/packages/common/src/i18n/en/translation.json b/packages/common/src/i18n/en/translation.json
index e1036a6580fd180af131a4c2744c8c4fef2745fb..f0d9105809fe74acde70187a7dee4af54a923157 100644
--- a/packages/common/src/i18n/en/translation.json
+++ b/packages/common/src/i18n/en/translation.json
@@ -7,5 +7,9 @@
         "api-documentation-server": "Connection to apiDocumentation server {{apiDocUrl}} failed!",
         "error-api-server": "Connection to api server {{apiUrl}} failed!",
         "error-hydra-documentation-url-not-set": "Hydra apiDocumentation url was not set for server {{apiUrl}}!"
+    },
+
+    "dbp-modal": {
+        "close": "close"
     }
 }
diff --git a/packages/common/src/micromodal.es.js b/packages/common/src/micromodal.es.js
new file mode 100644
index 0000000000000000000000000000000000000000..ce57377e51638ce65556fc1b23213378f2032e3e
--- /dev/null
+++ b/packages/common/src/micromodal.es.js
@@ -0,0 +1,515 @@
+// see https://github.com/ghosh/Micromodal/pull/351
+
+function _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+        throw new TypeError('Cannot call a class as a function');
+    }
+}
+
+function _defineProperties(target, props) {
+    for (var i = 0; i < props.length; i++) {
+        var descriptor = props[i];
+        descriptor.enumerable = descriptor.enumerable || false;
+        descriptor.configurable = true;
+        if ('value' in descriptor) descriptor.writable = true;
+        Object.defineProperty(target, descriptor.key, descriptor);
+    }
+}
+
+function _createClass(Constructor, protoProps, staticProps) {
+    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+    if (staticProps) _defineProperties(Constructor, staticProps);
+    return Constructor;
+}
+
+function _toConsumableArray(arr) {
+    return (
+        _arrayWithoutHoles(arr) ||
+        _iterableToArray(arr) ||
+        _unsupportedIterableToArray(arr) ||
+        _nonIterableSpread()
+    );
+}
+
+function _arrayWithoutHoles(arr) {
+    if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+}
+
+function _iterableToArray(iter) {
+    if (typeof Symbol !== 'undefined' && Symbol.iterator in Object(iter)) return Array.from(iter);
+}
+
+function _unsupportedIterableToArray(o, minLen) {
+    if (!o) return;
+    if (typeof o === 'string') return _arrayLikeToArray(o, minLen);
+    var n = Object.prototype.toString.call(o).slice(8, -1);
+    if (n === 'Object' && o.constructor) n = o.constructor.name;
+    if (n === 'Map' || n === 'Set') return Array.from(n);
+    if (n === 'Arguments' || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))
+        return _arrayLikeToArray(o, minLen);
+}
+
+function _arrayLikeToArray(arr, len) {
+    if (len == null || len > arr.length) len = arr.length;
+
+    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+
+    return arr2;
+}
+
+function _nonIterableSpread() {
+    throw new TypeError(
+        'Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.'
+    );
+}
+
+var MicroModal = (function () {
+    var FOCUSABLE_ELEMENTS = [
+        'a[href]',
+        'area[href]',
+        'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',
+        'select:not([disabled]):not([aria-hidden])',
+        'textarea:not([disabled]):not([aria-hidden])',
+        'button:not([disabled]):not([aria-hidden])',
+        'iframe',
+        'object',
+        'embed',
+        '[contenteditable]',
+        '[tabindex]:not([tabindex^="-"])',
+    ];
+
+    var Modal = /*#__PURE__*/ (function () {
+        function Modal(_ref) {
+            var targetModal = _ref.targetModal,
+                _ref$triggers = _ref.triggers,
+                triggers = _ref$triggers === void 0 ? [] : _ref$triggers,
+                _ref$onShow = _ref.onShow,
+                onShow = _ref$onShow === void 0 ? function () {} : _ref$onShow,
+                _ref$onClose = _ref.onClose,
+                onClose = _ref$onClose === void 0 ? function () {} : _ref$onClose,
+                _ref$openTrigger = _ref.openTrigger,
+                openTrigger =
+                    _ref$openTrigger === void 0 ? 'data-micromodal-trigger' : _ref$openTrigger,
+                _ref$closeTrigger = _ref.closeTrigger,
+                closeTrigger =
+                    _ref$closeTrigger === void 0 ? 'data-micromodal-close' : _ref$closeTrigger,
+                _ref$openClass = _ref.openClass,
+                openClass = _ref$openClass === void 0 ? 'is-open' : _ref$openClass,
+                _ref$disableScroll = _ref.disableScroll,
+                disableScroll = _ref$disableScroll === void 0 ? false : _ref$disableScroll,
+                _ref$disableFocus = _ref.disableFocus,
+                disableFocus = _ref$disableFocus === void 0 ? false : _ref$disableFocus,
+                _ref$awaitCloseAnimat = _ref.awaitCloseAnimation,
+                awaitCloseAnimation =
+                    _ref$awaitCloseAnimat === void 0 ? false : _ref$awaitCloseAnimat,
+                _ref$awaitOpenAnimati = _ref.awaitOpenAnimation,
+                awaitOpenAnimation =
+                    _ref$awaitOpenAnimati === void 0 ? false : _ref$awaitOpenAnimati,
+                _ref$debugMode = _ref.debugMode,
+                debugMode = _ref$debugMode === void 0 ? false : _ref$debugMode;
+
+            _classCallCheck(this, Modal);
+
+            // Save a reference of the modal
+            this.modal = this.modal =
+                typeof targetModal === 'string'
+                    ? document.getElementById(targetModal)
+                    : targetModal; // Save a reference to the passed config
+
+            this.config = {
+                debugMode: debugMode,
+                disableScroll: disableScroll,
+                openTrigger: openTrigger,
+                closeTrigger: closeTrigger,
+                openClass: openClass,
+                onShow: onShow,
+                onClose: onClose,
+                awaitCloseAnimation: awaitCloseAnimation,
+                awaitOpenAnimation: awaitOpenAnimation,
+                disableFocus: disableFocus,
+            }; // Register click events only if pre binding eventListeners
+
+            if (triggers.length > 0)
+                this.registerTriggers.apply(this, _toConsumableArray(triggers)); // pre bind functions for event listeners
+
+            this.onClick = this.onClick.bind(this);
+            this.onKeydown = this.onKeydown.bind(this);
+        }
+        /**
+         * Loops through all openTriggers and binds click event
+         * @param  {array} triggers [Array of node elements]
+         * @return {void}
+         */
+
+        _createClass(Modal, [
+            {
+                key: 'registerTriggers',
+                value: function registerTriggers() {
+                    var _this = this;
+
+                    for (
+                        var _len = arguments.length, triggers = new Array(_len), _key = 0;
+                        _key < _len;
+                        _key++
+                    ) {
+                        triggers[_key] = arguments[_key];
+                    }
+
+                    triggers.filter(Boolean).forEach(function (trigger) {
+                        trigger.addEventListener('click', function (event) {
+                            return _this.showModal(event);
+                        });
+                    });
+                },
+            },
+            {
+                key: 'showModal',
+                value: function showModal() {
+                    var _this2 = this;
+
+                    var event =
+                        arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
+                    this.activeElement = document.activeElement;
+                    this.modal.setAttribute('aria-hidden', 'false');
+                    this.modal.classList.add(this.config.openClass);
+                    this.scrollBehaviour('disable');
+                    this.addEventListeners();
+
+                    if (this.config.awaitOpenAnimation) {
+                        var handler = function handler() {
+                            _this2.modal.removeEventListener('animationend', handler, false);
+
+                            _this2.setFocusToFirstNode();
+                        };
+
+                        this.modal.addEventListener('animationend', handler, false);
+                    } else {
+                        this.setFocusToFirstNode();
+                    }
+
+                    this.config.onShow(this.modal, this.activeElement, event);
+                },
+            },
+            {
+                key: 'closeModal',
+                value: function closeModal() {
+                    var event =
+                        arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
+                    var modal = this.modal;
+                    this.modal.setAttribute('aria-hidden', 'true');
+                    this.removeEventListeners();
+                    this.scrollBehaviour('enable');
+
+                    if (this.activeElement && this.activeElement.focus) {
+                        this.activeElement.focus();
+                    }
+
+                    this.config.onClose(this.modal, this.activeElement, event);
+
+                    if (this.config.awaitCloseAnimation) {
+                        var openClass = this.config.openClass; // <- old school ftw
+
+                        this.modal.addEventListener(
+                            'animationend',
+                            function handler() {
+                                modal.classList.remove(openClass);
+                                modal.removeEventListener('animationend', handler, false);
+                            },
+                            false
+                        );
+                    } else {
+                        modal.classList.remove(this.config.openClass);
+                    }
+                },
+            },
+            {
+                key: 'closeModalById',
+                value: function closeModalById(targetModal) {
+                    // added support to pass on an element or an id -> for webcomponents
+                    if (targetModal instanceof HTMLElement) {
+                        this.modal = targetModal;
+                    } else {
+                        this.model = document.getElementById(targetModal);
+                    }
+                    if (this.modal) this.closeModal();
+                },
+            },
+            {
+                key: 'scrollBehaviour',
+                value: function scrollBehaviour(toggle) {
+                    if (!this.config.disableScroll) return;
+                    var body = document.querySelector('body');
+
+                    switch (toggle) {
+                        case 'enable':
+                            Object.assign(body.style, {
+                                overflow: '',
+                            });
+                            break;
+
+                        case 'disable':
+                            Object.assign(body.style, {
+                                overflow: 'hidden',
+                            });
+                            break;
+                    }
+                },
+            },
+            {
+                key: 'addEventListeners',
+                value: function addEventListeners() {
+                    this.modal.addEventListener('touchstart', this.onClick);
+                    this.modal.addEventListener('click', this.onClick);
+                    document.addEventListener('keydown', this.onKeydown);
+                },
+            },
+            {
+                key: 'removeEventListeners',
+                value: function removeEventListeners() {
+                    this.modal.removeEventListener('touchstart', this.onClick);
+                    this.modal.removeEventListener('click', this.onClick);
+                    document.removeEventListener('keydown', this.onKeydown);
+                },
+            },
+            {
+                key: 'onClick',
+                value: function onClick(event) {
+                    if (event.target.hasAttribute(this.config.closeTrigger)) {
+                        this.closeModal(event);
+                    }
+                },
+            },
+            {
+                key: 'onKeydown',
+                value: function onKeydown(event) {
+                    if (event.keyCode === 27) this.closeModal(event); // esc
+
+                    if (event.keyCode === 9) this.retainFocus(event); // tab
+                },
+            },
+            {
+                key: 'getFocusableNodes',
+                value: function getFocusableNodes() {
+                    var nodes = this.modal.querySelectorAll(FOCUSABLE_ELEMENTS);
+                    return Array.apply(void 0, _toConsumableArray(nodes));
+                },
+                /**
+                 * Tries to set focus on a node which is not a close trigger
+                 * if no other nodes exist then focuses on first close trigger
+                 */
+            },
+            {
+                key: 'setFocusToFirstNode',
+                value: function setFocusToFirstNode() {
+                    var _this3 = this;
+
+                    if (this.config.disableFocus) return;
+                    var focusableNodes = this.getFocusableNodes(); // no focusable nodes
+
+                    if (focusableNodes.length === 0) return; // remove nodes on whose click, the modal closes
+                    // could not think of a better name :(
+
+                    var nodesWhichAreNotCloseTargets = focusableNodes.filter(function (node) {
+                        return !node.hasAttribute(_this3.config.closeTrigger);
+                    });
+                    if (nodesWhichAreNotCloseTargets.length > 0)
+                        nodesWhichAreNotCloseTargets[0].focus();
+                    if (nodesWhichAreNotCloseTargets.length === 0) focusableNodes[0].focus();
+                },
+            },
+            {
+                key: 'retainFocus',
+                value: function retainFocus(event) {
+                    var focusableNodes = this.getFocusableNodes(); // no focusable nodes
+
+                    if (focusableNodes.length === 0) return;
+                    /**
+                     * Filters nodes which are hidden to prevent
+                     * focus leak outside modal
+                     */
+
+                    focusableNodes = focusableNodes.filter(function (node) {
+                        return node.offsetParent !== null;
+                    }); // if disableFocus is true
+
+                    if (!this.modal.contains(document.activeElement)) {
+                        focusableNodes[0].focus();
+                    } else {
+                        var focusedItemIndex = focusableNodes.indexOf(document.activeElement);
+
+                        if (event.shiftKey && focusedItemIndex === 0) {
+                            focusableNodes[focusableNodes.length - 1].focus();
+                            event.preventDefault();
+                        }
+
+                        if (
+                            !event.shiftKey &&
+                            focusableNodes.length > 0 &&
+                            focusedItemIndex === focusableNodes.length - 1
+                        ) {
+                            focusableNodes[0].focus();
+                            event.preventDefault();
+                        }
+                    }
+                },
+            },
+        ]);
+
+        return Modal;
+    })();
+    /**
+     * Modal prototype ends.
+     * Here on code is responsible for detecting and
+     * auto binding event handlers on modal triggers
+     */
+    // Keep a reference to the opened modal
+
+    var activeModal = null;
+    /**
+     * Generates an associative array of modals and it's
+     * respective triggers
+     * @param  {array} triggers     An array of all triggers
+     * @param  {string} triggerAttr The data-attribute which triggers the module
+     * @return {array}
+     */
+
+    var generateTriggerMap = function generateTriggerMap(triggers, triggerAttr) {
+        var triggerMap = [];
+        triggers.forEach(function (trigger) {
+            var targetModal = trigger.attributes[triggerAttr].value;
+            if (triggerMap[targetModal] === undefined) triggerMap[targetModal] = [];
+            triggerMap[targetModal].push(trigger);
+        });
+        return triggerMap;
+    };
+    /**
+     * Validates whether a modal of the given id exists
+     * in the DOM
+     * @param  {number} id  The id of the modal
+     * @return {boolean}
+     */
+
+    var validateModalPresence = function validateModalPresence(id) {
+        if (!document.getElementById(id)) {
+            console.warn(
+                "MicroModal: \u2757Seems like you have missed %c'".concat(id, "'"),
+                'background-color: #f8f9fa;color: #50596c;font-weight: bold;',
+                'ID somewhere in your code. Refer example below to resolve it.'
+            );
+            console.warn(
+                '%cExample:',
+                'background-color: #f8f9fa;color: #50596c;font-weight: bold;',
+                '<div class="modal" id="'.concat(id, '"></div>')
+            );
+            return false;
+        }
+    };
+    /**
+     * Validates if there are modal triggers present
+     * in the DOM
+     * @param  {array} triggers An array of data-triggers
+     * @return {boolean}
+     */
+
+    var validateTriggerPresence = function validateTriggerPresence(triggers) {
+        if (triggers.length <= 0) {
+            console.warn(
+                "MicroModal: \u2757Please specify at least one %c'micromodal-trigger'",
+                'background-color: #f8f9fa;color: #50596c;font-weight: bold;',
+                'data attribute.'
+            );
+            console.warn(
+                '%cExample:',
+                'background-color: #f8f9fa;color: #50596c;font-weight: bold;',
+                '<a href="#" data-micromodal-trigger="my-modal"></a>'
+            );
+            return false;
+        }
+    };
+    /**
+     * Checks if triggers and their corresponding modals
+     * are present in the DOM
+     * @param  {array} triggers   Array of DOM nodes which have data-triggers
+     * @param  {array} triggerMap Associative array of modals and their triggers
+     * @return {boolean}
+     */
+
+    var validateArgs = function validateArgs(triggers, triggerMap) {
+        validateTriggerPresence(triggers);
+        if (!triggerMap) return true;
+
+        for (var id in triggerMap) {
+            validateModalPresence(id);
+        }
+
+        return true;
+    };
+    /**
+     * Binds click handlers to all modal triggers
+     * @param  {object} config [description]
+     * @return void
+     */
+
+    var init = function init(config) {
+        // Create an config object with default openTrigger
+        var options = Object.assign(
+            {},
+            {
+                openTrigger: 'data-micromodal-trigger',
+            },
+            config
+        ); // Collects all the nodes with the trigger
+
+        var triggers = _toConsumableArray(
+            document.querySelectorAll('['.concat(options.openTrigger, ']'))
+        ); // Makes a mappings of modals with their trigger nodes
+
+        var triggerMap = generateTriggerMap(triggers, options.openTrigger); // Checks if modals and triggers exist in dom
+
+        if (options.debugMode === true && validateArgs(triggers, triggerMap) === false) return; // For every target modal creates a new instance
+
+        for (var key in triggerMap) {
+            var value = triggerMap[key];
+            options.targetModal = key;
+            options.triggers = _toConsumableArray(value);
+            activeModal = new Modal(options); // eslint-disable-line no-new
+        }
+    };
+    /**
+     * Shows a particular modal
+     * @param  {string} targetModal [The id of the modal to display]
+     * @param  {object} config [The configuration object to pass]
+     * @return {void}
+     */
+
+    var show = function show(targetModal, config) {
+        var options = config || {};
+        options.targetModal = targetModal; // Checks if modals and triggers exist in dom
+
+        if (options.debugMode === true && validateModalPresence(targetModal) === false) return; // clear events in case previous modal wasn't close
+
+        if (activeModal) activeModal.removeEventListeners(); // stores reference to active modal
+
+        activeModal = new Modal(options); // eslint-disable-line no-new
+
+        activeModal.showModal();
+    };
+    /**
+     * Closes the active modal
+     * @param  {string} targetModal [The id of the modal to close]
+     * @return {void}
+     */
+
+    var close = function close(targetModal) {
+        targetModal ? activeModal.closeModalById(targetModal) : activeModal.closeModal();
+    };
+
+    return {
+        init: init,
+        show: show,
+        close: close,
+    };
+})();
+window.MicroModal = MicroModal;
+
+export default MicroModal;
diff --git a/packages/common/src/modal.js b/packages/common/src/modal.js
new file mode 100644
index 0000000000000000000000000000000000000000..48980b25567d6be30d2e1e3a3c63d8a1ba821f9b
--- /dev/null
+++ b/packages/common/src/modal.js
@@ -0,0 +1,116 @@
+import {html, LitElement, css} from 'lit';
+import {createInstance} from './i18n';
+import * as commonStyles from '../styles.js';
+import {Icon} from "./icon";
+import {MiniSpinner} from "./mini-spinner";
+import MicroModal from './micromodal.es';
+import DBPLitElement from "../dbp-lit-element";
+
+
+export class Modal extends DBPLitElement {
+    constructor() {
+        super();
+        this._i18n = createInstance();
+        this.lang = this._i18n.language;
+        this.modalId = 'dbp-modal-id';
+        this.title = "Modal Title";
+    }
+
+    static get properties() {
+        return {
+            modalId: {type: String, attribute: 'modal-id'},
+            title: {type: String},
+        };
+    }
+
+    static get scopedElements() {
+        return {
+            'dbp-icon': Icon,
+            'dbp-mini-spinner': MiniSpinner,
+        };
+    }
+
+    open() {
+        MicroModal.show(this._('#' + this.modalId), {
+            disableScroll: true,
+            onClose: (modal) => {
+                // TODO get from parent maybe notify parent with event
+            },
+        });
+    }
+
+    static get styles() {
+        // language=css
+        return css`
+            ${commonStyles.getModalDialogCSS()}
+
+            .modal-title {
+                margin: 0;
+                padding: 0.25em 0 0 0;
+                font-weight: 300;
+            }
+            
+            .modal-container{
+                display: flex;
+                flex-direction: column;
+                justify-content: space-between;
+                padding: 15px 20px 20px;
+            }
+            
+            .modal-header{
+                padding: 0px;
+                display: flex;
+                justify-content: space-between;
+            }
+            
+            .modal-content{
+                display: flex;
+                padding-left: 0px;
+                padding-right: 0px;
+                overflow: unset;
+                gap: 1em;
+                flex-direction: column;
+                height: 100%;
+            }
+        `;
+    }
+
+    render() {
+        const i18n = this._i18n;
+
+        return html`
+            <div class="modal micromodal-slide" id="${this.modalId}" aria-hidden="true">
+                <div class="modal-overlay" tabindex="-2" data-micromodal-close>
+                    <div class="modal-container"
+                         role="dialog"
+                         aria-modal="true"
+                         aria-labelledby="show-recipient-modal-title">
+                        <header class="modal-header">
+                            <h3 class="modal-title">
+                                ${this.title}
+                            </h3>
+                            <button
+                                title="${i18n.t('dbp-modal.close')}"
+                                class="modal-close"
+                                aria-label="Close modal"
+                                @click="${() => {
+                                    MicroModal.close(this._('#' + this.modalId));
+                                }}">
+                                <dbp-icon
+                                    title="${i18n.t('dbp-modal.close')}"
+                                    name="close"
+                                    class="close-icon"></dbp-icon>
+                            </button>
+                        </header>
+                        <main class="modal-content">
+                            <slot name="content"></slot>
+                        </main>
+                        <footer class="modal-footer">
+                            <slot name="footer"></slot>
+                        </footer>
+                    </div>
+                </div>
+            </div>
+        `;
+    }
+}