diff --git a/changelog.d/332.misc b/changelog.d/332.misc
new file mode 100644
index 00000000..5c44c978
--- /dev/null
+++ b/changelog.d/332.misc
@@ -0,0 +1 @@
+Restructure widget web components.
\ No newline at end of file
diff --git a/web/App.tsx b/web/App.tsx
index 74c59884..a7fbfbef 100644
--- a/web/App.tsx
+++ b/web/App.tsx
@@ -3,7 +3,7 @@ import { h, Component } from 'preact';
import WA from 'matrix-widget-api';
import BridgeAPI, { BridgeAPIError } from './BridgeAPI';
import { BridgeRoomState } from '../src/Widgets/BridgeWidgetInterface';
-import ErrorPane from './components/ErrorPane';
+import ErrorPane from './components/elements';
import AdminSettings from './components/AdminSettings';
import RoomConfigView from './components/RoomConfigView';
diff --git a/web/components/configs/GeneralConfig.tsx b/web/components/configs/GeneralConfig.tsx
index ddd40f20..f0c79660 100644
--- a/web/components/configs/GeneralConfig.tsx
+++ b/web/components/configs/GeneralConfig.tsx
@@ -1,5 +1,5 @@
import { h } from "preact";
-import { Button } from "../Button";
+import { Button } from "../elements";
export default function GeneralConfig() {
return
diff --git a/web/components/Button.module.scss b/web/components/elements/Button.module.scss
similarity index 100%
rename from web/components/Button.module.scss
rename to web/components/elements/Button.module.scss
diff --git a/web/components/Button.tsx b/web/components/elements/Button.tsx
similarity index 61%
rename from web/components/Button.tsx
rename to web/components/elements/Button.tsx
index 4cdf8361..f0f6e2f0 100644
--- a/web/components/Button.tsx
+++ b/web/components/elements/Button.tsx
@@ -1,7 +1,7 @@
-import { h } from "preact";
+import { FunctionComponent, h } from "preact";
import style from "./Button.module.scss";
-export function Button(props: { [key: string]: unknown, intent?: string}) {
+export const Button: FunctionComponent = (props: { [key: string]: unknown, intent?: string}) => {
let className = style.button;
if (props.intent === "remove") {
className += ` ${ style.remove}`;
diff --git a/web/components/ButtonSet.module.scss b/web/components/elements/ButtonSet.module.scss
similarity index 100%
rename from web/components/ButtonSet.module.scss
rename to web/components/elements/ButtonSet.module.scss
diff --git a/web/components/ButtonSet.tsx b/web/components/elements/ButtonSet.tsx
similarity index 69%
rename from web/components/ButtonSet.tsx
rename to web/components/elements/ButtonSet.tsx
index 2ad1b0a9..b6bc1087 100644
--- a/web/components/ButtonSet.tsx
+++ b/web/components/elements/ButtonSet.tsx
@@ -1,9 +1,8 @@
import { FunctionComponent, h } from "preact";
import style from "./ButtonSet.module.scss";
-const ButtonSet: FunctionComponent = (props) => {
+export const ButtonSet: FunctionComponent = (props) => {
return
{props.children}
;
-}
-export default ButtonSet;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/web/components/ErrorPane.css b/web/components/elements/ErrorPane.css
similarity index 100%
rename from web/components/ErrorPane.css
rename to web/components/elements/ErrorPane.css
diff --git a/web/components/ErrorPane.tsx b/web/components/elements/ErrorPane.tsx
similarity index 66%
rename from web/components/ErrorPane.tsx
rename to web/components/elements/ErrorPane.tsx
index 7e75cea5..4b4af6bd 100644
--- a/web/components/ErrorPane.tsx
+++ b/web/components/elements/ErrorPane.tsx
@@ -1,11 +1,9 @@
import { h, FunctionComponent } from "preact";
import "./ErrorPane.css";
-const ErrorPane: FunctionComponent<{header?: string}> = ({ children, header }) => {
+export const ErrorPane: FunctionComponent<{header?: string}> = ({ children, header }) => {
return
{ header || "Error occured during widget load" }
{children}
;
-};
-
-export default ErrorPane;
\ No newline at end of file
+};
\ No newline at end of file
diff --git a/web/components/InputField.module.scss b/web/components/elements/InputField.module.scss
similarity index 100%
rename from web/components/InputField.module.scss
rename to web/components/elements/InputField.module.scss
diff --git a/web/components/InputField.tsx b/web/components/elements/InputField.tsx
similarity index 73%
rename from web/components/InputField.tsx
rename to web/components/elements/InputField.tsx
index 2aae792d..f00952e8 100644
--- a/web/components/InputField.tsx
+++ b/web/components/elements/InputField.tsx
@@ -7,11 +7,9 @@ interface Props {
noPadding: boolean;
}
-const InputField: FunctionComponent
= ({ children, visible = true, label, noPadding }) => {
+export const InputField: FunctionComponent = ({ children, visible = true, label, noPadding }) => {
return visible &&
{label && }
{children}
;
-};
-
-export default InputField;
\ No newline at end of file
+};
\ No newline at end of file
diff --git a/web/components/ListItem.module.scss b/web/components/elements/ListItem.module.scss
similarity index 100%
rename from web/components/ListItem.module.scss
rename to web/components/elements/ListItem.module.scss
diff --git a/web/components/ListItem.tsx b/web/components/elements/ListItem.tsx
similarity index 100%
rename from web/components/ListItem.tsx
rename to web/components/elements/ListItem.tsx
diff --git a/web/components/elements/index.ts b/web/components/elements/index.ts
new file mode 100644
index 00000000..db676c55
--- /dev/null
+++ b/web/components/elements/index.ts
@@ -0,0 +1,5 @@
+export * from "./Button";
+export * from "./ButtonSet";
+export * from "./ErrorPane";
+export * from "./InputField";
+export * from "./ListItem";
\ No newline at end of file
diff --git a/web/components/roomConfig/GenericWebhookConfig.tsx b/web/components/roomConfig/GenericWebhookConfig.tsx
index cc863be0..1a2bda69 100644
--- a/web/components/roomConfig/GenericWebhookConfig.tsx
+++ b/web/components/roomConfig/GenericWebhookConfig.tsx
@@ -2,12 +2,10 @@ import { h, FunctionComponent, createRef } from "preact";
import { useCallback, useState } from "preact/hooks"
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
-import { Button } from "../Button";
import BridgeAPI from "../../BridgeAPI";
import { GenericHookConnectionState, GenericHookResponseItem } from "../../../src/Connections/GenericHook";
import { ConnectionConfigurationProps, RoomConfig } from "./RoomConfig";
-import InputField from "../InputField";
-import ButtonSet from "../ButtonSet";
+import { InputField, ButtonSet, Button } from "../elements";
const EXAMPLE_SCRIPT = `if (data.counter === undefined) {
result = {
diff --git a/web/components/roomConfig/GitlabRepoConfig.tsx b/web/components/roomConfig/GitlabRepoConfig.tsx
index b491a4eb..5fe77bf2 100644
--- a/web/components/roomConfig/GitlabRepoConfig.tsx
+++ b/web/components/roomConfig/GitlabRepoConfig.tsx
@@ -3,10 +3,7 @@ import { useState, useCallback, useEffect, useMemo } from "preact/hooks";
import BridgeAPI from "../../BridgeAPI";
import { ConnectionConfigurationProps, RoomConfig } from "./RoomConfig";
import { GitLabRepoConnectionState, GitLabRepoResponseItem, GitLabTargetFilter, GitLabRepoConnectionTarget, GitLabRepoConnectionProjectTarget, GitLabRepoConnectionInstanceTarget } from "../../../src/Connections/GitlabRepo";
-import InputField from "../InputField";
-import ButtonSet from "../ButtonSet";
-import { Button } from "../Button";
-import ErrorPane from "../ErrorPane";
+import { InputField, ButtonSet, Button, ErrorPane } from "../elements";
const EventType = "uk.half-shot.matrix-hookshot.gitlab.repository";
diff --git a/web/components/roomConfig/RoomConfig.tsx b/web/components/roomConfig/RoomConfig.tsx
index bcf4a4b6..52343c08 100644
--- a/web/components/roomConfig/RoomConfig.tsx
+++ b/web/components/roomConfig/RoomConfig.tsx
@@ -1,8 +1,7 @@
import { h, FunctionComponent } from "preact";
import { useCallback, useEffect, useReducer, useState } from "preact/hooks"
-import { ListItem } from "../ListItem";
import BridgeAPI from "../../BridgeAPI";
-import ErrorPane from "../ErrorPane";
+import { ErrorPane, ListItem } from "../elements";
import style from "./RoomConfig.module.scss";
import { GetConnectionsResponseItem } from "../../../src/provisioning/api";