From db4048f9e3577107297e5782f65ec53bd8fa9a9f Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Mon, 12 May 2025 15:52:43 -0500 Subject: [PATCH 01/50] WIP: Removed unused home-interactions.js --- assets/js/home-interactions.js | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 assets/js/home-interactions.js diff --git a/assets/js/home-interactions.js b/assets/js/home-interactions.js deleted file mode 100644 index a90df14cd..000000000 --- a/assets/js/home-interactions.js +++ /dev/null @@ -1,22 +0,0 @@ -$('.exp-btn').click(function() { - var targetBtnElement = $(this).parent() - $('.exp-btn > p', targetBtnElement).fadeOut(100); - setTimeout(function() { - $('.exp-btn-links', targetBtnElement).fadeIn(200) - $('.exp-btn', targetBtnElement).addClass('open'); - $('.close-btn', targetBtnElement).fadeIn(200); - }, 100); -}) - -$('.close-btn').click(function() { - var targetBtnElement = $(this).parent().parent() - $('.exp-btn-links', targetBtnElement).fadeOut(100) - $('.exp-btn', targetBtnElement).removeClass('open'); - $(this).fadeOut(100); - setTimeout(function() { - $('p', targetBtnElement).fadeIn(100); - }, 100); -}) - -/////////////////////////////// EXPANDING BUTTONS ////////////////////////////// - From ccf74df759dbb5cc8762260b08a069c662376954 Mon Sep 17 00:00:00 2001 From: Jason Stirnaman Date: Mon, 12 May 2025 15:58:12 -0500 Subject: [PATCH 02/50] WIP: Refactored all scripts from footer.js into components. Removed footer.js. Exports jQuery ($) to a window global for use by other scripts. Scripts bundled into footer.js didn't reliably load after jQuery. --- assets/js/components/sidebar-search.js | 6 ++ assets/js/feature-callouts.js | 34 +++++----- assets/js/keybindings.js | 29 ++++----- assets/js/list-filters.js | 62 ++++++++++--------- assets/js/main.js | 20 +++++- assets/js/search-interactions.js | 10 --- assets/js/utils/search-interactions.js | 22 +++++++ assets/js/version-selector.js | 34 +++++----- layouts/index.html | 2 +- layouts/partials/footer/feature-callout.html | 2 +- layouts/partials/footer/javascript.html | 12 +--- layouts/partials/header/javascript.html | 6 +- layouts/partials/sidebar.html | 2 +- layouts/partials/topnav/product-selector.html | 2 +- layouts/shortcodes/keybind.html | 2 +- layouts/shortcodes/list-filters.html | 2 +- 16 files changed, 138 insertions(+), 109 deletions(-) create mode 100644 assets/js/components/sidebar-search.js delete mode 100644 assets/js/search-interactions.js create mode 100644 assets/js/utils/search-interactions.js diff --git a/assets/js/components/sidebar-search.js b/assets/js/components/sidebar-search.js new file mode 100644 index 000000000..1e5023050 --- /dev/null +++ b/assets/js/components/sidebar-search.js @@ -0,0 +1,6 @@ +import SearchInteractions from '../utils/search-interactions'; + +export default function SidebarSearch({ component }) { + const searchInput = component.querySelector('.sidebar--search-field'); + SearchInteractions({ searchInput }); +} \ No newline at end of file diff --git a/assets/js/feature-callouts.js b/assets/js/feature-callouts.js index 253b09b13..a77015e6e 100644 --- a/assets/js/feature-callouts.js +++ b/assets/js/feature-callouts.js @@ -6,33 +6,29 @@ assets/js/cookies.js. */ +import $ from 'jquery'; +import * as LocalStorageAPI from './local-storage.js'; + // Get notification ID -function getCalloutID (el) { +function getCalloutID(el) { return $(el).attr('id'); } // Hide a callout and update the cookie with the viewed callout -function hideCallout (calloutID) { - if (!window.LocalStorageAPI.notificationIsRead(calloutID)) { - window.LocalStorageAPI.setNotificationAsRead(calloutID, 'callout'); +function hideCallout(calloutID) { + if (!LocalStorageAPI.notificationIsRead(calloutID)) { + LocalStorageAPI.setNotificationAsRead(calloutID, 'callout'); $(`#${calloutID}`).fadeOut(200); } } // Show the url feature callouts on page load -$(document).ready(function () { - $('.feature-callout').each(function () { - const calloutID = getCalloutID($(this)); +export default function FeatureCallout({ component }) { + const calloutID = getCalloutID($(component)); - if (!window.LocalStorageAPI.notificationIsRead(calloutID, 'callout')) { - $(`#${calloutID}.feature-callout`) - .fadeIn(300) - .removeClass('start-position'); - } - }); -}); - -// Hide the InfluxDB URL selector callout -// $('button.url-trigger, #influxdb-url-selector .close').click(function () { -// hideCallout('influxdb-url-selector'); -// }); + if (LocalStorageAPI.notificationIsRead(calloutID, 'callout')) { + $(`#${calloutID}.feature-callout`) + .fadeIn(300) + .removeClass('start-position'); + } +} diff --git a/assets/js/keybindings.js b/assets/js/keybindings.js index 6c8f2fcbe..6048e899c 100644 --- a/assets/js/keybindings.js +++ b/assets/js/keybindings.js @@ -11,17 +11,14 @@ function getPlatform() { } } -const platform = getPlatform() - -function addOSClass(osClass) { - $('.keybinding').addClass(osClass) +function addOSClass(osClass, { $component }) { + $component.addClass(osClass) } -function updateKeyBindings() { - $('.keybinding').each(function() { - var osx = $(this).data("osx") - var linux = $(this).data("linux") - var win = $(this).data("win") +function updateKeyBindings({ $component }) { + var osx = $component.data("osx") + var linux = $component.data("linux") + var win = $component.data("win") if (platform === "other") { if (win != linux) { @@ -30,12 +27,16 @@ function updateKeyBindings() { var keybind = '' + linux + ' for Linux and Windows and ' + osx + ' for macOS'; } } else { - var keybind = '' + $(this).data(platform) + '' + var keybind = '' + $component.data(platform) + '' } - $(this).html(keybind) - }) + $component.html(keybind) } -addOSClass(platform) -updateKeyBindings() +export default function KeyBinding({ component }) { + // Initialize keybindings + const platform = getPlatform(); + const $component = $(component); + addOSClass(platform, { $component }); + updateKeyBindings({ $component }); +} diff --git a/assets/js/list-filters.js b/assets/js/list-filters.js index 7b008dcb6..b541161ec 100644 --- a/assets/js/list-filters.js +++ b/assets/js/list-filters.js @@ -3,8 +3,8 @@ function countTag(tag) { return $(".visible[data-tags*='" + tag + "']").length } -function getFilterCounts() { - $('#list-filters label').each(function() { +function getFilterCounts($labels) { + $labels.each(function() { var tagName = $('input', this).attr('name').replace(/[\W/]+/, "-"); var tagCount = countTag(tagName); $(this).attr('data-count', '(' + tagCount + ')'); @@ -16,35 +16,39 @@ function getFilterCounts() { }) } -// Get initial filter count on page load -getFilterCounts() +export default function ListFilters({ component }) { + const $labels = $(component).find('label'); + const $inputs = $(component).find('input'); -$("#list-filters input").click(function() { + getFilterCounts($labels); - // List of tags to hide - var tagArray = $("#list-filters input:checkbox:checked").map(function(){ - return $(this).attr('name').replace(/[\W]+/, "-"); - }).get(); + $inputs.click(function() { - // List of tags to restore - var restoreArray = $("#list-filters input:checkbox:not(:checked)").map(function(){ - return $(this).attr('name').replace(/[\W]+/, "-"); - }).get(); + // List of tags to hide + var tagArray = $(component).find("input:checkbox:checked").map(function(){ + return $(this).attr('name').replace(/[\W]+/, "-"); + }).get(); - // Actions for filter select - if ( $(this).is(':checked') ) { - $.each( tagArray, function( index, value ) { - $(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').fadeOut() - }) - } else { - $.each( restoreArray, function( index, value ) { - $(".filter-item:not(.visible)[data-tags~='" + value + "']").addClass('visible').fadeIn() - }) - $.each( tagArray, function( index, value ) { - $(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').hide() - }) - } + // List of tags to restore + var restoreArray = $(component).find("input:checkbox:not(:checked)").map(function(){ + return $(this).attr('name').replace(/[\W]+/, "-"); + }).get(); - // Refresh filter count - getFilterCounts() -}); + // Actions for filter select + if ( $(this).is(':checked') ) { + $.each( tagArray, function( index, value ) { + $(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').fadeOut() + }) + } else { + $.each( restoreArray, function( index, value ) { + $(".filter-item:not(.visible)[data-tags~='" + value + "']").addClass('visible').fadeIn() + }) + $.each( tagArray, function( index, value ) { + $(".filter-item.visible:not([data-tags~='" + value + "'])").removeClass('visible').hide() + }) + } + + // Refresh filter count + getFilterCounts($labels); + }); +} diff --git a/assets/js/main.js b/assets/js/main.js index 5c2289720..72838978b 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -3,6 +3,9 @@ // If you need to pass parameters from the calling Hugo page, you can import them here like so: // import * as pageParams from '@params'; +// Import dependencies that we still need to load in the global scope +import $ from 'jquery'; + /** Import modules that are not components. * TODO: Refactor these into single-purpose component modules. */ @@ -11,7 +14,7 @@ import * as codeControls from './code-controls.js'; import * as contentInteractions from './content-interactions.js'; import { delay } from './helpers.js'; import { InfluxDBUrl } from './influxdb-url.js'; -import * as localStorage from './local-storage.js'; +import * as localStorage from './local-storage.js'; import * as modals from './modals.js'; import * as notifications from './notifications.js'; import * as pageContext from './page-context.js'; @@ -29,8 +32,13 @@ import * as v3Wayfinding from './v3-wayfinding.js'; import AskAITrigger from './ask-ai-trigger.js'; import CodePlaceholder from './code-placeholders.js'; import { CustomTimeTrigger } from './custom-timestamps.js'; +import FeatureCallout from './feature-callouts.js'; import FluxInfluxDBVersionsTrigger from './flux-influxdb-versions.js'; +import KeyBinding from './keybindings.js'; +import ListFilters from './list-filters.js'; +import ProductSelector from './version-selector.js'; import { SearchButton } from './search-button.js'; +import SidebarSearch from './components/sidebar-search.js'; import { SidebarToggle } from './sidebar-toggle.js'; import Theme from './theme.js'; import ThemeSwitch from './theme-switch.js'; @@ -49,8 +57,13 @@ const componentRegistry = { 'ask-ai-trigger': AskAITrigger, 'code-placeholder': CodePlaceholder, 'custom-time-trigger': CustomTimeTrigger, + 'feature-callout': FeatureCallout, 'flux-influxdb-versions-trigger': FluxInfluxDBVersionsTrigger, + 'keybinding': KeyBinding, + 'list-filters': ListFilters, + 'product-selector': ProductSelector, 'search-button': SearchButton, + 'sidebar-search': SidebarSearch, 'sidebar-toggle': SidebarToggle, 'theme': Theme, 'theme-switch': ThemeSwitch @@ -72,6 +85,11 @@ function initGlobals() { window.influxdatadocs.toggleModal = modals.toggleModal; window.influxdatadocs.componentRegistry = componentRegistry; + // Re-export jQuery to global namespace for legacy scripts + if (typeof window.jQuery === 'undefined') { + window.jQuery = window.$ = $; + } + return window.influxdatadocs; } diff --git a/assets/js/search-interactions.js b/assets/js/search-interactions.js deleted file mode 100644 index 4f8fdd8ac..000000000 --- a/assets/js/search-interactions.js +++ /dev/null @@ -1,10 +0,0 @@ -// Fade content wrapper when focusing on search input -$('#algolia-search-input').focus(function() { - $('.content-wrapper').fadeTo(300, .35); -}) - -// Hide search dropdown when leaving search input -$('#algolia-search-input').blur(function() { - $('.content-wrapper').fadeTo(200, 1); - $('.ds-dropdown-menu').hide(); -}) diff --git a/assets/js/utils/search-interactions.js b/assets/js/utils/search-interactions.js new file mode 100644 index 000000000..83d217382 --- /dev/null +++ b/assets/js/utils/search-interactions.js @@ -0,0 +1,22 @@ +export default function SearchInteractions({ searchInput }) { + const contentWrapper = document.querySelector('.content-wrapper'); + const dropdownMenu = document.querySelector('.ds-dropdown-menu'); + + // Fade content wrapper when focusing on search input + searchInput.addEventListener('focus', () => { + // Using CSS transitions instead of jQuery's fadeTo for better performance + contentWrapper.style.opacity = '0.35'; + contentWrapper.style.transition = 'opacity 300ms'; + }); + + // Hide search dropdown when leaving search input + searchInput.addEventListener('blur', () => { + contentWrapper.style.opacity = '1'; + contentWrapper.style.transition = 'opacity 200ms'; + + // Hide dropdown menu + if (dropdownMenu) { + dropdownMenu.style.display = 'none'; + } + }); +} \ No newline at end of file diff --git a/assets/js/version-selector.js b/assets/js/version-selector.js index 51fa52c53..253365a23 100644 --- a/assets/js/version-selector.js +++ b/assets/js/version-selector.js @@ -1,19 +1,21 @@ -// Select the product dropdown and dropdown items -const productDropdown = document.querySelector("#product-dropdown"); -const dropdownItems = document.querySelector("#dropdown-items"); +export default function ProductSelector({ component }) { + // Select the product dropdown and dropdown items + const productDropdown = component.querySelector("#product-dropdown"); + const dropdownItems = component.querySelector("#dropdown-items"); -// Expand the menu on click -if (productDropdown) { - productDropdown.addEventListener("click", function() { - productDropdown.classList.toggle("open"); - dropdownItems.classList.toggle("open"); + // Expand the menu on click + if (productDropdown) { + productDropdown.addEventListener("click", function() { + productDropdown.classList.toggle("open"); + dropdownItems.classList.toggle("open"); + }); + } + + // Close the dropdown by clicking anywhere else + document.addEventListener("click", function(e) { + // Check if the click was outside of the '.product-list' container + if (!e.target.closest('.product-list')) { + dropdownItems.classList.remove("open"); + } }); } - -// Close the dropdown by clicking anywhere else -document.addEventListener("click", function(e) { - // Check if the click was outside of the '.product-list' container - if (!e.target.closest('.product-list')) { - dropdownItems.classList.remove("open"); - } -}); diff --git a/layouts/index.html b/layouts/index.html index b04b66e5c..6bbd51ab6 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -19,7 +19,7 @@