diff --git a/development/issues/closed/268.html b/development/issues/closed/268.html
new file mode 100644
index 0000000000000000000000000000000000000000..36a5b82c995dd286a90eee9d116785cbce456876
--- /dev/null
+++ b/development/issues/closed/268.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>auto activate tab after close #268</title>
+    <script src="268.mjs" type="module"></script>
+</head>
+<body>
+    <h1>auto activate tab after close #268</h1>
+    <p>When one tab is closed, another should be activated.</p>
+    <ul>
+        <li><a href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/268">Issue #268</a></li>
+        <li><a href="/">Back to overview</a></li>
+    </ul>
+    <main>
+
+          <monster-tabs data-monster-option-features-removeBehavior="auto">
+              <div data-monster-button-label="A1" data-monster-removable>test</div>
+              <div data-monster-button-label="A2" data-monster-removable>test</div>
+              <div data-monster-button-label="A3" class="active" data-monster-removable>test</div>
+              <div data-monster-button-label="A4" data-monster-removable>test</div>
+              <div data-monster-button-label="A5" data-monster-removable>test</div>
+          </monster-tabs>
+
+    </main>
+</body>
+</html>
diff --git a/development/issues/closed/268.mjs b/development/issues/closed/268.mjs
new file mode 100644
index 0000000000000000000000000000000000000000..201c5bd657796fda21cc22f34b978ae7fb6179ab
--- /dev/null
+++ b/development/issues/closed/268.mjs
@@ -0,0 +1,15 @@
+/**
+* @file development/issues/open/268.mjs
+* @url https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/268
+* @description auto activate tab after close
+* @issue 268
+*/
+
+import "../../../source/components/style/property.pcss";
+import "../../../source/components/style/link.pcss";
+import "../../../source/components/style/color.pcss";
+import "../../../source/components/style/theme.pcss";
+import "../../../source/components/style/normalize.pcss";
+import "../../../source/components/style/typography.pcss";
+import "../../../source/components/layout/tabs.mjs";
+
diff --git a/source/components/datatable/save-button.mjs b/source/components/datatable/save-button.mjs
index 6220fadf301111fb6f8f2bc4b1162a6b78ec4187..f7f8a492241e522c9b0ef873a100489d97d5ba6c 100644
--- a/source/components/datatable/save-button.mjs
+++ b/source/components/datatable/save-button.mjs
@@ -58,6 +58,9 @@ const originValuesSymbol = Symbol("originValues");
  */
 const badgeElementSymbol = Symbol("badgeElement");
 
+/**
+ *
+ */
 class SaveButton extends CustomElement {
 	/**
 	 * This method is called by the `instanceof` operator.
diff --git a/source/components/form/context-error.mjs b/source/components/form/context-error.mjs
index 561d296a981e697284e5714a17075574382d2026..a79b9831943105e535b29b05b6a65d76532f63e6 100644
--- a/source/components/form/context-error.mjs
+++ b/source/components/form/context-error.mjs
@@ -53,23 +53,12 @@ const popperElementSymbol = Symbol("popperElement");
  */
 const iconElementSymbol = Symbol("iconElement");
 
-/**
- * The ContextError control shows an error message in a popper.
- *
- * @fragments /fragments/components/form/context-error/
- *
- * @example /examples/components/form/context-error-simple
- *
- * @copyright schukai GmbH
- * @summary A control that can be used to display a tooltip or a popover with an error message.
- **/
-
 /**
  * A context error control.
  *
- * @fragments /fragments/components/form/select/
+ * @fragments /fragments/components/form/context-error
  *
- * @example /examples/components/form/select-simple
+ * @example /examples/components/form/context-error-simple
  *
  * @since 3.55.0
  * @copyright schukai GmbH
diff --git a/source/components/form/context-help.mjs b/source/components/form/context-help.mjs
index 9aea72cb56340bd237b66cfa61d0f66cec730a7c..01e7b371a24807defc82ebad0f06da5a01ca9fe8 100644
--- a/source/components/form/context-help.mjs
+++ b/source/components/form/context-help.mjs
@@ -23,7 +23,7 @@ export { ContextHelp };
 /**
  * A context help control.
  *
- * @fragments /fragments/components/form/context-help/
+ * @fragments /fragments/components/form/context-help
  *
  * @example /examples/components/form/context-help-simple
  *
diff --git a/source/components/form/password.mjs b/source/components/form/password.mjs
index 8415ffaded497c0ba44dd96c8e26ccd0d2ff64ed..b71055b7cf669d5703851587891e729bcbbc6510 100644
--- a/source/components/form/password.mjs
+++ b/source/components/form/password.mjs
@@ -50,9 +50,9 @@ export const inputElementSymbol = Symbol("inputIconElement");
 /**
  * A password field
  *
- * @fragments /fragments/components/components/form/password/
+ * @fragments /fragments/components/form/password
  *
- * @example /examples/components/components/form/password-simple
+ * @example /examples/components/form/password-simple
  *
  * @since 3.89.0
  * @copyright schukai GmbH
diff --git a/source/components/form/reload.mjs b/source/components/form/reload.mjs
index d4acf9792f18f3607f2358dad1633aa6e9979e0f..86c288af1ef0443fcfc926ec492a9635844cb0d0 100644
--- a/source/components/form/reload.mjs
+++ b/source/components/form/reload.mjs
@@ -121,7 +121,7 @@ class Reload extends CustomElement {
 	 * @property {string} url=undefined
 	 * @property {string} reload=undefined currently the values defined are `onshow` and `always`. The default `onshow` removes the IntersectionObserver. This means that the content is only loaded once. reloading of the content does not occur.
 	 * @property {string} filter=undefined dom selectors to search for elements, if undefined then everything is taken
-	 * @property {Monster.Components.Form.Processor[]} processors
+	 * @property {Object[]} processors
 	 * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
 	 * @property {String} fetch.redirect=error
 	 * @property {String} fetch.method=GET
diff --git a/source/components/form/shadow-reload.mjs b/source/components/form/shadow-reload.mjs
index 42d4f80f6273999e147a6bd6192ca7851458b5cc..f5ca623ae7d5f4d7ac3fca322d427cd09d99b5e0 100644
--- a/source/components/form/shadow-reload.mjs
+++ b/source/components/form/shadow-reload.mjs
@@ -50,7 +50,7 @@ class ShadowReload extends Reload {
 	 * @property {string} url=undefined
 	 * @property {string} reload=undefined currently the values defined are `onshow` and `always`. The default `onshow` removes the IntersectionObserver. This means that the content is only loaded once. reloading of the content does not occur.
 	 * @property {string} filter=undefined dom selectors to search for elements, if undefined then everything is taken
-	 * @property {Monster.Components.Form.Processor[]} processors
+	 * @property {Object[]} processors
 	 * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
 	 * @property {String} fetch.redirect=error
 	 * @property {String} fetch.method=GET
diff --git a/source/components/form/template.mjs b/source/components/form/template.mjs
index 860067c36b783789b2210e75e896052631afa3ed..0b1cf5b9c07f0014d78e636945821636c22a0374 100644
--- a/source/components/form/template.mjs
+++ b/source/components/form/template.mjs
@@ -40,9 +40,12 @@ const intersectionObserverWasInitialized = Symbol("wasInitialized");
 /**
  * A Template control is a control that can be used to load content from a URL and display it in the ShadowRoot.
  *
- * @fragments /fragments/components/form/template/
+ * @fragments /fragments/components/form/template
  *
  * @example /examples/components/form/template-simple
+ * @example /examples/components/form/template-with-default
+ * @example /examples/components/form/template-with-processor
+ * @example /examples/components/form/template-onshow
  *
  * @since 1.11.0
  * @copyright schukai GmbH
@@ -69,7 +72,7 @@ class Template extends CustomElement {
 	 * @property {string} templates.main Main template
 	 * @property {string} url=undefined
 	 * @property {string} reload=undefined  currently the only value defined is `onshow`. Currently the only value defined is onshow. this removes the IntersectionObserver. this means that the content is only loaded once. reloading of the content does not occur.
-	 * @property {Monster.Components.Form.Processor[]} processors
+	 * @property {Object[]} processors
 	 * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
 	 * @property {String} fetch.redirect=error
 	 * @property {String} fetch.method=GET
@@ -85,8 +88,8 @@ class Template extends CustomElement {
 				templates: {
 					main: getTemplate(),
 				},
-				url: undefined,
-				reload: undefined,
+				url: null,
+				reload: null,
 				processors: [],
 				fetch: {
 					redirect: "error",
@@ -123,8 +126,6 @@ class Template extends CustomElement {
 		this[attributeObserverSymbol][ATTRIBUTE_FORM_URL] = (url) => {
 			if (this.hasAttribute(ATTRIBUTE_FORM_URL)) {
 				this.setOption("url", new URL(url, document.location).toString());
-			} else {
-				this.setOption("url", undefined);
 			}
 		};
 	}
@@ -139,7 +140,7 @@ class Template extends CustomElement {
 	 * @throws {Error} not found
 	 * @throws {Error} undefined status or type
 	 * @fires monster-fetched
-	 * @return {Monster.Components.Form.Form}
+	 * @return {void}
 	 */
 	[assembleMethodSymbol]() {
 		super[assembleMethodSymbol]();
@@ -181,13 +182,6 @@ class Template extends CustomElement {
 	}
 }
 
-/**
- * @typedef {Object} Processor
- * @property {String} destination
- * @property {String} source
- * @since 1.11.8
- */
-
 /**
  * This attribute can be used to pass a URL to this select.
  *
@@ -237,6 +231,7 @@ function initIntersectionObserver() {
 	};
 
 	const callback = (entries, observer) => {
+
 		for (const [, entry] of entries.entries()) {
 			if (entry.isIntersecting === true) {
 				if (this.getOption("reload") === "onshow") {
@@ -276,7 +271,12 @@ function loadContent() {
 		throw new Error("no shadow-root is defined");
 	}
 
-	const url = this.getOption("url", undefined);
+	let url = this.getOption("url", undefined);
+
+	if (url instanceof URL) {
+		url = url.toString();
+	}
+
 	if (!isString(url) || url === "") {
 		throw new Error("missing url");
 	}
@@ -303,6 +303,7 @@ function loadContent() {
 	loadAndAssignContent(container, url, options)
 		.then(() => {
 			defaultSlot.style.display = "none";
+			container.style.display = "block";
 			runProcessors.call(this);
 		})
 		.catch((e) => {
@@ -316,15 +317,33 @@ function loadContent() {
  */
 function runProcessors() {
 	const processors = this.getOption("processors");
-	if (!isArray(processors)) return;
+	if (!isArray(processors)) return this;
 
 	for (const [, processor] of processors.entries()) {
 		const source = processor?.source;
-		const destination = processor?.destination;
+		let destination = processor?.destination;
+
+		if (source === null) {
+			addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "missing source");
+			continue;
+		}
+
+		if (destination === null || destination === undefined || destination === "") {
+			destination = "["+ATTRIBUTE_ROLE+"=container]";
+		}
+
 
 		if (isString(source) && isString(destination)) {
 			const sourceNode = this.shadowRoot.querySelector(source);
-			const destinationNode = document.querySelector(destination);
+			let destinationNode = document.querySelector(destination);
+
+			if (destinationNode===null) {
+				destinationNode = this.shadowRoot.querySelector(destination);
+				if (destinationNode===null) {
+					addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "destination not found");
+					continue;
+				}
+			}
 
 			if (
 				sourceNode instanceof HTMLElement &&
@@ -332,6 +351,8 @@ function runProcessors() {
 			) {
 				destinationNode.innerHTML = sourceNode.cloneNode(true).innerHTML;
 			}
+		} else {
+			addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "invalid source or destination");
 		}
 	}
 
diff --git a/source/components/form/tree-select.mjs b/source/components/form/tree-select.mjs
index d2a6db5e4a89639c5ff8735e7926de8a6d66e16e..c616459c6c61020b23b6e84df4968aeb6e8da924 100644
--- a/source/components/form/tree-select.mjs
+++ b/source/components/form/tree-select.mjs
@@ -12,33 +12,34 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import { buildTree } from "../../data/buildtree.mjs";
-import { findClosestByAttribute } from "../../dom/attributes.mjs";
+import {buildTree} from "../../data/buildtree.mjs";
+import {addAttributeToken, findClosestByAttribute} from "../../dom/attributes.mjs";
 import {
-	ATTRIBUTE_ROLE,
-	ATTRIBUTE_UPDATER_INSERT_REFERENCE,
+    ATTRIBUTE_ERRORMESSAGE,
+    ATTRIBUTE_ROLE,
+    ATTRIBUTE_UPDATER_INSERT_REFERENCE,
 } from "../../dom/constants.mjs";
-import { instanceSymbol } from "../../constants.mjs";
+import {instanceSymbol} from "../../constants.mjs";
 import {
-	assembleMethodSymbol,
-	registerCustomElement,
+    assembleMethodSymbol,
+    registerCustomElement,
 } from "../../dom/customelement.mjs";
 import {
-	findTargetElementFromEvent,
-	fireCustomEvent,
-	fireEvent,
+    findTargetElementFromEvent,
+    fireCustomEvent,
+    fireEvent,
 } from "../../dom/events.mjs";
-import { Formatter } from "../../text/formatter.mjs";
-import { isString } from "../../types/is.mjs";
-import { Node } from "../../types/node.mjs";
-import { NodeRecursiveIterator } from "../../types/noderecursiveiterator.mjs";
-import { validateInstance } from "../../types/validate.mjs";
-import { ATTRIBUTE_FORM_URL, ATTRIBUTE_INTEND } from "./constants.mjs";
-import { Select } from "./select.mjs";
-import { SelectStyleSheet } from "./stylesheet/select.mjs";
-import { TreeSelectStyleSheet } from "./stylesheet/tree-select.mjs";
-
-export { TreeSelect, formatHierarchicalSelection };
+import {Formatter} from "../../text/formatter.mjs";
+import {isString} from "../../types/is.mjs";
+import {Node} from "../../types/node.mjs";
+import {NodeRecursiveIterator} from "../../types/noderecursiveiterator.mjs";
+import {validateInstance} from "../../types/validate.mjs";
+import {ATTRIBUTE_FORM_URL, ATTRIBUTE_INTEND} from "./constants.mjs";
+import {Select} from "./select.mjs";
+import {SelectStyleSheet} from "./stylesheet/select.mjs";
+import {TreeSelectStyleSheet} from "./stylesheet/tree-select.mjs";
+
+export {TreeSelect, formatHierarchicalSelection};
 
 /**
  * @private
@@ -57,7 +58,7 @@ const keyEventHandler = Symbol("keyEventHandler");
  *
  * @fragments /fragments/components/form/tree-select
  *
- * @example /examples/components/form/tree-select
+ * @example /examples/components/form/tree-select-simple
  *
  * @since 1.9.0
  * @copyright schukai GmbH
@@ -68,136 +69,148 @@ const keyEventHandler = Symbol("keyEventHandler");
  * @fires monster-changed
  */
 class TreeSelect extends Select {
-	/**
-	 * This method is called by the `instanceof` operator.
-	 * @return {symbol}
-	 * @since 2.1.0
-	 */
-	static get [instanceSymbol]() {
-		return Symbol.for("@schukai/monster/components/form/tree-select@@instance");
-	}
-
-	/**
-	 * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
-	 * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
-	 *
-	 * The individual configuration values can be found in the table.
-	 *
-	 * @extends Select
-	 * @property {String} mapping.rootReferences=['0', undefined, null]
-	 * @property {String} mapping.idTemplate=id
-	 * @property {String} mapping.parentTemplate=parent
-	 * @property {String} mapping.selection
-	 * @property {Object} formatter
-	 * @property {String} formatter.separator=" / "
-	 */
-	get defaults() {
-		return Object.assign(
-			{},
-			super.defaults,
-			{
-				mapping: {
-					rootReferences: ["0", undefined, null],
-					idTemplate: "id",
-					parentTemplate: "parent",
-				},
-				formatter: {
-					selection: formatHierarchicalSelection,
-					separator: " / ",
-				},
-				templates: {
-					main: getTemplate(),
-				},
-			},
-			initOptionsFromArguments.call(this),
-		);
-	}
-
-	/**
-	 *
-	 * @return {string}
-	 */
-	static getTag() {
-		return "monster-tree-select";
-	}
-
-	/**
-	 *
-	 * @return {CSSStyleSheet[]}
-	 */
-	static getCSSStyleSheet() {
-		return [SelectStyleSheet, TreeSelectStyleSheet];
-	}
-
-	/**
-	 * Import Select Options from dataset
-	 * Not to be confused with the control defaults/options
-	 *
-	 * @param {array|object|Map|Set} data
-	 * @return {Select}
-	 * @throws {Error} map is not iterable
-	 */
-	importOptions(data) {
-		this[internalNodesSymbol] = new Map();
-
-		const mappingOptions = this.getOption("mapping", {});
-
-		const filter = mappingOptions?.["filter"];
-		const rootReferences = mappingOptions?.["rootReferences"];
-
-		const id = this.getOption("mapping.idTemplate", "id");
-		const parentID = this.getOption("mapping.parentTemplate", "parent");
-
-		const selector = mappingOptions?.["selector"];
-
-		const nodes = buildTree(data, selector, id, parentID, {
-			filter,
-			rootReferences,
-		});
-
-		const options = [];
-		for (const node of nodes) {
-			const iterator = new NodeRecursiveIterator(node);
-			for (const n of iterator) {
-				const formattedValues = formatKeyLabel.call(this, n);
-
-				const label = formattedValues.label;
-				const value = formattedValues.value;
-				const intend = n.level;
-
-				const visibility = intend > 0 ? "hidden" : "visible";
-				const state = "close";
-
-				this[internalNodesSymbol].set(value, n);
-
-				options.push({
-					value,
-					label,
-					intend,
-					state,
-					visibility,
-					["has-children"]: n.hasChildNodes(),
-				});
-			}
-		}
-
-		this.setOption("options", options);
-
-		fireCustomEvent(this, "monster-options-set", {
-			options,
-		});
-
-		return this;
-	}
-
-	/**
-	 *
-	 * @return {Monster.Components.Form.Select}
-	 */
-	[assembleMethodSymbol]() {
-		super[assembleMethodSymbol]();
-		initEventHandler.call(this);
-	}
+    /**
+     * This method is called by the `instanceof` operator.
+     * @return {symbol}
+     * @since 2.1.0
+     */
+    static get [instanceSymbol]() {
+        return Symbol.for("@schukai/monster/components/form/tree-select@@instance");
+    }
+
+    /**
+     * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
+     * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
+     *
+     * The individual configuration values can be found in the table.
+     *
+     * @extends Select
+     * @property {String} mapping.rootReferences=['0', undefined, null]
+     * @property {String} mapping.idTemplate=id
+     * @property {String} mapping.parentTemplate=parent
+     * @property {String} mapping.selection
+     * @property {Object} formatter
+     * @property {String} formatter.separator=" / "
+     */
+    get defaults() {
+        return Object.assign(
+            {},
+            super.defaults,
+            {
+                mapping: {
+                    rootReferences: ["0", undefined, null],
+                    id: "id",
+                    parent: "parent",
+
+                    selector: "*",
+                    labelTemplate: "",
+                    valueTemplate: "",
+                },
+                formatter: {
+                    selection: formatHierarchicalSelection,
+                    separator: " / ",
+                },
+                templates: {
+                    main: getTemplate(),
+                },
+            },
+            initOptionsFromArguments.call(this),
+        );
+    }
+
+    /**
+     *
+     * @return {string}
+     */
+    static getTag() {
+        return "monster-tree-select";
+    }
+
+    /**
+     *
+     * @return {CSSStyleSheet[]}
+     */
+    static getCSSStyleSheet() {
+        return [SelectStyleSheet, TreeSelectStyleSheet];
+    }
+
+    /**
+     * Import Select Options from dataset
+     * Not to be confused with the control defaults/options
+     *
+     * @param {array|object|Map|Set} data
+     * @return {Select}
+     * @throws {Error} map is not iterable
+     */
+    importOptions(data) {
+        this[internalNodesSymbol] = new Map();
+
+        const mappingOptions = this.getOption("mapping", {});
+
+        const filter = mappingOptions?.["filter"];
+        const rootReferences = mappingOptions?.["rootReferences"];
+
+        const id = this.getOption("mapping.id", "id");
+        const parentID = this.getOption("mapping.parent", "parent");
+
+        const selector = mappingOptions?.["selector"];
+        const options = [];
+
+        try {
+            const nodes = buildTree(data, selector, id, parentID, {
+                filter,
+                rootReferences,
+            });
+
+            for (const node of nodes) {
+                const iterator = new NodeRecursiveIterator(node);
+                for (const n of iterator) {
+
+                    const formattedValues = formatKeyLabel.call(this, n);
+
+                    const label = formattedValues.label;
+                    const value = formattedValues.value;
+                    const intend = n.level;
+
+                    const visibility = intend > 0 ? "hidden" : "visible";
+                    const state = "close";
+
+                    this[internalNodesSymbol].set(value, n);
+
+                    options.push({
+                        value,
+                        label,
+                        intend,
+                        state,
+                        visibility,
+                        ["has-children"]: n.hasChildNodes(),
+                    });
+                }
+            }
+
+            this.setOption("options", options);
+
+            fireCustomEvent(this, "monster-options-set", {
+                options,
+            });
+
+
+        } catch (e) {
+            addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e?.message || e);
+        }
+
+
+        return this;
+    }
+
+    /**
+     *
+     * @return {TreeSelect}
+     */
+    [assembleMethodSymbol]() {
+        super[assembleMethodSymbol]();
+        initEventHandler.call(this);
+    }
 }
 
 /**
@@ -205,16 +218,16 @@ class TreeSelect extends Select {
  * @param event
  */
 function handleOptionKeyboardEvents(event) {
-	switch (event?.["code"]) {
-		case "ArrowLeft":
-			closeOrOpenCurrentOption.call(this, event, "close");
-			event.preventDefault();
-			break;
-		case "ArrowRight":
-			closeOrOpenCurrentOption.call(this, event, "open");
-			event.preventDefault();
-			break;
-	}
+    switch (event?.["code"]) {
+        case "ArrowLeft":
+            closeOrOpenCurrentOption.call(this, event, "close");
+            event.preventDefault();
+            break;
+        case "ArrowRight":
+            closeOrOpenCurrentOption.call(this, event, "open");
+            event.preventDefault();
+            break;
+    }
 }
 
 /**
@@ -222,24 +235,24 @@ function handleOptionKeyboardEvents(event) {
  * @param {event} event
  */
 function closeOrOpenCurrentOption(event, mode) {
-	validateInstance(event, Event);
-
-	if (typeof event.composedPath !== "function") {
-		throw new Error("unsupported event");
-	}
-
-	const path = event.composedPath();
-	const optionNode = path.shift();
-
-	const state = optionNode.getAttribute("data-monster-state");
-	if (state !== mode) {
-		const handler = optionNode.querySelector(
-			"[data-monster-role=folder-handler]",
-		);
-		if (handler instanceof HTMLElement) {
-			fireEvent(handler, "click");
-		}
-	}
+    validateInstance(event, Event);
+
+    if (typeof event.composedPath !== "function") {
+        throw new Error("unsupported event");
+    }
+
+    const path = event.composedPath();
+    const optionNode = path.shift();
+
+    const state = optionNode.getAttribute("data-monster-state");
+    if (state !== mode) {
+        const handler = optionNode.querySelector(
+            "[data-monster-role=folder-handler]",
+        );
+        if (handler instanceof HTMLElement) {
+            fireEvent(handler, "click");
+        }
+    }
 }
 
 /**
@@ -249,19 +262,25 @@ function closeOrOpenCurrentOption(event, mode) {
  * @private
  */
 function formatKeyLabel(node) {
-	validateInstance(node, Node);
-
-	const label = new Formatter(node.value).format(
-		this.getOption("mapping.labelTemplate", ""),
-	);
-	const value = new Formatter(node.value).format(
-		this.getOption("mapping.valueTemplate", ""),
-	);
-
-	return {
-		value,
-		label,
-	};
+    validateInstance(node, Node);
+
+    const v = node.value;
+    if (v === undefined) {
+        throw new Error("the object has no value for the specified id");
+    }
+
+    const label = new Formatter(v).format(
+        this.getOption("mapping.labelTemplate", ""),
+    );
+
+    const value = new Formatter(v).format(
+        this.getOption("mapping.valueTemplate", ""),
+    );
+
+    return {
+        value,
+        label,
+    };
 }
 
 /**
@@ -270,23 +289,23 @@ function formatKeyLabel(node) {
  * @return {Array}
  */
 function buildTreeLabels(value) {
-	let node = this[internalNodesSymbol].get(value);
-	if (node === undefined) {
-		node = this[internalNodesSymbol].get(parseInt(value));
-	}
-
-	const parts = [];
-
-	if (node instanceof Node) {
-		let ptr = node;
-		while (ptr) {
-			const formattedValues = formatKeyLabel.call(this, ptr);
-			parts.unshift(formattedValues.label);
-			ptr = ptr.parent;
-		}
-	}
-
-	return parts;
+    let node = this[internalNodesSymbol].get(value);
+    if (node === undefined) {
+        node = this[internalNodesSymbol].get(parseInt(value));
+    }
+
+    const parts = [];
+
+    if (node instanceof Node) {
+        let ptr = node;
+        while (ptr) {
+            const formattedValues = formatKeyLabel.call(this, ptr);
+            parts.unshift(formattedValues.label);
+            ptr = ptr.parent;
+        }
+    }
+
+    return parts;
 }
 
 /**
@@ -304,9 +323,9 @@ function buildTreeLabels(value) {
  * @return {string}
  */
 function formatHierarchicalSelection(value) {
-	return buildTreeLabels
-		.call(this, value)
-		.join(this.getOption("formatter.separator", " / "));
+    return buildTreeLabels
+        .call(this, value)
+        .join(this.getOption("formatter.separator", " / "));
 }
 
 /**
@@ -320,99 +339,99 @@ const openOptionEventHandler = Symbol("openOptionEventHandler");
  * @throws {Error} no shadow-root is defined
  */
 function initEventHandler() {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	this[openOptionEventHandler] = (event) => {
-		const element = findTargetElementFromEvent(
-			event,
-			ATTRIBUTE_ROLE,
-			"folder-handler",
-		);
-		if (!(element instanceof HTMLElement)) {
-			return;
-		}
-
-		const container = findClosestByAttribute(element, ATTRIBUTE_ROLE, "option");
-		const index = container
-			.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
-			.split("-")
-			.pop();
-
-		const currentState = this.getOption(`options.${index}.state`);
-
-		const newState = currentState === "close" ? "open" : "close";
-		this.setOption(`options.${index}.state`, newState);
-
-		const newVisibility = newState === "open" ? "visible" : "hidden";
-
-		if (container.hasAttribute(ATTRIBUTE_INTEND)) {
-			const intend = container.getAttribute(ATTRIBUTE_INTEND);
-
-			let ref = container.nextElementSibling;
-			const childIntend = parseInt(intend) + 1;
-
-			const cmp = (a, b) => {
-				if (newState === "open") {
-					return a === b;
-				}
-
-				return a >= b;
-			};
-
-			while (
-				ref?.hasAttribute(ATTRIBUTE_INTEND) &&
-				cmp(parseInt(ref.getAttribute(ATTRIBUTE_INTEND)), childIntend)
-			) {
-				const refIndex = ref
-					.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
-					.split("-")
-					.pop();
-				this.setOption(`options.${refIndex}.visibility`, newVisibility);
-
-				if (newState === "close") {
-					this.setOption(`options.${refIndex}.state`, "close");
-				}
-
-				ref = ref.nextElementSibling;
-			}
-		}
-	};
-
-	this[keyEventHandler] = (event) => {
-		const path = event.composedPath();
-		const element = path?.[0];
-
-		let role;
-
-		if (element instanceof HTMLElement) {
-			if (element.hasAttribute(ATTRIBUTE_ROLE)) {
-				role = element.getAttribute(ATTRIBUTE_ROLE);
-			} else if (element === this) {
-				show.call(this);
-				focusFilter.call(this);
-			} else {
-				const e = element.closest(`[${ATTRIBUTE_ROLE}]`);
-				if (e instanceof HTMLElement && e.hasAttribute()) {
-					role = e.getAttribute(ATTRIBUTE_ROLE);
-				}
-			}
-		} else {
-			return;
-		}
-
-		switch (role) {
-			case "option-label":
-			case "option-control":
-			case "option":
-				handleOptionKeyboardEvents.call(this, event);
-				break;
-		}
-	};
-
-	this.shadowRoot.addEventListener("keydown", this[keyEventHandler]);
-	this.shadowRoot.addEventListener("click", this[openOptionEventHandler]);
+    if (!this.shadowRoot) {
+        throw new Error("no shadow-root is defined");
+    }
+
+    this[openOptionEventHandler] = (event) => {
+        const element = findTargetElementFromEvent(
+            event,
+            ATTRIBUTE_ROLE,
+            "folder-handler",
+        );
+        if (!(element instanceof HTMLElement)) {
+            return;
+        }
+
+        const container = findClosestByAttribute(element, ATTRIBUTE_ROLE, "option");
+        const index = container
+            .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
+            .split("-")
+            .pop();
+
+        const currentState = this.getOption(`options.${index}.state`);
+
+        const newState = currentState === "close" ? "open" : "close";
+        this.setOption(`options.${index}.state`, newState);
+
+        const newVisibility = newState === "open" ? "visible" : "hidden";
+
+        if (container.hasAttribute(ATTRIBUTE_INTEND)) {
+            const intend = container.getAttribute(ATTRIBUTE_INTEND);
+
+            let ref = container.nextElementSibling;
+            const childIntend = parseInt(intend) + 1;
+
+            const cmp = (a, b) => {
+                if (newState === "open") {
+                    return a === b;
+                }
+
+                return a >= b;
+            };
+
+            while (
+                ref?.hasAttribute(ATTRIBUTE_INTEND) &&
+                cmp(parseInt(ref.getAttribute(ATTRIBUTE_INTEND)), childIntend)
+                ) {
+                const refIndex = ref
+                    .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
+                    .split("-")
+                    .pop();
+                this.setOption(`options.${refIndex}.visibility`, newVisibility);
+
+                if (newState === "close") {
+                    this.setOption(`options.${refIndex}.state`, "close");
+                }
+
+                ref = ref.nextElementSibling;
+            }
+        }
+    };
+
+    this[keyEventHandler] = (event) => {
+        const path = event.composedPath();
+        const element = path?.[0];
+
+        let role;
+
+        if (element instanceof HTMLElement) {
+            if (element.hasAttribute(ATTRIBUTE_ROLE)) {
+                role = element.getAttribute(ATTRIBUTE_ROLE);
+            } else if (element === this) {
+                show.call(this);
+                focusFilter.call(this);
+            } else {
+                const e = element.closest(`[${ATTRIBUTE_ROLE}]`);
+                if (e instanceof HTMLElement && e.hasAttribute()) {
+                    role = e.getAttribute(ATTRIBUTE_ROLE);
+                }
+            }
+        } else {
+            return;
+        }
+
+        switch (role) {
+            case "option-label":
+            case "option-control":
+            case "option":
+                handleOptionKeyboardEvents.call(this, event);
+                break;
+        }
+    };
+
+    this.shadowRoot.addEventListener("keydown", this[keyEventHandler]);
+    this.shadowRoot.addEventListener("click", this[openOptionEventHandler]);
 }
 
 /**
@@ -426,14 +445,14 @@ function initEventHandler() {
  * @return {object}
  */
 function initOptionsFromArguments() {
-	const options = {};
+    const options = {};
 
-	const url = this.getAttribute(ATTRIBUTE_FORM_URL);
-	if (isString(url)) {
-		options["url"] = new URL(url).toString();
-	}
+    const url = this.getAttribute(ATTRIBUTE_FORM_URL);
+    if (isString(url)) {
+        options["url"] = new URL(url).toString();
+    }
 
-	return options;
+    return options;
 }
 
 /**
@@ -441,8 +460,8 @@ function initOptionsFromArguments() {
  * @return {string}
  */
 function getTemplate() {
-	// language=HTML
-	return `
+    // language=HTML
+    return `
         <template id="options">
             <div data-monster-role="option"
                  tabindex="-1"
diff --git a/source/components/layout/tabs.mjs b/source/components/layout/tabs.mjs
index 99b441a576f8dda8b7870340e3ae85e6e2ec2804..ee02a7f215e77d8bab1f860a68718f02ee965402 100644
--- a/source/components/layout/tabs.mjs
+++ b/source/components/layout/tabs.mjs
@@ -12,55 +12,55 @@
  * SPDX-License-Identifier: AGPL-3.0
  */
 
-import { instanceSymbol } from "../../constants.mjs";
-import { createPopper } from "@popperjs/core";
-import { extend } from "../../data/extend.mjs";
-import { Pathfinder } from "../../data/pathfinder.mjs";
+import {instanceSymbol} from "../../constants.mjs";
+import {createPopper} from "@popperjs/core";
+import {extend} from "../../data/extend.mjs";
+import {Pathfinder} from "../../data/pathfinder.mjs";
 import {
-	addAttributeToken,
-	addToObjectLink,
-	hasObjectLink,
+    addAttributeToken,
+    addToObjectLink,
+    hasObjectLink,
 } from "../../dom/attributes.mjs";
 import {
-	ATTRIBUTE_ERRORMESSAGE,
-	ATTRIBUTE_PREFIX,
-	ATTRIBUTE_ROLE,
+    ATTRIBUTE_ERRORMESSAGE,
+    ATTRIBUTE_PREFIX,
+    ATTRIBUTE_ROLE,
 } from "../../dom/constants.mjs";
 import {
-	assembleMethodSymbol,
-	CustomElement,
-	getSlottedElements,
-	registerCustomElement,
+    assembleMethodSymbol,
+    CustomElement,
+    getSlottedElements,
+    registerCustomElement,
 } from "../../dom/customelement.mjs";
 import {
-	findTargetElementFromEvent,
-	fireCustomEvent,
+    findTargetElementFromEvent,
+    fireCustomEvent,
 } from "../../dom/events.mjs";
-import { getDocument } from "../../dom/util.mjs";
-import { random } from "../../math/random.mjs";
-import { getGlobal } from "../../types/global.mjs";
-import { ID } from "../../types/id.mjs";
-import { isArray, isString } from "../../types/is.mjs";
-import { TokenList } from "../../types/tokenlist.mjs";
-import { clone } from "../../util/clone.mjs";
-import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
-import { Processing } from "../../util/processing.mjs";
+import {getDocument} from "../../dom/util.mjs";
+import {random} from "../../math/random.mjs";
+import {getGlobal} from "../../types/global.mjs";
+import {ID} from "../../types/id.mjs";
+import {isArray, isString} from "../../types/is.mjs";
+import {TokenList} from "../../types/tokenlist.mjs";
+import {clone} from "../../util/clone.mjs";
+import {DeadMansSwitch} from "../../util/deadmansswitch.mjs";
+import {Processing} from "../../util/processing.mjs";
 import {
-	ATTRIBUTE_BUTTON_LABEL,
-	ATTRIBUTE_FORM_RELOAD,
-	ATTRIBUTE_FORM_URL,
-	STYLE_DISPLAY_MODE_BLOCK,
+    ATTRIBUTE_BUTTON_LABEL,
+    ATTRIBUTE_FORM_RELOAD,
+    ATTRIBUTE_FORM_URL,
+    STYLE_DISPLAY_MODE_BLOCK,
 } from "../form/constants.mjs";
 
-import { TabsStyleSheet } from "./stylesheet/tabs.mjs";
-import { loadAndAssignContent } from "../form/util/fetch.mjs";
-import { ThemeStyleSheet } from "../stylesheet/theme.mjs";
+import {TabsStyleSheet} from "./stylesheet/tabs.mjs";
+import {loadAndAssignContent} from "../form/util/fetch.mjs";
+import {ThemeStyleSheet} from "../stylesheet/theme.mjs";
 import {
-	popperInstanceSymbol,
-	setEventListenersModifiers,
+    popperInstanceSymbol,
+    setEventListenersModifiers,
 } from "../form/util/popper.mjs";
 
-export { Tabs };
+export {Tabs};
 
 /**
  * @private
@@ -146,408 +146,414 @@ const resizeObserverSymbol = Symbol("resizeObserver");
  * @fragments /fragments/components/layout/tabs/
  *
  * @example /examples/components/layout/tabs-simple
+ * @example /examples/components/layout/tabs-active
+ * @example /examples/components/layout/tabs-removable
+ *
+ * @issue https://localhost.alvine.dev:8443/development/issues/closed/268.html
  *
  * @since 3.74.0
  * @copyright schukai GmbH
  * @summary This CustomControl creates a tab element with a variety of options.
  */
 class Tabs extends CustomElement {
-	/**
-	 * This method is called by the `instanceof` operator.
-	 * @return {symbol}
-	 */
-	static get [instanceSymbol]() {
-		return Symbol.for("@schukai/monster/components/layout/tabs");
-	}
-
-	/**
-	 * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
-	 * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
-	 *
-	 * The individual configuration values can be found in the table.
-	 *
-	 * @property {Object} templates Template definitions
-	 * @property {string} templates.main Main template
-	 * @property {Object} labels
-	 * @property {string} labels.new-tab-label="New Tab"
-	 * @property {Object} features
-	 * @property {number} features.openDelay=500 Open delay in milliseconds
-	 * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
-	 * @property {String} fetch.redirect=error
-	 * @property {String} fetch.method=GET
-	 * @property {String} fetch.mode=same-origin
-	 * @property {String} fetch.credentials=same-origin
-	 * @property {Object} fetch.headers={"accept":"text/html"}}
-	 * @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
-	 * @property {string} popper.placement=bottom PopperJS placement
-	 * @property {Object[]} modifiers={name:offset} PopperJS placement
-	 */
-	get defaults() {
-		return Object.assign({}, super.defaults, {
-			templates: {
-				main: getTemplate(),
-			},
-			labels: {
-				"new-tab-label": "New Tab",
-			},
-			buttons: {
-				standard: [],
-				popper: [],
-			},
-			fetch: {
-				redirect: "error",
-				method: "GET",
-				mode: "same-origin",
-				credentials: "same-origin",
-				headers: {
-					accept: "text/html",
-				},
-			},
-
-			features: {
-				openDelay: null,
-			},
-
-			classes: {
-				button: "monster-theme-primary-1",
-				popper: "monster-theme-primary-1",
-				navigation: "monster-theme-primary-1",
-			},
-
-			popper: {
-				placement: "bottom",
-				modifiers: [
-					{
-						name: "offset",
-						options: {
-							offset: [0, 2],
-						},
-					},
-
-					{
-						name: "eventListeners",
-						enabled: false,
-					},
-				],
-			},
-		});
-	}
-
-	/**
-	 * This method is called internal and should not be called directly.
-	 */
-	[assembleMethodSymbol]() {
-		super[assembleMethodSymbol]();
-
-		initControlReferences.call(this);
-
-		this[dimensionsSymbol] = new Pathfinder({ data: {} });
-
-		initEventHandler.call(this);
-
-		// setup structure
-		initTabButtons.call(this).then(() => {
-			initPopperSwitch.call(this);
-			initPopper.call(this);
-			attachResizeObserver.call(this);
-			attachTabChangeObserver.call(this);
-		});
-	}
-
-	/**
-	 * This method is called internal and should not be called directly.
-	 *
-	 * @return {CSSStyleSheet[]}
-	 */
-	static getCSSStyleSheet() {
-		return [TabsStyleSheet];
-	}
-
-	/**
-	 * This method is called internal and should not be called directly.
-	 *
-	 * @return {string}
-	 */
-	static getTag() {
-		return "monster-tabs";
-	}
-
-	/**
-	 * A function that activates a tab based on the provided name.
-	 *
-	 * The tabs have to be named with the `data-monster-name` attribute.
-	 *
-	 * @param {type} idOrName - the name or id of the tab to activate
-	 * @return {Tabs} - The current instance
-	 */
-	activeTab(idOrName) {
-		let found = false;
-
-		getSlottedElements.call(this).forEach((node) => {
-			if (found === true) {
-				return;
-			}
-
-			if (node.getAttribute("data-monster-name") === idOrName) {
-				this.shadowRoot
-					.querySelector(
-						`[data-monster-tab-reference="${node.getAttribute("id")}"]`,
-					)
-					.click();
-				found = true;
-			}
-
-			if (node.getAttribute("id") === idOrName) {
-				this.shadowRoot
-					.querySelector(
-						`[data-monster-tab-reference="${node.getAttribute("id")}"]`,
-					)
-					.click();
-				found = true;
-			}
-		});
-
-		return this;
-	}
-
-	/**
-	 * A function that returns the name or id of the currently active tab.
-	 *
-	 * The tabs have to be named with the `data-monster-name` attribute.
-	 *
-	 * @return {string|null}
-	 */
-	getActiveTab() {
-		const nodes = getSlottedElements.call(this);
-		for (const node of nodes) {
-			if (node.matches(".active") === true) {
-				if (node.hasAttribute("data-monster-name")) {
-					return node.getAttribute("data-monster-name");
-				}
-
-				return node.getAttribute("id");
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * This method is called by the dom and should not be called directly.
-	 *
-	 * @return {void}
-	 */
-	connectedCallback() {
-		super.connectedCallback();
-
-		const document = getDocument();
-
-		for (const [, type] of Object.entries(["click", "touch"])) {
-			// close on outside ui-events
-			document.addEventListener(type, this[closeEventHandler]);
-		}
-	}
-
-	/**
-	 * This method is called by the dom and should not be called directly.
-	 *
-	 * @return {void}
-	 */
-	disconnectedCallback() {
-		super.disconnectedCallback();
-
-		const document = getDocument();
-
-		// close on outside ui-events
-		for (const [, type] of Object.entries(["click", "touch"])) {
-			document.removeEventListener(type, this[closeEventHandler]);
-		}
-	}
+    /**
+     * This method is called by the `instanceof` operator.
+     * @return {symbol}
+     */
+    static get [instanceSymbol]() {
+        return Symbol.for("@schukai/monster/components/layout/tabs");
+    }
+
+    /**
+     * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
+     * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
+     *
+     * The individual configuration values can be found in the table.
+     *
+     * @property {Object} templates Template definitions
+     * @property {string} templates.main Main template
+     * @property {Object} labels
+     * @property {string} labels.new-tab-label="New Tab"
+     * @property {Object} features
+     * @property {number} features.openDelay=500 Open delay in milliseconds
+     * @property {string} features.removeBehavior="auto" Remove behavior, auto (default), next, previous and none
+     * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
+     * @property {String} fetch.redirect=error
+     * @property {String} fetch.method=GET
+     * @property {String} fetch.mode=same-origin
+     * @property {String} fetch.credentials=same-origin
+     * @property {Object} fetch.headers={"accept":"text/html"}}
+     * @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
+     * @property {string} popper.placement=bottom PopperJS placement
+     * @property {Object[]} modifiers={name:offset} PopperJS placement
+     */
+    get defaults() {
+        return Object.assign({}, super.defaults, {
+            templates: {
+                main: getTemplate(),
+            },
+            labels: {
+                "new-tab-label": "New Tab",
+            },
+            buttons: {
+                standard: [],
+                popper: [],
+            },
+            fetch: {
+                redirect: "error",
+                method: "GET",
+                mode: "same-origin",
+                credentials: "same-origin",
+                headers: {
+                    accept: "text/html",
+                },
+            },
+
+            features: {
+                openDelay: null,
+                removeBehavior: "auto",
+            },
+
+            classes: {
+                button: "monster-theme-primary-1",
+                popper: "monster-theme-primary-1",
+                navigation: "monster-theme-primary-1",
+            },
+
+            popper: {
+                placement: "bottom",
+                modifiers: [
+                    {
+                        name: "offset",
+                        options: {
+                            offset: [0, 2],
+                        },
+                    },
+
+                    {
+                        name: "eventListeners",
+                        enabled: false,
+                    },
+                ],
+            },
+        });
+    }
+
+    /**
+     * This method is called internal and should not be called directly.
+     */
+    [assembleMethodSymbol]() {
+        super[assembleMethodSymbol]();
+
+        initControlReferences.call(this);
+
+        this[dimensionsSymbol] = new Pathfinder({data: {}});
+
+        initEventHandler.call(this);
+
+        // setup structure
+        initTabButtons.call(this).then(() => {
+            initPopperSwitch.call(this);
+            initPopper.call(this);
+            attachResizeObserver.call(this);
+            attachTabChangeObserver.call(this);
+        });
+    }
+
+    /**
+     * This method is called internal and should not be called directly.
+     *
+     * @return {CSSStyleSheet[]}
+     */
+    static getCSSStyleSheet() {
+        return [TabsStyleSheet];
+    }
+
+    /**
+     * This method is called internal and should not be called directly.
+     *
+     * @return {string}
+     */
+    static getTag() {
+        return "monster-tabs";
+    }
+
+    /**
+     * A function that activates a tab based on the provided name.
+     *
+     * The tabs have to be named with the `data-monster-name` attribute.
+     *
+     * @param {type} idOrName - the name or id of the tab to activate
+     * @return {Tabs} - The current instance
+     */
+    activeTab(idOrName) {
+        let found = false;
+
+        getSlottedElements.call(this).forEach((node) => {
+            if (found === true) {
+                return;
+            }
+
+            if (node.getAttribute("data-monster-name") === idOrName) {
+                this.shadowRoot
+                    .querySelector(
+                        `[data-monster-tab-reference="${node.getAttribute("id")}"]`,
+                    )
+                    .click();
+                found = true;
+            }
+
+            if (node.getAttribute("id") === idOrName) {
+                this.shadowRoot
+                    .querySelector(
+                        `[data-monster-tab-reference="${node.getAttribute("id")}"]`,
+                    )
+                    .click();
+                found = true;
+            }
+        });
+
+        return this;
+    }
+
+    /**
+     * A function that returns the name or id of the currently active tab.
+     *
+     * The tabs have to be named with the `data-monster-name` attribute.
+     *
+     * @return {string|null}
+     */
+    getActiveTab() {
+        const nodes = getSlottedElements.call(this);
+        for (const node of nodes) {
+            if (node.matches(".active") === true) {
+                if (node.hasAttribute("data-monster-name")) {
+                    return node.getAttribute("data-monster-name");
+                }
+
+                return node.getAttribute("id");
+            }
+        }
+        return null;
+    }
+
+    /**
+     * This method is called by the dom and should not be called directly.
+     *
+     * @return {void}
+     */
+    connectedCallback() {
+        super.connectedCallback();
+
+        const document = getDocument();
+
+        for (const [, type] of Object.entries(["click", "touch"])) {
+            // close on outside ui-events
+            document.addEventListener(type, this[closeEventHandler]);
+        }
+    }
+
+    /**
+     * This method is called by the dom and should not be called directly.
+     *
+     * @return {void}
+     */
+    disconnectedCallback() {
+        super.disconnectedCallback();
+
+        const document = getDocument();
+
+        // close on outside ui-events
+        for (const [, type] of Object.entries(["click", "touch"])) {
+            document.removeEventListener(type, this[closeEventHandler]);
+        }
+    }
 }
 
 /**
  * @private
  */
 function initPopperSwitch() {
-	const nodes = getSlottedElements.call(this, `[${ATTRIBUTE_ROLE}="switch"]`); // null ↦ only unnamed slots
-	let switchButton;
-	if (nodes.size === 0) {
-		switchButton = document.createElement("button");
-		switchButton.setAttribute(ATTRIBUTE_ROLE, "switch");
-		switchButton.setAttribute("part", "switch");
-		switchButton.classList.add("hidden");
-		const classList = this.getOption("classes.button");
-		if (classList) {
-			switchButton.classList.add(classList);
-		}
-		switchButton.innerHTML =
-			'<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/></svg>';
-		this[navElementSymbol].prepend(switchButton);
-	} else {
-		switchButton = nodes.next();
-	}
-
-	/**
-	 * @param {Event} event
-	 */
-	this[popperSwitchEventHandler] = (event) => {
-		const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "switch");
-
-		if (element instanceof HTMLButtonElement) {
-			togglePopper.call(this);
-		}
-	};
-
-	for (const type of ["click", "touch"]) {
-		switchButton.addEventListener(type, this[popperSwitchEventHandler]);
-	}
-
-	this[switchElementSymbol] = switchButton;
+    const nodes = getSlottedElements.call(this, `[${ATTRIBUTE_ROLE}="switch"]`); // null ↦ only unnamed slots
+    let switchButton;
+    if (nodes.size === 0) {
+        switchButton = document.createElement("button");
+        switchButton.setAttribute(ATTRIBUTE_ROLE, "switch");
+        switchButton.setAttribute("part", "switch");
+        switchButton.classList.add("hidden");
+        const classList = this.getOption("classes.button");
+        if (classList) {
+            switchButton.classList.add(classList);
+        }
+        switchButton.innerHTML =
+            '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/></svg>';
+        this[navElementSymbol].prepend(switchButton);
+    } else {
+        switchButton = nodes.next();
+    }
+
+    /**
+     * @param {Event} event
+     */
+    this[popperSwitchEventHandler] = (event) => {
+        const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "switch");
+
+        if (element instanceof HTMLButtonElement) {
+            togglePopper.call(this);
+        }
+    };
+
+    for (const type of ["click", "touch"]) {
+        switchButton.addEventListener(type, this[popperSwitchEventHandler]);
+    }
+
+    this[switchElementSymbol] = switchButton;
 }
 
 /**
  * @private
  */
 function hidePopper() {
-	if (!this[popperInstanceSymbol]) {
-		return;
-	}
+    if (!this[popperInstanceSymbol]) {
+        return;
+    }
 
-	this[popperElementSymbol].style.display = "none";
-	// performance https://popper.js.org/docs/v2/tutorial/#performance
-	setEventListenersModifiers.call(this, false);
+    this[popperElementSymbol].style.display = "none";
+    // performance https://popper.js.org/docs/v2/tutorial/#performance
+    setEventListenersModifiers.call(this, false);
 }
 
 /**
  * @private
  */
 function showPopper() {
-	if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
-		return;
-	}
-
-	this[popperElementSymbol].style.visibility = "hidden";
-	this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
-	// performance https://popper.js.org/docs/v2/tutorial/#performance
-	setEventListenersModifiers.call(this, true);
-
-	this[popperInstanceSymbol].update();
-
-	new Processing(() => {
-		this[popperElementSymbol].style.removeProperty("visibility");
-	})
-		.run(undefined)
-		.then(() => {})
-		.catch((e) => {
-			addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
-		});
+    if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
+        return;
+    }
+
+    this[popperElementSymbol].style.visibility = "hidden";
+    this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
+    // performance https://popper.js.org/docs/v2/tutorial/#performance
+    setEventListenersModifiers.call(this, true);
+
+    this[popperInstanceSymbol].update();
+
+    new Processing(() => {
+        this[popperElementSymbol].style.removeProperty("visibility");
+    })
+        .run(undefined)
+        .then(() => {
+        })
+        .catch((e) => {
+            addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
+        });
 }
 
 /**
  * @private
  */
 function togglePopper() {
-	if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
-		hidePopper.call(this);
-	} else {
-		showPopper.call(this);
-	}
+    if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
+        hidePopper.call(this);
+    } else {
+        showPopper.call(this);
+    }
 }
 
 /**
  * @private
  */
 function attachResizeObserver() {
-	// against flickering
-	this[resizeObserverSymbol] = new ResizeObserver((entries) => {
-		if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
-			try {
-				this[timerCallbackSymbol].touch();
-				return;
-			} catch (e) {
-				delete this[timerCallbackSymbol];
-			}
-		}
-
-		this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
-			this[dimensionsSymbol].setVia("data.calculated", false);
-			checkAndRearrangeButtons.call(this);
-		});
-	});
-
-	this[resizeObserverSymbol].observe(this[navElementSymbol]);
+    // against flickering
+    this[resizeObserverSymbol] = new ResizeObserver((entries) => {
+        if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
+            try {
+                this[timerCallbackSymbol].touch();
+                return;
+            } catch (e) {
+                delete this[timerCallbackSymbol];
+            }
+        }
+
+        this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
+            this[dimensionsSymbol].setVia("data.calculated", false);
+            checkAndRearrangeButtons.call(this);
+        });
+    });
+
+    this[resizeObserverSymbol].observe(this[navElementSymbol]);
 }
 
 /**
  * @private
  */
 function attachTabChangeObserver() {
-	// against flickering
-	new MutationObserver((mutations) => {
-		let runUpdate = false;
-
-		for (const mutation of mutations) {
-			if (mutation.type === "childList") {
-				if (
-					mutation.addedNodes.length > 0 ||
-					mutation.removedNodes.length > 0
-				) {
-					runUpdate = true;
-					break;
-				}
-			}
-		}
-
-		if (runUpdate === true) {
-			this[dimensionsSymbol].setVia("data.calculated", false);
-			initTabButtons.call(this);
-		}
-	}).observe(this, {
-		childList: true,
-	});
+    // against flickering
+    new MutationObserver((mutations) => {
+        let runUpdate = false;
+
+        for (const mutation of mutations) {
+            if (mutation.type === "childList") {
+                if (
+                    mutation.addedNodes.length > 0 ||
+                    mutation.removedNodes.length > 0
+                ) {
+                    runUpdate = true;
+                    break;
+                }
+            }
+        }
+
+        if (runUpdate === true) {
+            this[dimensionsSymbol].setVia("data.calculated", false);
+            initTabButtons.call(this);
+        }
+    }).observe(this, {
+        childList: true,
+    });
 }
 
 /**
  * @private
  * @return {Select}
  * @external "external:createPopper"
- * @see {@link  Plugins}
  */
 function initPopper() {
-	const self = this;
-
-	const options = extend({}, self.getOption("popper"));
-
-	self[popperInstanceSymbol] = createPopper(
-		self[switchElementSymbol],
-		self[popperElementSymbol],
-		options,
-	);
-
-	const observer1 = new MutationObserver(function (mutations) {
-		let runUpdate = false;
-		for (const mutation of mutations) {
-			if (mutation.type === "childList") {
-				if (
-					mutation.addedNodes.length > 0 ||
-					mutation.removedNodes.length > 0
-				) {
-					runUpdate = true;
-					break;
-				}
-			}
-		}
-
-		if (runUpdate === true) {
-			self[popperInstanceSymbol].update();
-		}
-	});
-
-	observer1.observe(self[popperNavElementSymbol], {
-		childList: true,
-		subtree: true,
-	});
-
-	return self;
+    const self = this;
+
+    const options = extend({}, self.getOption("popper"));
+
+    self[popperInstanceSymbol] = createPopper(
+        self[switchElementSymbol],
+        self[popperElementSymbol],
+        options,
+    );
+
+    const observer1 = new MutationObserver(function (mutations) {
+        let runUpdate = false;
+        for (const mutation of mutations) {
+            if (mutation.type === "childList") {
+                if (
+                    mutation.addedNodes.length > 0 ||
+                    mutation.removedNodes.length > 0
+                ) {
+                    runUpdate = true;
+                    break;
+                }
+            }
+        }
+
+        if (runUpdate === true) {
+            self[popperInstanceSymbol].update();
+        }
+    });
+
+    observer1.observe(self[popperNavElementSymbol], {
+        childList: true,
+        subtree: true,
+    });
+
+    return self;
 }
 
 /**
@@ -555,172 +561,203 @@ function initPopper() {
  * @param {HTMLElement} element
  */
 function show(element) {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	const reference = element.getAttribute(`${ATTRIBUTE_PREFIX}tab-reference`);
-
-	const nodes = getSlottedElements.call(this);
-	for (const node of nodes) {
-		const id = node.getAttribute("id");
-
-		if (id === reference) {
-			node.classList.add("active");
-
-			const openDelay = parseInt(this.getOption("features.openDelay"), 10);
-
-			if (!isNaN(openDelay) && openDelay > 0) {
-				node.style.visibility = "hidden";
-
-				setTimeout(() => {
-					node.style.visibility = "visible";
-				}, openDelay);
-			}
-
-			// get all data- from button and filter out data-monster-attributes and data-monster-insert
-			const data = {};
-			const mask = [
-				"data-monster-attributes",
-				"data-monster-insert-reference",
-				"data-monster-state",
-				"data-monster-button-label",
-				"data-monster-objectlink",
-				"data-monster-role",
-			];
-
-			for (const [, attr] of Object.entries(node.attributes)) {
-				if (attr.name.startsWith("data-") && mask.indexOf(attr.name) === -1) {
-					data[attr.name] = attr.value;
-				}
-			}
-
-			if (node.hasAttribute(ATTRIBUTE_FORM_URL)) {
-				const url = node.getAttribute(ATTRIBUTE_FORM_URL);
-
-				if (
-					!node.hasAttribute(ATTRIBUTE_FORM_RELOAD) ||
-					node.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase() === "onshow"
-				) {
-					node.removeAttribute(ATTRIBUTE_FORM_URL);
-				}
-
-				const options = this.getOption("fetch", {});
-				const filter = undefined;
-				loadAndAssignContent(node, url, options, filter)
-					.then(() => {
-						fireCustomEvent(this, "monster-tab-changed", {
-							reference,
-						});
-					})
-					.catch((e) => {
-						addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
-					});
-			} else {
-				fireCustomEvent(this, "monster-tab-changed", {
-					reference,
-					data,
-				});
-			}
-		} else {
-			node.classList.remove("active");
-		}
-	}
-
-	const standardButtons = this.getOption("buttons.standard");
-	for (const index in standardButtons) {
-		const button = standardButtons[index];
-		const state = button["reference"] === reference ? "active" : "inactive";
-		this.setOption(`buttons.standard.${index}.state`, state);
-	}
-
-	const popperButton = this.getOption("buttons.popper");
-	for (const index in popperButton) {
-		const button = popperButton[index];
-		const state = button["reference"] === reference ? "active" : "inactive";
-		this.setOption(`buttons.popper.${index}.state`, state);
-	}
-
-	hidePopper.call(this);
+    if (!this.shadowRoot) {
+        throw new Error("no shadow-root is defined");
+    }
+
+    const reference = element.getAttribute(`${ATTRIBUTE_PREFIX}tab-reference`);
+
+    const nodes = getSlottedElements.call(this);
+    for (const node of nodes) {
+        const id = node.getAttribute("id");
+
+        if (id === reference) {
+            node.classList.add("active");
+
+            const openDelay = parseInt(this.getOption("features.openDelay"), 10);
+
+            if (!isNaN(openDelay) && openDelay > 0) {
+                node.style.visibility = "hidden";
+
+                setTimeout(() => {
+                    node.style.visibility = "visible";
+                }, openDelay);
+            }
+
+            // get all data- from button and filter out data-monster-attributes and data-monster-insert
+            const data = {};
+            const mask = [
+                "data-monster-attributes",
+                "data-monster-insert-reference",
+                "data-monster-state",
+                "data-monster-button-label",
+                "data-monster-objectlink",
+                "data-monster-role",
+            ];
+
+            for (const [, attr] of Object.entries(node.attributes)) {
+                if (attr.name.startsWith("data-") && mask.indexOf(attr.name) === -1) {
+                    data[attr.name] = attr.value;
+                }
+            }
+
+            if (node.hasAttribute(ATTRIBUTE_FORM_URL)) {
+                const url = node.getAttribute(ATTRIBUTE_FORM_URL);
+
+                if (
+                    !node.hasAttribute(ATTRIBUTE_FORM_RELOAD) ||
+                    node.getAttribute(ATTRIBUTE_FORM_RELOAD).toLowerCase() === "onshow"
+                ) {
+                    node.removeAttribute(ATTRIBUTE_FORM_URL);
+                }
+
+                const options = this.getOption("fetch", {});
+                const filter = undefined;
+                loadAndAssignContent(node, url, options, filter)
+                    .then(() => {
+                        fireCustomEvent(this, "monster-tab-changed", {
+                            reference,
+                        });
+                    })
+                    .catch((e) => {
+                        addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
+                    });
+            } else {
+                fireCustomEvent(this, "monster-tab-changed", {
+                    reference,
+                    data,
+                });
+            }
+        } else {
+            node.classList.remove("active");
+        }
+    }
+
+    const standardButtons = this.getOption("buttons.standard");
+    for (const index in standardButtons) {
+        const button = standardButtons[index];
+        const state = button["reference"] === reference ? "active" : "inactive";
+        this.setOption(`buttons.standard.${index}.state`, state);
+    }
+
+    const popperButton = this.getOption("buttons.popper");
+    for (const index in popperButton) {
+        const button = popperButton[index];
+        const state = button["reference"] === reference ? "active" : "inactive";
+        this.setOption(`buttons.popper.${index}.state`, state);
+    }
+
+    hidePopper.call(this);
 }
 
 /**
  * @private
  */
 function initEventHandler() {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	/**
-	 * @param {Event} event
-	 */
-	this[changeTabEventHandler] = (event) => {
-		const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "button");
-
-		if (element instanceof HTMLButtonElement && element.disabled !== true) {
-			show.call(this, element);
-		}
-	};
-
-	/**
-	 * @param {Event} event
-	 * @fires monster-tab-remove
-	 */
-	this[removeTabEventHandler] = (event) => {
-		const element = findTargetElementFromEvent(
-			event,
-			ATTRIBUTE_ROLE,
-			"remove-tab",
-		);
-
-		if (element instanceof HTMLElement) {
-			const button = findTargetElementFromEvent(
-				event,
-				ATTRIBUTE_ROLE,
-				"button",
-			);
-
-			if (button instanceof HTMLButtonElement && button.disabled !== true) {
-				const reference = button.getAttribute(
-					`${ATTRIBUTE_PREFIX}tab-reference`,
-				);
-				if (reference) {
-					const container = this.querySelector(`[id=${reference}]`);
-					if (container instanceof HTMLElement) {
-						container.remove();
-						initTabButtons.call(this);
-						fireCustomEvent(this, "monster-tab-remove", {
-							reference,
-						});
-					}
-				}
-			}
-		}
-	};
-
-	this[navElementSymbol].addEventListener("touch", this[changeTabEventHandler]);
-	this[navElementSymbol].addEventListener("click", this[changeTabEventHandler]);
-
-	this[navElementSymbol].addEventListener("touch", this[removeTabEventHandler]);
-	this[navElementSymbol].addEventListener("click", this[removeTabEventHandler]);
-
-	/**
-	 * @param {Event} event
-	 */
-	this[closeEventHandler] = (event) => {
-		const path = event.composedPath();
-
-		for (const [, element] of Object.entries(path)) {
-			if (element === this) {
-				return;
-			}
-		}
-
-		hidePopper.call(this);
-	};
-
-	return this;
+    if (!this.shadowRoot) {
+        throw new Error("no shadow-root is defined");
+    }
+
+    /**
+     * @param {Event} event
+     */
+    this[changeTabEventHandler] = (event) => {
+        const element = findTargetElementFromEvent(event, ATTRIBUTE_ROLE, "button");
+
+        if (element instanceof HTMLButtonElement && element.disabled !== true) {
+            show.call(this, element);
+        }
+    };
+
+    /**
+     * @param {Event} event
+     * @fires monster-tab-remove
+     */
+    this[removeTabEventHandler] = (event) => {
+        const element = findTargetElementFromEvent(
+            event,
+            ATTRIBUTE_ROLE,
+            "remove-tab",
+        );
+
+        if (element instanceof HTMLElement) {
+            const button = findTargetElementFromEvent(
+                event,
+                ATTRIBUTE_ROLE,
+                "button",
+            );
+
+            if (button instanceof HTMLButtonElement && button.disabled !== true) {
+                const reference = button.getAttribute(
+                    `${ATTRIBUTE_PREFIX}tab-reference`,
+                );
+
+                const previous = button.previousElementSibling;
+                const next = button.nextElementSibling;
+
+                if (reference) {
+                    const container = this.querySelector(`[id=${reference}]`);
+                    if (container instanceof HTMLElement) {
+                        container.remove();
+                        initTabButtons.call(this);
+                        fireCustomEvent(this, "monster-tab-remove", {
+                            reference,
+                        });
+                    }
+                }
+
+                switch (this.getOption("features.removeBehavior")) {
+                    case "auto":
+                        if (next instanceof HTMLButtonElement) {
+                            next.click();
+                        } else {
+                            // get previous button
+                            if (previous instanceof HTMLButtonElement) {
+                                previous.click();
+                            }
+                        }
+                        break;
+                    case "next":
+                        if (next instanceof HTMLButtonElement) {
+                            next.click();
+                        }
+                        break;
+                    case "previous":
+                        if (previous instanceof HTMLButtonElement) {
+                            previous.click();
+                        }
+                        break;
+
+                    default: // and "none"
+                        break;
+                }
+            }
+
+        }
+    };
+
+    this[navElementSymbol].addEventListener("touch", this[changeTabEventHandler]);
+    this[navElementSymbol].addEventListener("click", this[changeTabEventHandler]);
+
+    this[navElementSymbol].addEventListener("touch", this[removeTabEventHandler]);
+    this[navElementSymbol].addEventListener("click", this[removeTabEventHandler]);
+
+    /**
+     * @param {Event} event
+     */
+    this[closeEventHandler] = (event) => {
+        const path = event.composedPath();
+
+        for (const [, element] of Object.entries(path)) {
+            if (element === this) {
+                return;
+            }
+        }
+
+        hidePopper.call(this);
+    };
+
+    return this;
 }
 
 /**
@@ -728,37 +765,37 @@ function initEventHandler() {
  * @param observedNode
  */
 function attachTabMutationObserver(observedNode) {
-	const self = this;
-
-	if (hasObjectLink(observedNode, mutationObserverSymbol)) {
-		return;
-	}
-
-	/**
-	 * this construct monitors a node whether it is disabled or modified
-	 * @type {MutationObserver}
-	 */
-	const observer = new MutationObserver(function (mutations) {
-		if (isArray(mutations)) {
-			const mutation = mutations.pop();
-			if (mutation instanceof MutationRecord) {
-				initTabButtons.call(self);
-			}
-		}
-	});
-
-	observer.observe(observedNode, {
-		childList: false,
-		attributes: true,
-		subtree: false,
-		attributeFilter: [
-			"disabled",
-			ATTRIBUTE_BUTTON_LABEL,
-			`${ATTRIBUTE_PREFIX}button-icon`,
-		],
-	});
-
-	addToObjectLink(observedNode, mutationObserverSymbol, observer);
+    const self = this;
+
+    if (hasObjectLink(observedNode, mutationObserverSymbol)) {
+        return;
+    }
+
+    /**
+     * this construct monitors a node whether it is disabled or modified
+     * @type {MutationObserver}
+     */
+    const observer = new MutationObserver(function (mutations) {
+        if (isArray(mutations)) {
+            const mutation = mutations.pop();
+            if (mutation instanceof MutationRecord) {
+                initTabButtons.call(self);
+            }
+        }
+    });
+
+    observer.observe(observedNode, {
+        childList: false,
+        attributes: true,
+        subtree: false,
+        attributeFilter: [
+            "disabled",
+            ATTRIBUTE_BUTTON_LABEL,
+            `${ATTRIBUTE_PREFIX}button-icon`,
+        ],
+    });
+
+    addToObjectLink(observedNode, mutationObserverSymbol, observer);
 }
 
 /**
@@ -767,22 +804,22 @@ function attachTabMutationObserver(observedNode) {
  * @throws {Error} no shadow-root is defined
  */
 function initControlReferences() {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	this[controlElementSymbol] = this.shadowRoot.querySelector(
-		`[${ATTRIBUTE_ROLE}=control]`,
-	);
-	this[navElementSymbol] = this.shadowRoot.querySelector(
-		`nav[${ATTRIBUTE_ROLE}=nav]`,
-	);
-	this[popperElementSymbol] = this.shadowRoot.querySelector(
-		`[${ATTRIBUTE_ROLE}=popper]`,
-	);
-	this[popperNavElementSymbol] = this.shadowRoot.querySelector(
-		`[${ATTRIBUTE_ROLE}=popper-nav]`,
-	);
+    if (!this.shadowRoot) {
+        throw new Error("no shadow-root is defined");
+    }
+
+    this[controlElementSymbol] = this.shadowRoot.querySelector(
+        `[${ATTRIBUTE_ROLE}=control]`,
+    );
+    this[navElementSymbol] = this.shadowRoot.querySelector(
+        `nav[${ATTRIBUTE_ROLE}=nav]`,
+    );
+    this[popperElementSymbol] = this.shadowRoot.querySelector(
+        `[${ATTRIBUTE_ROLE}=popper]`,
+    );
+    this[popperNavElementSymbol] = this.shadowRoot.querySelector(
+        `[${ATTRIBUTE_ROLE}=popper-nav]`,
+    );
 }
 
 /**
@@ -792,101 +829,102 @@ function initControlReferences() {
  *
  */
 function initTabButtons() {
-	if (!this.shadowRoot) {
-		throw new Error("no shadow-root is defined");
-	}
-
-	let activeReference;
-
-	const dimensionsCalculated = this[dimensionsSymbol].getVia(
-		"data.calculated",
-		false,
-	);
-
-	const buttons = [];
-	const nodes = getSlottedElements.call(this, undefined, null); // null ↦ only unnamed slots
-
-	for (const node of nodes) {
-		if (!(node instanceof HTMLElement)) continue;
-		let label = getButtonLabel.call(this, node);
-
-		let reference;
-		if (node.hasAttribute("id")) {
-			reference = node.getAttribute("id");
-		}
-
-		let disabled;
-		if (node.hasAttribute("disabled") || node.disabled === true) {
-			disabled = true;
-		}
-
-		if (!reference) {
-			reference = new ID("tab").toString();
-			node.setAttribute("id", reference);
-		}
-
-		if (node.hasAttribute(`${ATTRIBUTE_PREFIX}button-icon`)) {
-			label = `<span part="label">${label}</span><img part="icon" src="${node.getAttribute(
-				`${ATTRIBUTE_PREFIX}button-icon`,
-			)}">`;
-		}
-
-		let remove = false;
-		if (node.hasAttribute(`${ATTRIBUTE_PREFIX}removable`)) {
-			remove = true;
-		}
-
-		if (node.matches(".active") === true && disabled !== true) {
-			node.classList.remove("active");
-			activeReference = reference;
-		}
-
-		const state = "";
-		const classes = dimensionsCalculated ? "" : "invisible";
-
-		buttons.push({
-			reference,
-			label,
-			state,
-			class: classes,
-			disabled,
-			remove,
-		});
-
-		attachTabMutationObserver.call(this, node);
-	}
-
-	this.setOption("buttons.standard", clone(buttons));
-	this.setOption("buttons.popper", []);
-	this.setOption("marker", random());
-
-	return adjustButtonVisibility.call(this).then(() => {
-		if (activeReference) {
-			return new Processing(() => {
-				const button = this.shadowRoot.querySelector(
-					`[${ATTRIBUTE_PREFIX}tab-reference="${activeReference}"]`,
-				);
-				if (button instanceof HTMLButtonElement && button.disabled !== true) {
-					show.call(this, button);
-				}
-			})
-				.run(undefined)
-				.then(() => {})
-				.catch((e) => {
-					addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
-				});
-		}
-
-		return Promise.resolve();
-	});
+    if (!this.shadowRoot) {
+        throw new Error("no shadow-root is defined");
+    }
+
+    let activeReference;
+
+    const dimensionsCalculated = this[dimensionsSymbol].getVia(
+        "data.calculated",
+        false,
+    );
+
+    const buttons = [];
+    const nodes = getSlottedElements.call(this, undefined, null); // null ↦ only unnamed slots
+
+    for (const node of nodes) {
+        if (!(node instanceof HTMLElement)) continue;
+        let label = getButtonLabel.call(this, node);
+
+        let reference;
+        if (node.hasAttribute("id")) {
+            reference = node.getAttribute("id");
+        }
+
+        let disabled;
+        if (node.hasAttribute("disabled") || node.disabled === true) {
+            disabled = true;
+        }
+
+        if (!reference) {
+            reference = new ID("tab").toString();
+            node.setAttribute("id", reference);
+        }
+
+        if (node.hasAttribute(`${ATTRIBUTE_PREFIX}button-icon`)) {
+            label = `<span part="label">${label}</span><img part="icon" alt="this is an icon" src="${node.getAttribute(
+                `${ATTRIBUTE_PREFIX}button-icon`,
+            )}">`;
+        }
+
+        let remove = false;
+        if (node.hasAttribute(`${ATTRIBUTE_PREFIX}removable`)) {
+            remove = true;
+        }
+
+        if (node.matches(".active") === true && disabled !== true) {
+            node.classList.remove("active");
+            activeReference = reference;
+        }
+
+        const state = "";
+        const classes = dimensionsCalculated ? "" : "invisible";
+
+        buttons.push({
+            reference,
+            label,
+            state,
+            class: classes,
+            disabled,
+            remove,
+        });
+
+        attachTabMutationObserver.call(this, node);
+    }
+
+    this.setOption("buttons.standard", clone(buttons));
+    this.setOption("buttons.popper", []);
+    this.setOption("marker", random());
+
+    return adjustButtonVisibility.call(this).then(() => {
+        if (activeReference) {
+            return new Processing(() => {
+                const button = this.shadowRoot.querySelector(
+                    `[${ATTRIBUTE_PREFIX}tab-reference="${activeReference}"]`,
+                );
+                if (button instanceof HTMLButtonElement && button.disabled !== true) {
+                    show.call(this, button);
+                }
+            })
+                .run(undefined)
+                .then(() => {
+                })
+                .catch((e) => {
+                    addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
+                });
+        }
+
+        return Promise.resolve();
+    });
 }
 
 function checkAndRearrangeButtons() {
-	if (this[dimensionsSymbol].getVia("data.calculated", false) !== true) {
-		calculateNavigationButtonsDimensions.call(this);
-	}
+    if (this[dimensionsSymbol].getVia("data.calculated", false) !== true) {
+        calculateNavigationButtonsDimensions.call(this);
+    }
 
-	rearrangeButtons.call(this);
+    rearrangeButtons.call(this);
 }
 
 /**
@@ -894,29 +932,29 @@ function checkAndRearrangeButtons() {
  * @return {Promise<unknown>}
  */
 function adjustButtonVisibility() {
-	const self = this;
+    const self = this;
 
-	return new Promise((resolve) => {
-		const observer = new MutationObserver(function (mutations) {
-			const defCount = self.getOption("buttons.standard").length;
-			const domCount = self[navElementSymbol].querySelectorAll(
-				'button[data-monster-role="button"]',
-			).length;
+    return new Promise((resolve) => {
+        const observer = new MutationObserver(function (mutations) {
+            const defCount = self.getOption("buttons.standard").length;
+            const domCount = self[navElementSymbol].querySelectorAll(
+                'button[data-monster-role="button"]',
+            ).length;
 
-			// in drawing
-			if (defCount !== domCount) return;
+            // in drawing
+            if (defCount !== domCount) return;
 
-			observer.disconnect();
+            observer.disconnect();
 
-			checkAndRearrangeButtons.call(self);
+            checkAndRearrangeButtons.call(self);
 
-			resolve();
-		});
+            resolve();
+        });
 
-		observer.observe(self[navElementSymbol], {
-			attributes: true,
-		});
-	});
+        observer.observe(self[navElementSymbol], {
+            attributes: true,
+        });
+    });
 }
 
 /**
@@ -925,17 +963,17 @@ function adjustButtonVisibility() {
  * @return {number}
  */
 function getDimValue(value) {
-	if ([undefined, null].indexOf(value) !== -1) {
-		return 0;
-	}
+    if ([undefined, null].indexOf(value) !== -1) {
+        return 0;
+    }
 
-	const valueAsInt = parseInt(value, 10);
+    const valueAsInt = parseInt(value, 10);
 
-	if (isNaN(valueAsInt)) {
-		return 0;
-	}
+    if (isNaN(valueAsInt)) {
+        return 0;
+    }
 
-	return valueAsInt;
+    return valueAsInt;
 }
 
 /**
@@ -944,18 +982,18 @@ function getDimValue(value) {
  * @return {number}
  */
 function calcBoxWidth(node) {
-	const dim = getGlobal("window").getComputedStyle(node);
-	const bounding = node.getBoundingClientRect();
-
-	return (
-		getDimValue(dim["border-left-width"]) +
-		getDimValue(dim["padding-left"]) +
-		getDimValue(dim["margin-left"]) +
-		getDimValue(bounding["width"]) +
-		getDimValue(dim["border-right-width"]) +
-		getDimValue(dim["margin-right"]) +
-		getDimValue(dim["padding-left"])
-	);
+    const dim = getGlobal("window").getComputedStyle(node);
+    const bounding = node.getBoundingClientRect();
+
+    return (
+        getDimValue(dim["border-left-width"]) +
+        getDimValue(dim["padding-left"]) +
+        getDimValue(dim["margin-left"]) +
+        getDimValue(bounding["width"]) +
+        getDimValue(dim["border-right-width"]) +
+        getDimValue(dim["margin-right"]) +
+        getDimValue(dim["padding-left"])
+    );
 }
 
 /**
@@ -963,35 +1001,35 @@ function calcBoxWidth(node) {
  * @return {Object}
  */
 function rearrangeButtons() {
-	const standardButtons = [];
-	const popperButtons = [];
-
-	let sum = 0;
-	const space = this[dimensionsSymbol].getVia("data.space");
-
-	const buttons = this.getOption("buttons.standard");
-	for (const [, button] of buttons.entries()) {
-		const ref = button?.reference;
-
-		sum += this[dimensionsSymbol].getVia(`data.button.${ref}`);
-
-		if (sum > space) {
-			popperButtons.push(clone(button));
-		} else {
-			standardButtons.push(clone(button));
-		}
-	}
-
-	this.setOption("buttons.standard", standardButtons);
-	this.setOption("buttons.popper", popperButtons);
-
-	if (this[switchElementSymbol]) {
-		if (popperButtons.length > 0) {
-			this[switchElementSymbol].classList.remove("hidden");
-		} else {
-			this[switchElementSymbol].classList.add("hidden");
-		}
-	}
+    const standardButtons = [];
+    const popperButtons = [];
+
+    let sum = 0;
+    const space = this[dimensionsSymbol].getVia("data.space");
+
+    const buttons = this.getOption("buttons.standard");
+    for (const [, button] of buttons.entries()) {
+        const ref = button?.reference;
+
+        sum += this[dimensionsSymbol].getVia(`data.button.${ref}`);
+
+        if (sum > space) {
+            popperButtons.push(clone(button));
+        } else {
+            standardButtons.push(clone(button));
+        }
+    }
+
+    this.setOption("buttons.standard", standardButtons);
+    this.setOption("buttons.popper", popperButtons);
+
+    if (this[switchElementSymbol]) {
+        if (popperButtons.length > 0) {
+            this[switchElementSymbol].classList.remove("hidden");
+        } else {
+            this[switchElementSymbol].classList.add("hidden");
+        }
+    }
 }
 
 /**
@@ -999,50 +1037,50 @@ function rearrangeButtons() {
  * @return {Object}
  */
 function calculateNavigationButtonsDimensions() {
-	const width = this[navElementSymbol].getBoundingClientRect().width;
-
-	let startEndWidth = 0;
-
-	getSlottedElements.call(this, undefined, "start").forEach((node) => {
-		startEndWidth += calcBoxWidth.call(this, node);
-	});
-
-	getSlottedElements.call(this, undefined, "end").forEach((node) => {
-		startEndWidth += calcBoxWidth.call(this, node);
-	});
-
-	this[dimensionsSymbol].setVia("data.space", width - startEndWidth - 2);
-	this[dimensionsSymbol].setVia("data.visible", !(width === 0));
-
-	const buttons = this.getOption("buttons.standard").concat(
-		this.getOption("buttons.popper"),
-	);
-
-	for (const [i, button] of buttons.entries()) {
-		const ref = button?.reference;
-		const element = this[navElementSymbol].querySelector(
-			`:scope > [${ATTRIBUTE_PREFIX}tab-reference="${ref}"]`,
-		);
-		if (!(element instanceof HTMLButtonElement)) continue;
-
-		this[dimensionsSymbol].setVia(
-			`data.button.${ref}`,
-			calcBoxWidth.call(this, element),
-		);
-		button["class"] = new TokenList(button["class"])
-			.remove("invisible")
-			.toString();
-	}
-
-	const slots = this[controlElementSymbol].querySelectorAll(
-		`nav[${ATTRIBUTE_PREFIX}role=nav] > slot.invisible, slot[${ATTRIBUTE_PREFIX}role=slot].invisible`,
-	);
-	for (const [, slot] of slots.entries()) {
-		slot.classList.remove("invisible");
-	}
-
-	this[dimensionsSymbol].setVia("data.calculated", true);
-	this.setOption("buttons.standard", clone(buttons));
+    const width = this[navElementSymbol].getBoundingClientRect().width;
+
+    let startEndWidth = 0;
+
+    getSlottedElements.call(this, undefined, "start").forEach((node) => {
+        startEndWidth += calcBoxWidth.call(this, node);
+    });
+
+    getSlottedElements.call(this, undefined, "end").forEach((node) => {
+        startEndWidth += calcBoxWidth.call(this, node);
+    });
+
+    this[dimensionsSymbol].setVia("data.space", width - startEndWidth - 2);
+    this[dimensionsSymbol].setVia("data.visible", !(width === 0));
+
+    const buttons = this.getOption("buttons.standard").concat(
+        this.getOption("buttons.popper"),
+    );
+
+    for (const [i, button] of buttons.entries()) {
+        const ref = button?.reference;
+        const element = this[navElementSymbol].querySelector(
+            `:scope > [${ATTRIBUTE_PREFIX}tab-reference="${ref}"]`,
+        );
+        if (!(element instanceof HTMLButtonElement)) continue;
+
+        this[dimensionsSymbol].setVia(
+            `data.button.${ref}`,
+            calcBoxWidth.call(this, element),
+        );
+        button["class"] = new TokenList(button["class"])
+            .remove("invisible")
+            .toString();
+    }
+
+    const slots = this[controlElementSymbol].querySelectorAll(
+        `nav[${ATTRIBUTE_PREFIX}role=nav] > slot.invisible, slot[${ATTRIBUTE_PREFIX}role=slot].invisible`,
+    );
+    for (const [, slot] of slots.entries()) {
+        slot.classList.remove("invisible");
+    }
+
+    this[dimensionsSymbol].setVia("data.calculated", true);
+    this.setOption("buttons.standard", clone(buttons));
 }
 
 /**
@@ -1051,34 +1089,34 @@ function calculateNavigationButtonsDimensions() {
  * @return {string}
  */
 function getButtonLabel(node) {
-	let label;
-	let setLabel = false;
-	if (node.hasAttribute(ATTRIBUTE_BUTTON_LABEL)) {
-		label = node.getAttribute(ATTRIBUTE_BUTTON_LABEL);
-	} else {
-		label = node.innerText;
-		setLabel = true;
-	}
-
-	if (!isString(label)) {
-		label = "";
-	}
-
-	label = label.trim();
-
-	if (label === "") {
-		label = this.getOption("labels.new-tab-label", "New Tab");
-	}
-
-	if (label.length > 100) {
-		label = `${label.substring(0, 99)}…`;
-	}
-
-	if (setLabel === true) {
-		node.setAttribute(ATTRIBUTE_BUTTON_LABEL, label);
-	}
-
-	return label;
+    let label;
+    let setLabel = false;
+    if (node.hasAttribute(ATTRIBUTE_BUTTON_LABEL)) {
+        label = node.getAttribute(ATTRIBUTE_BUTTON_LABEL);
+    } else {
+        label = node.innerText;
+        setLabel = true;
+    }
+
+    if (!isString(label)) {
+        label = "";
+    }
+
+    label = label.trim();
+
+    if (label === "") {
+        label = this.getOption("labels.new-tab-label", "New Tab");
+    }
+
+    if (label.length > 100) {
+        label = `${label.substring(0, 99)}…`;
+    }
+
+    if (setLabel === true) {
+        node.setAttribute(ATTRIBUTE_BUTTON_LABEL, label);
+    }
+
+    return label;
 }
 
 /**
@@ -1086,8 +1124,8 @@ function getButtonLabel(node) {
  * @return {string}
  */
 function getTemplate() {
-	// language=HTML
-	return `
+    // language=HTML
+    return `
         <template id="buttons">
             <button part="button"
                     data-monster-role="button"
@@ -1107,7 +1145,7 @@ function getTemplate() {
                  data-monster-insert="buttons path:buttons.standard">
                 <slot name="start" class="invisible"></slot>
                 <div data-monster-role="popper" part="popper" tabindex="-1"
-					 data-monster-attributes="class path:classes.popper">
+                     data-monster-attributes="class path:classes.popper">
                     <div data-popper-arrow></div>