diff --git a/README.md b/README.md
index a2b055fa..4fbd8a24 100644
--- a/README.md
+++ b/README.md
@@ -95,6 +95,7 @@ All fields are optional, unless otherwise stated.
- `backgroundImg` - String: Path to an optional full-screen app background image. This can be either remote (http) or local (/). Note that this will slow down initial load
- `enableFontAwesome` - Boolean: Where `true` is enabled, if left blank font-awesome will be enabled only if required by 1 or more icons
- `fontAwesomeKey` - String: If you have a font-awesome key, then you can use it here and make use of premium icons. It is a 10-digit alpha-numeric string from you're FA kit URL (e.g. `13014ae648`)
+- `customCss` - String: Raw CSS that will be applied to the page. Please minify it first.
- `theme`- String: The default theme for first load (you can change this later from the UI)
- `cssThemes` - String[]: An array of custom theme names which can be used in the theme switcher dropdown - _See **theming** below_
- `externalStyleSheet` - String or String[] - Either a URL to an external stylesheet or an array or URLs, which can be applied as themes within the UI
diff --git a/src/App.vue b/src/App.vue
index c5aad223..d6446210 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -20,11 +20,21 @@ export default {
},
data: () => ({
// pageInfo: this.getPageInfo(conf.pageInfo),
- appConfig: conf.appConfig || Defaults.appConfig,
showFooter: Defaults.visibleComponents.footer,
}),
computed: {
- pageInfo: function pi() { return this.getPageInfo(conf.pageInfo); },
+ pageInfo() {
+ return this.getPageInfo(conf.pageInfo);
+ },
+ appConfig() {
+ if (localStorage[localStorageKeys.APP_CONFIG]) {
+ return JSON.parse(localStorage[localStorageKeys.APP_CONFIG]);
+ } else if (conf.appConfig) {
+ return conf.appConfig;
+ } else {
+ return Defaults.appConfig;
+ }
+ },
},
methods: {
/* Returns either page info from the config, or default values */
@@ -53,6 +63,17 @@ export default {
}
return '';
},
+ injectCustomStyles(usersCss) {
+ const style = document.createElement('style');
+ style.textContent = usersCss;
+ document.head.append(style);
+ },
+ },
+ mounted() {
+ if (this.appConfig.customCss) {
+ const cleanedCss = this.appConfig.customCss.replace(/<\/?[^>]+(>|$)/g, '');
+ this.injectCustomStyles(cleanedCss);
+ }
},
};
diff --git a/src/components/Configuration/ConfigContainer.vue b/src/components/Configuration/ConfigContainer.vue
index fc33f100..f0dd9622 100644
--- a/src/components/Configuration/ConfigContainer.vue
+++ b/src/components/Configuration/ConfigContainer.vue
@@ -49,6 +49,9 @@
+
+
+
@@ -58,6 +61,7 @@ import JsonToYaml from '@/utils/JsonToYaml';
import { localStorageKeys, modalNames } from '@/utils/defaults';
import EditSiteMeta from '@/components/Configuration/EditSiteMeta';
import JsonEditor from '@/components/Configuration/JsonEditor';
+import CustomCssEditor from '@/components/Configuration/CustomCss';
import DownloadIcon from '@/assets/interface-icons/config-download-file.svg';
import DeleteIcon from '@/assets/interface-icons/config-delete-local.svg';
import EditIcon from '@/assets/interface-icons/config-edit-json.svg';
@@ -83,6 +87,7 @@ export default {
components: {
EditSiteMeta,
JsonEditor,
+ CustomCssEditor,
DownloadIcon,
DeleteIcon,
EditIcon,
diff --git a/src/components/Configuration/CustomCss.vue b/src/components/Configuration/CustomCss.vue
new file mode 100644
index 00000000..c3d4dd2a
--- /dev/null
+++ b/src/components/Configuration/CustomCss.vue
@@ -0,0 +1,67 @@
+
+