]> BookStack Code Mirror - bookstack/commitdiff
Update JS to show live changes and set light color values
authorDan Brown <redacted>
Sat, 28 Jan 2023 17:11:15 +0000 (17:11 +0000)
committerDan Brown <redacted>
Sat, 28 Jan 2023 17:11:15 +0000 (17:11 +0000)
app/Config/setting-defaults.php
resources/js/components/index.js
resources/js/components/setting-app-color-picker.js [deleted file]
resources/js/components/setting-app-color-scheme.js [new file with mode: 0644]
resources/js/components/setting-color-picker.js
resources/js/components/tabs.js
resources/js/services/util.js
resources/views/common/custom-styles.blade.php
resources/views/settings/customization.blade.php
resources/views/settings/parts/setting-color-scheme.blade.php

index 005fddfd03b74b033761b55bfde9b906049295fa..88c4612ca61195944835fc5611ca6c05a3b64afb 100644 (file)
@@ -24,7 +24,7 @@ return [
     'page-draft-color'     => '#7e50b1',
     'app-color-dark'       => '#195785',
     'app-color-light-dark' => 'rgba(32,110,167,0.15)',
-    'link-color-dark'      => '#195785',
+    'link-color-dark'      => '#429fe3',
     'bookshelf-color-dark' => '#ff5454',
     'book-color-dark'      => '#389f60',
     'chapter-color-dark'   => '#ee7a2d',
index 27bce48dbb3d0354ac0dfde6961cd9e7c410974e..82136184b4eaa84f5095c3fe85fd1b457bb5d592 100644 (file)
@@ -41,7 +41,7 @@ export {PagePicker} from "./page-picker.js"
 export {PermissionsTable} from "./permissions-table.js"
 export {Pointer} from "./pointer.js"
 export {Popup} from "./popup.js"
-export {SettingAppColorPicker} from "./setting-app-color-picker.js"
+export {SettingAppColorScheme} from "./setting-app-color-scheme.js"
 export {SettingColorPicker} from "./setting-color-picker.js"
 export {SettingHomepageControl} from "./setting-homepage-control.js"
 export {ShelfSort} from "./shelf-sort.js"
diff --git a/resources/js/components/setting-app-color-picker.js b/resources/js/components/setting-app-color-picker.js
deleted file mode 100644 (file)
index f167e5f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-import {Component} from "./component";
-
-export class SettingAppColorPicker extends Component {
-
-    setup() {
-        // TODO
-        this.colorInput = this.$refs.input;
-        this.lightColorInput = this.$refs.lightInput;
-
-        this.colorInput.addEventListener('change', this.updateColor.bind(this));
-        this.colorInput.addEventListener('input', this.updateColor.bind(this));
-    }
-
-    /**
-     * Update the app colors as a preview, and create a light version of the color.
-     */
-    updateColor() {
-        const hexVal = this.colorInput.value;
-        const rgb = this.hexToRgb(hexVal);
-        const rgbLightVal = 'rgba('+ [rgb.r, rgb.g, rgb.b, '0.15'].join(',') +')';
-
-        this.lightColorInput.value = rgbLightVal;
-
-        const customStyles = document.getElementById('custom-styles');
-        const oldColor = customStyles.getAttribute('data-color');
-        const oldColorLight = customStyles.getAttribute('data-color-light');
-
-        customStyles.innerHTML = customStyles.innerHTML.split(oldColor).join(hexVal);
-        customStyles.innerHTML = customStyles.innerHTML.split(oldColorLight).join(rgbLightVal);
-
-        customStyles.setAttribute('data-color', hexVal);
-        customStyles.setAttribute('data-color-light', rgbLightVal);
-    }
-
-    /**
-     * Covert a hex color code to rgb components.
-     * @attribution https://stackoverflow.com/a/5624139
-     * @param {String} hex
-     * @returns {{r: Number, g: Number, b: Number}}
-     */
-    hexToRgb(hex) {
-        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
-        return {
-            r: result ? parseInt(result[1], 16) : 0,
-            g: result ? parseInt(result[2], 16) : 0,
-            b: result ? parseInt(result[3], 16) : 0
-        };
-    }
-
-}
diff --git a/resources/js/components/setting-app-color-scheme.js b/resources/js/components/setting-app-color-scheme.js
new file mode 100644 (file)
index 0000000..71b14ba
--- /dev/null
@@ -0,0 +1,82 @@
+import {Component} from "./component";
+
+export class SettingAppColorScheme extends Component {
+
+    setup() {
+        this.container = this.$el;
+        this.mode = this.$opts.mode;
+        this.lightContainer = this.$refs.lightContainer;
+        this.darkContainer = this.$refs.darkContainer;
+
+        this.container.addEventListener('tabs-change', event => {
+            const panel = event.detail.showing;
+            const newMode = (panel === 'color-scheme-panel-light') ? 'light' : 'dark';
+            this.handleModeChange(newMode);
+        });
+
+        const onInputChange = (event) => {
+            this.updateAppColorsFromInputs();
+
+            if (event.target.name.startsWith('setting-app-color')) {
+                this.updateLightForInput(event.target);
+            }
+        };
+        this.container.addEventListener('change', onInputChange);
+        this.container.addEventListener('input', onInputChange);
+    }
+
+    handleModeChange(newMode) {
+        this.mode = newMode;
+        const isDark = (newMode === 'dark');
+
+        document.documentElement.classList.toggle('dark-mode', isDark);
+        this.updateAppColorsFromInputs();
+    }
+
+    updateAppColorsFromInputs() {
+        const inputContainer = this.mode === 'dark' ? this.darkContainer : this.lightContainer;
+        const inputs = inputContainer.querySelectorAll('input[type="color"]');
+        for (const input of inputs) {
+            const splitName = input.name.split('-');
+            const colorPos = splitName.indexOf('color');
+            let cssId = splitName.slice(1, colorPos).join('-');
+            if (cssId === 'app') {
+                cssId = 'primary';
+            }
+
+            const varName = '--color-' + cssId;
+            document.body.style.setProperty(varName, input.value);
+        }
+    }
+
+    /**
+     * Update the 'light' app color variant for the given input.
+     * @param {HTMLInputElement} input
+     */
+    updateLightForInput(input) {
+        const lightName = input.name.replace('-color', '-color-light');
+        const hexVal = input.value;
+        const rgb = this.hexToRgb(hexVal);
+        const rgbLightVal = 'rgba('+ [rgb.r, rgb.g, rgb.b, '0.15'].join(',') +')';
+
+        console.log(input.name, lightName, hexVal, rgbLightVal)
+        const lightColorInput = this.container.querySelector(`input[name="${lightName}"][type="hidden"]`);
+        lightColorInput.value = rgbLightVal;
+    }
+
+    /**
+     * Covert a hex color code to rgb components.
+     * @attribution https://stackoverflow.com/a/5624139
+     * @param {String} hex
+     * @returns {{r: Number, g: Number, b: Number}}
+     */
+    hexToRgb(hex) {
+        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+        return {
+            r: result ? parseInt(result[1], 16) : 0,
+            g: result ? parseInt(result[2], 16) : 0,
+            b: result ? parseInt(result[3], 16) : 0
+        };
+    }
+
+}
index 876e14f20c276a2fc7c4401316f0b80e1fa6a0a8..bfb2c93cee4810d290ed2dfdb16303148082b048 100644 (file)
@@ -15,6 +15,6 @@ export class SettingColorPicker extends Component {
 
     setValue(value) {
         this.colorInput.value = value;
-        this.colorInput.dispatchEvent(new Event('change'));
+        this.colorInput.dispatchEvent(new Event('change', {bubbles: true}));
     }
 }
\ No newline at end of file
index 6d48048b55ef9a3ec7647df891e51dcba095c859..8d22e3e9b57279648ce4c2bc45856ff351e84a79 100644 (file)
@@ -43,7 +43,7 @@ export class Tabs extends Component {
             tab.setAttribute('aria-selected', selected ? 'true' : 'false');
         }
 
-        this.$emit('change', {section: sectionId});
+        this.$emit('change', {showing: sectionId});
     }
 
 }
\ No newline at end of file
index 1a56ebf6ce8595a29cab4f48fbd9422f9a9649a2..238f8b1d88c7b4d1f2be0d684a9f816be9461949 100644 (file)
@@ -34,7 +34,7 @@ export function scrollAndHighlightElement(element) {
     if (!element) return;
     element.scrollIntoView({behavior: 'smooth'});
 
-    const color = document.getElementById('custom-styles').getAttribute('data-color-light');
+    const color = getComputedStyle(document.body).getPropertyValue('--color-primary-light');
     const initColor = window.getComputedStyle(element).getPropertyValue('background-color');
     element.style.backgroundColor = color;
     setTimeout(() => {
index d261110c7064d8a64c7f43ab160ed989960e05e9..bfdcc8512896821335cb0da6c28dc3982973224e 100644 (file)
@@ -1,13 +1,7 @@
-<style id="custom-styles"
-       data-color="{{ setting('app-color') }}"
-       data-color-dark="{{ setting('app-color-dark') }}"
-       data-color-light="{{ setting('app-color-light') }}"
-       data-color-light-dark="{{ setting('app-color-light-dark') }}">
-
-    @php
-        $settingSuffix = setting()->getForCurrentUser('dark-mode-enabled') ? '-dark' : '';
-    @endphp
-
+@php
+    $settingSuffix = setting()->getForCurrentUser('dark-mode-enabled') ? '-dark' : '';
+@endphp
+<style>
     :root {
         --color-primary: {{ setting('app-color' . $settingSuffix) }};
         --color-primary-light: {{ setting('app-color-light' . $settingSuffix) }};
index ac1f678a56c32ad7d68c6a2d52e4c54b274fa891..be99cc2547606a93fff6a0ac430dadb953f73d4e 100644 (file)
             </div>
 
             <!-- App Color Scheme -->
-            <div class="pb-l">
+            @php
+                $darkMode = boolval(setting()->getForCurrentUser('dark-mode-enabled'));
+            @endphp
+            <div component="setting-app-color-scheme"
+                 option:setting-app-color-scheme:mode="{{ $darkMode ? 'dark' : 'light' }}"
+                 class="pb-l">
                 <div class="mb-l">
                     <label class="setting-list-label">{{ trans('settings.color_scheme') }}</label>
                     <p class="small">{{ trans('settings.color_scheme_desc') }}</p>
                 </div>
 
-                @php
-                    $darkMode = boolval(setting()->getForCurrentUser('dark-mode-enabled'));
-                @endphp
                 <div component="tabs" class="tab-container">
                     <div role="tablist" class="controls-card">
                         <button type="button"
@@ -94,6 +96,7 @@
                     </div>
                     <div class="sub-card">
                         <div id="color-scheme-panel-light"
+                             refs="setting-app-color-scheme@lightContainer"
                              tabindex="0"
                              role="tabpanel"
                              aria-labelledby="color-scheme-tab-light"
                             @include('settings.parts.setting-color-scheme', ['mode' => 'light'])
                         </div>
                         <div id="color-scheme-panel-dark"
+                             refs="setting-app-color-scheme@darkContainer"
                              tabindex="0"
                              role="tabpanel"
                              aria-labelledby="color-scheme-tab-light"
index 1b18a9a6afc3bd0076b677338a21e33d4bf89704..7f8e55ac21a0a93ec54757e5ee82ab29006c7f07 100644 (file)
@@ -22,4 +22,8 @@
         @include('settings.parts.setting-color-picker', ['type' => 'page', 'mode' => $mode])
         @include('settings.parts.setting-color-picker', ['type' => 'page-draft', 'mode' => $mode])
     </div>
-</div>
\ No newline at end of file
+</div>
+
+<input type="hidden"
+       value="{{ setting('app-color-light' . ($mode === 'dark' ? '-dark' : '')) }}"
+       name="setting-app-color-light{{ $mode === 'dark' ? '-dark' : '' }}">
\ No newline at end of file