From 8135ff2dd05c039e1e0c835dc2012b84a5cf4a63 Mon Sep 17 00:00:00 2001 From: Jason Henriquez Date: Fri, 26 Apr 2024 17:58:56 -0500 Subject: [PATCH] Implement dynamic scroll-based underlining of active section --- .../ft-settings-menu/ft-settings-menu.css | 29 ++++++++++--- .../ft-settings-menu/ft-settings-menu.vue | 18 +++++--- src/renderer/views/Settings/Settings.css | 29 ++++++++++--- src/renderer/views/Settings/Settings.js | 34 +++++++++++---- src/renderer/views/Settings/Settings.vue | 42 +++++++++---------- 5 files changed, 107 insertions(+), 45 deletions(-) diff --git a/src/renderer/components/ft-settings-menu/ft-settings-menu.css b/src/renderer/components/ft-settings-menu/ft-settings-menu.css index d551fcdeb..f5f93289c 100644 --- a/src/renderer/components/ft-settings-menu/ft-settings-menu.css +++ b/src/renderer/components/ft-settings-menu/ft-settings-menu.css @@ -2,11 +2,10 @@ position: fixed; display: flex; flex-direction: column; - padding: 0; - gap: 5px; + gap: 2px; font-size: 22px; - inline-size: fit-content; - max-inline-size: 250px; + inline-size: 250px; + padding-inline-start: 10px; } .header { @@ -26,9 +25,29 @@ color: var(--primary-text-color); } +.settingsMenuTitleContent { + inline-size: fit-content; +} + +.settingsMenuTitleAndIcon { + /* needed to have underline poke out */ + margin-inline-start: 3px; +} + +.settingsMenuTitleUnderline { + /* have underline poke out */ + inline-size: calc(100% + 3px); + + /* prevent "active" border from visibly pushing the content up */ + border-block-end: 3px solid transparent; +} + .settingsMenuTitle.active { color: var(--primary-text-color); - border-block-end: 3px solid var(--primary-text-color); +} + +.settingsMenuTitle.active .settingsMenuTitleUnderline { + border-block-end: 3px solid var(--primary-color); } .settingsMenuTitleIcon { diff --git a/src/renderer/components/ft-settings-menu/ft-settings-menu.vue b/src/renderer/components/ft-settings-menu/ft-settings-menu.vue index 9a7d27834..e9166f307 100644 --- a/src/renderer/components/ft-settings-menu/ft-settings-menu.vue +++ b/src/renderer/components/ft-settings-menu/ft-settings-menu.vue @@ -7,15 +7,21 @@ - - {{ getTitleForSection(settingsSection) }} +
+
+ + {{ getTitleForSection(settingsSection) }} +
+
+
diff --git a/src/renderer/views/Settings/Settings.css b/src/renderer/views/Settings/Settings.css index a7cd9463a..bdc89a7cd 100644 --- a/src/renderer/views/Settings/Settings.css +++ b/src/renderer/views/Settings/Settings.css @@ -7,25 +7,42 @@ display: flex; flex-direction: column; align-items: center; + max-inline-size: 80%; } .settingsSections { margin-inline: auto; } -.switchRow { - display: flex; +.settingsSections:last-child { + margin-block-end: calc(76vh - 150px) } -/* .settingsSections { - -} */ +.switchRow { + display: flex; + margin-inline-end: auto; +} .settingsToggle { padding-block: 0; - margin-block: 10px 5px; + margin-block: 0; +} + +.section { + /* enables anchor link clicks to land right at the section headings */ + scroll-margin-top: 24vh; } .section + .section { padding-block-start: 20px; } + +@media only screen and (width <= 950px) { + ft-settings-menu { + display: none; + } + + .settingsContent { + margin-inline: auto; + } +} diff --git a/src/renderer/views/Settings/Settings.js b/src/renderer/views/Settings/Settings.js index 26e8c59d0..35ed77cbb 100644 --- a/src/renderer/views/Settings/Settings.js +++ b/src/renderer/views/Settings/Settings.js @@ -45,10 +45,6 @@ export default defineComponent({ } }, computed: { - locale: function() { - return this.$i18n.locale.replace('_', '-') - }, - settingsPassword: function () { return this.$store.getters.getSettingsPassword }, @@ -170,15 +166,39 @@ export default defineComponent({ return settingsSections }, }, + watch: { + locale: 'scrollToGeneralSettings' + }, created: function () { if (this.settingsPassword === '') { this.unlocked = true } }, + mounted: function () { + document.addEventListener('scroll', this.scrollCurrentSection) + }, + beforeDestroy: function () { + document.removeEventListener('scroll', this.scrollCurrentSection) + }, methods: { - scrollToSection(section) { - const sectionElement = this.$refs[section] - sectionElement?.scrollIntoView() + scrollToGeneralSettings() { + document.getElementById('general-settings')?.scrollIntoView() + }, + + scrollCurrentSection: function() { + const scrollY = window.scrollY + innerHeight / 4 + this.settingsSectionComponents.forEach((section) => { + const sectionElement = document.getElementById(section.type) + const sectionHeight = sectionElement.offsetHeight + const sectionTop = sectionElement.offsetTop + + const menuElement = document.getElementById(`${section.type}-link`) + if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) { + menuElement.classList.add('active') + } else { + menuElement.classList.remove('active') + } + }) }, ...mapActions([ diff --git a/src/renderer/views/Settings/Settings.vue b/src/renderer/views/Settings/Settings.vue index ed50a0709..e30c2e0b9 100644 --- a/src/renderer/views/Settings/Settings.vue +++ b/src/renderer/views/Settings/Settings.vue @@ -5,29 +5,29 @@ :settings-sections="settingsSectionComponents" />
-
- -
-
- +
+
+ +
-