diff --git a/public/smartcomponent/svg-layout-designer.html b/public/smartcomponent/svg-layout-designer.html
new file mode 100644
index 0000000..bc310ed
--- /dev/null
+++ b/public/smartcomponent/svg-layout-designer.html
@@ -0,0 +1,2 @@
+
+
diff --git a/public/smartcomponent/svg-layout-designer.ts b/public/smartcomponent/svg-layout-designer.ts
new file mode 100644
index 0000000..218d304
--- /dev/null
+++ b/public/smartcomponent/svg-layout-designer.ts
@@ -0,0 +1,67 @@
+namespace SmartBusiness.Web.Components {
+ export class SVGLayoutDesigner extends Components.ComponentBase {
+
+ public constructor(componentInfo: KnockoutComponentTypes.ComponentInfo, params: any) {
+ super(componentInfo, params);
+ // this.$component.id = SVGLayoutDesigner.generateUUID();
+ setTimeout(() => (window as any).SVGLayoutDesigner.Render(this.$component[0]));
+ this.InitEventsListener();
+ }
+
+
+ public static generateUUID() { // Public Domain/MIT
+ let d = new Date().getTime();//Timestamp
+ let d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now()*1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
+ let r = Math.random() * 16;//random number between 0 and 16
+ if(d > 0){//Use timestamp until depleted
+ r = (d + r)%16 | 0;
+ d = Math.floor(d/16);
+ } else {//Use microseconds since page-load if supported
+ r = (d2 + r)%16 | 0;
+ d2 = Math.floor(d2/16);
+ }
+ return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
+ });
+ }
+
+ public GetEditorComponent() {
+ return this.$component[0].querySelector('.Editor');
+ }
+
+ public GetCurrentHistoryState() {
+ this.GetEditorComponent().dispatchEvent(new CustomEvent('getCurrentHistoryState'));
+ }
+
+ public GetEditorState() {
+ this.GetEditorComponent().dispatchEvent(new CustomEvent('getEditorState'));
+ }
+
+ public SetEditorState(editorState: IEditorState) {
+ this.GetEditorComponent().dispatchEvent(new CustomEvent('SetEditorState', { detail: editorState }));
+ }
+
+ public AppendNewHistoryState(historyState: IHistoryState) {
+ this.GetEditorComponent().dispatchEvent(new CustomEvent('appendNewState', { detail: historyState }));
+ }
+
+ public OHistoryState: KnockoutObservable;
+
+ private InitEventsListener() {
+ this.$component[0].addEventListener('getCurrentHistoryState', (e: CustomEvent) => {
+ this.OHistoryState(e.detail);
+ console.log(this.OHistoryState());
+ });
+ this.$component[0].addEventListener('getEditorState', (e) => console.log((e as any).detail));
+ }
+ }
+
+ ko.components.register('svg-layout-designer', {
+ viewModel: {
+ createViewModel: function (params, componentInfo) {
+ return new SmartBusiness.Web.Components.SVGLayoutDesigner(componentInfo, params);
+ }
+ },
+ template: { element: 'svg-layout-designer' }
+ });
+}
\ No newline at end of file
diff --git a/public/smartcomponent/svg-layout-designer.xcomponent b/public/smartcomponent/svg-layout-designer.xcomponent
new file mode 100644
index 0000000..0bf7b1d
--- /dev/null
+++ b/public/smartcomponent/svg-layout-designer.xcomponent
@@ -0,0 +1,14 @@
+
+
+ false
+ 0A61000D-FC2D-4490-BB3E-0FAED2AF3FDC
+
+ svg-layout-designer
+
+
+ viewModel
+ ViewModel
+
+
+ svg-layout-designer
+
diff --git a/src/Components/App/App.tsx b/src/Components/App/App.tsx
index a77f8cb..6acaa8b 100644
--- a/src/Components/App/App.tsx
+++ b/src/Components/App/App.tsx
@@ -11,6 +11,7 @@ import { DEFAULT_CONFIG, DEFAULT_MAINCONTAINER_PROPS } from '../../utils/default
// App will never have props
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface IAppProps {
+ root: Element | Document
}
export const App: React.FunctionComponent = (props) => {
@@ -59,6 +60,7 @@ export const App: React.FunctionComponent = (props) => {
return (
= (props) => {
const isActiveClasses = props.isActive ? 'border-l-4 border-blue-500 bg-slate-200' : '';
return (
-