diff --git a/scm-ui/ui-components/.storybook/preview-body.html b/scm-ui/ui-components/.storybook/preview-body.html
deleted file mode 100644
index d2084fbba6..0000000000
--- a/scm-ui/ui-components/.storybook/preview-body.html
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/scm-ui/ui-components/src/toast/Toast.tsx b/scm-ui/ui-components/src/toast/Toast.tsx
index cbbb2c58b6..6e6b12ff51 100644
--- a/scm-ui/ui-components/src/toast/Toast.tsx
+++ b/scm-ui/ui-components/src/toast/Toast.tsx
@@ -2,14 +2,13 @@ import React, { FC } from "react";
import { createPortal } from "react-dom";
import styled from "styled-components";
import { getTheme, Themeable, ToastThemeContext, Type } from "./themes";
+import usePortalRootElement from "../usePortalRootElement";
type Props = {
type: Type;
title: string;
};
-const rootElement = document.getElementById("toastRoot");
-
const Container = styled.div`
z-index: 99999;
position: fixed;
@@ -43,8 +42,10 @@ const Title = styled.h1`
`;
const Toast: FC = ({ children, title, type }) => {
+ const rootElement = usePortalRootElement("toastRoot");
if (!rootElement) {
- throw new Error("could not find toast container #toastRoot");
+ // portal not yet ready
+ return null;
}
const theme = getTheme(type);
diff --git a/scm-ui/ui-components/src/usePortalRootElement.ts b/scm-ui/ui-components/src/usePortalRootElement.ts
new file mode 100644
index 0000000000..33925286d8
--- /dev/null
+++ b/scm-ui/ui-components/src/usePortalRootElement.ts
@@ -0,0 +1,33 @@
+import { useEffect, useState } from "react";
+
+const createElement = (id: string) => {
+ const element = document.createElement("div");
+ element.setAttribute("id", id);
+ return element;
+};
+
+const appendRootElement = (rootElement: HTMLElement) => {
+ document.body.appendChild(rootElement);
+};
+
+const usePortalRootElement = (id: string) => {
+ const [rootElement, setRootElement] = useState();
+ useEffect(() => {
+ let element = document.getElementById(id);
+ if (!element) {
+ element = createElement(id);
+ appendRootElement(element);
+ }
+ setRootElement(element);
+ return () => {
+ if (element) {
+ element.remove();
+ }
+ setRootElement(undefined);
+ };
+ }, [id]);
+
+ return rootElement;
+};
+
+export default usePortalRootElement;
diff --git a/scm-ui/ui-webapp/public/index.mustache b/scm-ui/ui-webapp/public/index.mustache
index 86193387ce..d94bc552ee 100644
--- a/scm-ui/ui-webapp/public/index.mustache
+++ b/scm-ui/ui-webapp/public/index.mustache
@@ -34,7 +34,6 @@
-