Loading admin_toolbar_search/admin_toolbar_search.libraries.yml +3 −3 Original line number Diff line number Diff line # Libraries for the Admin Toolbar Search module. # The main library that provides the search functionality and styling. search: admin_toolbar_search: css: theme: # Styles for the search tab, field, and autocomplete dropdown. Loading @@ -14,8 +14,8 @@ search: - core/drupal.autocomplete # A separate library to handle keyboard shortcuts for the search field. search.keyboard_shortcut: admin_toolbar_search.keyboard_shortcut: js: js/admin_toolbar_search.keyboard_shortcut.js: {} dependencies: - admin_toolbar_search/search - admin_toolbar_search/admin_toolbar_search admin_toolbar_search/admin_toolbar_search.module +71 −60 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ */ use Drupal\admin_toolbar_search\Constants\AdminToolbarSearchConstants; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Url; /** Loading @@ -27,16 +28,22 @@ function admin_toolbar_search_help($route_name) { /** * Implements hook_toolbar(). * * Inject the admin toolbar search JS autocomplete text field in the Toolbar, * either directly or as a toolbar item tab with a tray ('display_menu_item'). * Add the necessary CSS classes, HTML IDs and load required JS libraries and * settings. * Inject the admin toolbar search JS autocomplete text field in the Toolbar * directly as a toolbar item or as a menu item tab with a tray * ('display_menu_item'). Add the necessary CSS classes, HTML IDs and load * required JS libraries and settings. * * Provide support for mobile devices by adding a mobile search tab that * displays the search field in a custom tray when the toolbar width is below * 769px. * Note the display styles for mobile devices is still different depending on * whether the 'display_menu_item' setting is enabled or not. * The autocomplete search field is always loaded with a menu item tab and tray, * but if the 'display_menu_item' setting is disabled, the search field is also * added directly in the toolbar as a separate toolbar item. * The default search tab is then hidden or displayed with CSS styles when the * toolbar width is below '769px', to support mobile devices. * * In other words, support for smaller devices is not provided by the module, * but by Drupal core. * * @see admin_toolbar_search/css/admin_toolbar_search.css * @see admin_toolbar_search/js/admin_toolbar_search.js */ function admin_toolbar_search_toolbar() { // Load the admin toolbar search only if the user has the required permission. Loading @@ -57,17 +64,14 @@ function admin_toolbar_search_toolbar() { $search_field_placeholder = t('Search for menu links'); $search_field_title_attribute = t('Type text to search for menu links in the admin toolbar.'); // Render array of properties for the admin search tab menu link, when it is // *not* displayed directly in the toolbar or as a fallback for mobile search. $administration_search_tab_link = [ '#type' => 'link', '#title' => $search_field_title, // Since the search field is handled with JS, the tab does not need a link. '#url' => Url::fromRoute('<nolink>'), '#attributes' => [ 'class' => [ 'toolbar-icon', // Ensure the toolbar items are rebuilt when the user permissions or module's // settings change and keep the render arrays cached. $toolbar_search_item_cache = [ 'contexts' => [ 'user.permissions', ], 'tags' => [ 'config:admin_toolbar_search.settings', ], ]; // Render array of properties for the admin toolbar search JS autocomplete Loading @@ -92,6 +96,24 @@ function admin_toolbar_search_toolbar() { // Add the admin toolbar search as a toolbar item render array. $items['administration_search'] = [ '#type' => 'toolbar_item', 'tab' => [ // Render array of properties for the admin search tab menu link, when it // is *not* displayed directly in the toolbar or as a fallback for mobile. '#type' => 'link', '#title' => $search_field_title, // Since the search field is handled with JS, there is no link url for the // tab, so a simple 'span' element could be used instead. '#url' => Url::fromRoute('<nolink>'), '#attributes' => [ 'class' => [ // Ensures compatibility with Drupal core toolbar styles for the // search tab magnifying glass icon. 'toolbar-icon', ], ], ], // Move the search tab to the end of the toolbar items, by default. '#weight' => 110, // Set the ID of the HTML element wrapping the toolbar item. '#wrapper_attributes' => [ 'id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_tab'], Loading @@ -99,7 +121,7 @@ function admin_toolbar_search_toolbar() { // Load the required JS library and settings by default. '#attached' => [ 'library' => [ 'admin_toolbar_search/search', 'admin_toolbar_search/admin_toolbar_search', ], // Add a setting to determine if extra links should be loaded via AJAX. 'drupalSettings' => [ Loading @@ -108,24 +130,13 @@ function admin_toolbar_search_toolbar() { ], ], ], // Ensure the toolbar item is rebuilt when the user permissions or module's // settings change and keep this render array cached. '#cache' => [ 'contexts' => [ 'user.permissions', ], 'tags' => [ 'config:admin_toolbar_search.settings', ], ], // Set the cache metadata for the administration search toolbar item. '#cache' => $toolbar_search_item_cache, ]; // Add the keyboard shortcut library if enabled ('enable_keyboard_shortcut'). if ($admin_toolbar_search_settings->get('enable_keyboard_shortcut')) { $items['administration_search']['#attached']['library'][] = 'admin_toolbar_search/search.keyboard_shortcut'; // The display menu item setting is used to determine if the search input // should be displayed as a menu item or directly in the toolbar. $items['administration_search']['#attached']['drupalSettings']['adminToolbarSearch']['displayMenuItem'] = $display_menu_item; $items['administration_search']['#attached']['library'][] = 'admin_toolbar_search/admin_toolbar_search.keyboard_shortcut'; // Add the keyboard shortcut label to the search field placeholder and // title attributes. Loading @@ -136,39 +147,39 @@ function admin_toolbar_search_toolbar() { ]); } // Build the toolbar item depending on the whether it is displayed as a menu // item with a tray or directly in the toolbar ('display_menu_item' setting). if ($display_menu_item) { // The search field is displayed in a specific Tray under the Search Tab. $items['administration_search'] += [ 'tab' => $administration_search_tab_link, 'tray' => $administration_search_field, ]; } else { // Reduce the size and hide the label of the search input field. $administration_search_field['search']['#title_display'] = 'invisible'; $administration_search_field['search']['#size'] = 30; // The search field is always displayed in a specific tray under the 'Search' // tab menu item. This tab is hidden or shown with CSS styles depending on the // toolbar width breakpoint and the 'display_menu_item' setting. $items['administration_search']['tray'] = $administration_search_field; // Add the autocomplete search field directly in the toolbar by default, as // a toolbar item ('display_menu_item:false'). if (!$display_menu_item) { // The search field is displayed directly in the Toolbar without a tray. $items['administration_search'] += [ '#weight' => 110, 'tab' => $administration_search_field, ]; // Add toolbar item render array for the mobile search tab that displays the // search field in a custom tray, see module's CSS for styling. The display // of the mobile search tab is toggled with a CSS breakpoint at 769px. $items['administration_mobile_search'] = [ $items['administration_search_field'] = [ '#type' => 'toolbar_item', 'tab' => $administration_search_tab_link, // It is important the mobile search tab is displayed *before* the search // toolbar item otherwise module's CSS rules will not work. // Display the search field directly in the toolbar tab: Modify the search // field properties for the toolbar item by merging the new options with // the existing ones. 'tab' => NestedArray::mergeDeep($administration_search_field, [ 'search' => [ // Reduce the size and hide the label of the search input field. '#size' => 30, '#title_display' => 'invisible', // Set a different HTML ID for the search input field when displayed // directly in the toolbar. '#id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_field_input'], ], ]), // The search field toolbar item should be right before the main search // tab so it stays at the same position when the tab is hidden or shown. '#weight' => $items['administration_search']['#weight'] - 1, // Set the ID of the HTML element wrapping the toolbar item. '#wrapper_attributes' => [ 'id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_tab_mobile'], 'id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_field_tab'], ], // Set the cache metadata for the admin search field toolbar item. '#cache' => $toolbar_search_item_cache, ]; } Loading admin_toolbar_search/css/admin_toolbar_search.css +42 −46 Original line number Diff line number Diff line /* CSS styles for the Admin Toolbar Search module. */ /* Styles for the search tab menu link and the mobile search tab. */ #admin-toolbar-search-tab, #admin-toolbar-mobile-search-tab { /* Styles for the search tab menu link used for desktop and mobile. */ #admin-toolbar-search-tab { /* Add a small magnifier icon before the search tab link. */ .toolbar-item { display: block; Loading @@ -13,41 +12,31 @@ } } /* Styles for the mobile search tab and its interaction with the search tab. */ #admin-toolbar-mobile-search-tab { /* These styles only work if the mobile tab is before the search tab. */ ~ #admin-toolbar-search-tab { /* Show the search tab and hide the search field by default on mobile. */ display: none; /* Set the search field to full width when visible. */ &.visible { display: block; width: 100%; } /* Add padding to the wrapper around the search label and input field. */ .js-form-item { margin: 0; padding: 0.3rem 1rem; } /* Make the search input field take the full width on mobile. */ #admin-toolbar-search-input { width: 100%; } } } /* Styles for the search JS autocomplete input text field. */ #admin-toolbar-search-input { /* Styles for the search JS autocomplete input text fields. */ #admin-toolbar-search-input, #admin-toolbar-search-field-input { height: 100%; min-height: 1.875rem; margin: 0; padding: 0 0.4rem; padding: 0 0.5rem; color: #3b3b3b; border: 1px solid #ccc; border-radius: unset; background: #fcfcfa; font-size: 0.813rem; line-height: 1.75rem; font-size: 0.8125rem; line-height: 1.625rem; } /* Styles for the field tab and its interactions with the search tab. */ #admin-toolbar-search-field-tab { /* Hide the field tab and show the search tab by default on mobile. */ display: none; .form-item { /* Unset default form item margin to prevent a scrollbar from appearing. */ margin-block: auto; /* Add padding to the wrapper around the search label and input field. */ padding: 0.3125rem 1rem; } } /* Styles for the autocomplete suggestion list. Class added through the JS. */ Loading @@ -56,7 +45,7 @@ vertical scrolling if needed. */ overflow-y: scroll; max-height: 18.75rem; font-size: 0.7rem; font-size: 0.8125rem; /* Styles for each suggestion item in the autocomplete list. */ .ui-menu-item { Loading Loading @@ -88,39 +77,46 @@ /* Styles for the search form within the admin toolbar tray. */ #toolbar-item-administration-search-tray { /* Add margin to the wrapper around the search label and input field. */ .js-form-item { margin: 0.6rem; .form-item { /* Unset default form item margin. */ margin-block: auto; /* Add padding to the wrapper around the search label and input field. */ padding: 0.625rem; } /* Basic styles for the search label and input field. */ label { display: inline-block; margin-right: 0.45rem; margin-right: 0.5rem; color: #000; font-weight: bold; } input { display: inline-block; padding: 0.3rem 0.5rem; font-size: 0.86rem; padding: 0.3125rem 0.5rem; font-size: 0.85rem; } } /* Mobile first media query for screens wider than 769px (desktop, tablets). */ @media only screen and (min-width: 769px) { .admin-toolbar-search-autocomplete-list { /* Increase font size of autocomplete suggestions for wider screens. */ font-size: 1rem; } #admin-toolbar-mobile-search-tab { /* Hide the mobile search tab on wider screens by default. */ display: none; /* Display the search field and adjust its styles for wider screens. */ ~ #admin-toolbar-search-tab { /* Display the search field and and hide the search tab for wider screens. */ #admin-toolbar-search-field-tab { display: block; /* Reset width to auto for wider screens so it fits in the toolbar. */ &.visible { width: auto; /* These styles only work if the search field is before the search tab. */ ~ #admin-toolbar-search-tab { /* Hide the search tab when the field tab is visible on wider screens. */ display: none; } } /* Add a bit more margin space on the left of the search label in the toolbar tray when displayed on wider screens ('display menu item'). */ #toolbar-item-administration-search-tray { label { margin-left: 0.45rem; } } } admin_toolbar_search/js/admin_toolbar_search.js +12 −11 Original line number Diff line number Diff line Loading @@ -23,14 +23,14 @@ $(elements).each(function () { $self.links = []; var $searchTab = $(this).find('#admin-toolbar-search-tab') var $searchInput = $searchTab.find('#admin-toolbar-search-input'); var $searchInputs = $(this).find('#admin-toolbar-search-input, #admin-toolbar-search-field-input'); if ($searchInput.length === 0) { if ($searchInputs.length === 0) { return; } $searchInput.autocomplete({ $searchInputs.each(function (index, $searchInput) { $($searchInput).autocomplete({ minLength: 2, position: { collision : 'fit' }, source: function (request, response) { Loading Loading @@ -72,18 +72,19 @@ .append('<div ><a href="' + item.value + '">' + item.labelRaw + ' <span class="admin-toolbar-search-url">' + item.value + '</span></a></div>') .appendTo(ul); }); }); // Populate the links for search results when the input is pressed. $searchInput.focus(function () { $searchInputs.focus(function () { Drupal.behaviors.adminToolbarSearch.populateLinks($self); }); // Show/hide search input field when mobile tab item is pressed. $('#admin-toolbar-mobile-search-tab .toolbar-item', context).click(function (e) { // Focus the search input field when the search tab is pressed. context.querySelector('#admin-toolbar-search-tab .toolbar-item') .addEventListener('click', (e) => { e.preventDefault(); $(this).toggleClass('is-active'); $searchTab.toggleClass('visible'); $searchInput.focus(); const searchTabTray = e.target.nextElementSibling; searchTabTray.classList.toggle('is-active'); searchTabTray.querySelector('#admin-toolbar-search-input').focus(); }); }); }, Loading admin_toolbar_search/js/admin_toolbar_search.keyboard_shortcut.js +32 −11 Original line number Diff line number Diff line Loading @@ -7,6 +7,10 @@ /** * Implements the Admin Toolbar Search configured keyboard shortcut. * * Depending on whether the search input field is displayed as a toolbar * menu tray or as a standalone input field, the behavior will focus on the * appropriate element when the keyboard shortcut is triggered. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach Loading @@ -14,7 +18,7 @@ * shortcut combination of keys, currently defaults to: 'Alt + a'. */ Drupal.behaviors.adminToolbarSearchKeyboardShortcut = { attach: (context, settings) => { attach: (context) => { if (context !== document) { return; } Loading @@ -26,18 +30,35 @@ // Shortcut 'Alt + a' will focus on the search form. document.addEventListener('keydown', (event) => { if (event.altKey && (event.key === 'a' || event.keyCode === 65)) { const searchInputField = context.getElementById( 'admin-toolbar-search-input', // Get the search tab which should *always* be loaded. const searchTab = context.getElementById( 'admin-toolbar-search-tab', ); // Get the computed style of the search tab to check if it is // visible based on the toolbar width breakpoint. const searchTabStyle = window.getComputedStyle(searchTab); // Get the search field tab which could be empty ('null') if the // setting 'display_menu_item' is enabled. const searchFieldTab = context.getElementById( 'admin-toolbar-search-field-tab', ); // If the search input field is displayed as a toolbar menu tray, // toggle the toolbar item so the field could be focused. if (settings.adminToolbarSearch.displayMenuItem) { searchInputField .closest('.toolbar-tab') .querySelector('.toolbar-item') .click(); // If the search field tab is loaded and the search tab is not // visible, focus on the search input field directly. if (searchFieldTab !== null && searchTabStyle.display === 'none') { searchFieldTab .querySelector('#admin-toolbar-search-field-input') .focus(); } else { // If the search input field is displayed as a toolbar menu tray // and is not visible, toggle its display to focus its field. const searchTabToolbarItem = searchTab.querySelector('.toolbar-item'); if (!searchTabToolbarItem.classList.contains('is-active')) { searchTabToolbarItem.click(); } searchTab.querySelector('#admin-toolbar-search-input').focus(); } searchInputField.focus(); // Don't transmit the keystroke. event.preventDefault(); } Loading Loading
admin_toolbar_search/admin_toolbar_search.libraries.yml +3 −3 Original line number Diff line number Diff line # Libraries for the Admin Toolbar Search module. # The main library that provides the search functionality and styling. search: admin_toolbar_search: css: theme: # Styles for the search tab, field, and autocomplete dropdown. Loading @@ -14,8 +14,8 @@ search: - core/drupal.autocomplete # A separate library to handle keyboard shortcuts for the search field. search.keyboard_shortcut: admin_toolbar_search.keyboard_shortcut: js: js/admin_toolbar_search.keyboard_shortcut.js: {} dependencies: - admin_toolbar_search/search - admin_toolbar_search/admin_toolbar_search
admin_toolbar_search/admin_toolbar_search.module +71 −60 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ */ use Drupal\admin_toolbar_search\Constants\AdminToolbarSearchConstants; use Drupal\Component\Utility\NestedArray; use Drupal\Core\Url; /** Loading @@ -27,16 +28,22 @@ function admin_toolbar_search_help($route_name) { /** * Implements hook_toolbar(). * * Inject the admin toolbar search JS autocomplete text field in the Toolbar, * either directly or as a toolbar item tab with a tray ('display_menu_item'). * Add the necessary CSS classes, HTML IDs and load required JS libraries and * settings. * Inject the admin toolbar search JS autocomplete text field in the Toolbar * directly as a toolbar item or as a menu item tab with a tray * ('display_menu_item'). Add the necessary CSS classes, HTML IDs and load * required JS libraries and settings. * * Provide support for mobile devices by adding a mobile search tab that * displays the search field in a custom tray when the toolbar width is below * 769px. * Note the display styles for mobile devices is still different depending on * whether the 'display_menu_item' setting is enabled or not. * The autocomplete search field is always loaded with a menu item tab and tray, * but if the 'display_menu_item' setting is disabled, the search field is also * added directly in the toolbar as a separate toolbar item. * The default search tab is then hidden or displayed with CSS styles when the * toolbar width is below '769px', to support mobile devices. * * In other words, support for smaller devices is not provided by the module, * but by Drupal core. * * @see admin_toolbar_search/css/admin_toolbar_search.css * @see admin_toolbar_search/js/admin_toolbar_search.js */ function admin_toolbar_search_toolbar() { // Load the admin toolbar search only if the user has the required permission. Loading @@ -57,17 +64,14 @@ function admin_toolbar_search_toolbar() { $search_field_placeholder = t('Search for menu links'); $search_field_title_attribute = t('Type text to search for menu links in the admin toolbar.'); // Render array of properties for the admin search tab menu link, when it is // *not* displayed directly in the toolbar or as a fallback for mobile search. $administration_search_tab_link = [ '#type' => 'link', '#title' => $search_field_title, // Since the search field is handled with JS, the tab does not need a link. '#url' => Url::fromRoute('<nolink>'), '#attributes' => [ 'class' => [ 'toolbar-icon', // Ensure the toolbar items are rebuilt when the user permissions or module's // settings change and keep the render arrays cached. $toolbar_search_item_cache = [ 'contexts' => [ 'user.permissions', ], 'tags' => [ 'config:admin_toolbar_search.settings', ], ]; // Render array of properties for the admin toolbar search JS autocomplete Loading @@ -92,6 +96,24 @@ function admin_toolbar_search_toolbar() { // Add the admin toolbar search as a toolbar item render array. $items['administration_search'] = [ '#type' => 'toolbar_item', 'tab' => [ // Render array of properties for the admin search tab menu link, when it // is *not* displayed directly in the toolbar or as a fallback for mobile. '#type' => 'link', '#title' => $search_field_title, // Since the search field is handled with JS, there is no link url for the // tab, so a simple 'span' element could be used instead. '#url' => Url::fromRoute('<nolink>'), '#attributes' => [ 'class' => [ // Ensures compatibility with Drupal core toolbar styles for the // search tab magnifying glass icon. 'toolbar-icon', ], ], ], // Move the search tab to the end of the toolbar items, by default. '#weight' => 110, // Set the ID of the HTML element wrapping the toolbar item. '#wrapper_attributes' => [ 'id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_tab'], Loading @@ -99,7 +121,7 @@ function admin_toolbar_search_toolbar() { // Load the required JS library and settings by default. '#attached' => [ 'library' => [ 'admin_toolbar_search/search', 'admin_toolbar_search/admin_toolbar_search', ], // Add a setting to determine if extra links should be loaded via AJAX. 'drupalSettings' => [ Loading @@ -108,24 +130,13 @@ function admin_toolbar_search_toolbar() { ], ], ], // Ensure the toolbar item is rebuilt when the user permissions or module's // settings change and keep this render array cached. '#cache' => [ 'contexts' => [ 'user.permissions', ], 'tags' => [ 'config:admin_toolbar_search.settings', ], ], // Set the cache metadata for the administration search toolbar item. '#cache' => $toolbar_search_item_cache, ]; // Add the keyboard shortcut library if enabled ('enable_keyboard_shortcut'). if ($admin_toolbar_search_settings->get('enable_keyboard_shortcut')) { $items['administration_search']['#attached']['library'][] = 'admin_toolbar_search/search.keyboard_shortcut'; // The display menu item setting is used to determine if the search input // should be displayed as a menu item or directly in the toolbar. $items['administration_search']['#attached']['drupalSettings']['adminToolbarSearch']['displayMenuItem'] = $display_menu_item; $items['administration_search']['#attached']['library'][] = 'admin_toolbar_search/admin_toolbar_search.keyboard_shortcut'; // Add the keyboard shortcut label to the search field placeholder and // title attributes. Loading @@ -136,39 +147,39 @@ function admin_toolbar_search_toolbar() { ]); } // Build the toolbar item depending on the whether it is displayed as a menu // item with a tray or directly in the toolbar ('display_menu_item' setting). if ($display_menu_item) { // The search field is displayed in a specific Tray under the Search Tab. $items['administration_search'] += [ 'tab' => $administration_search_tab_link, 'tray' => $administration_search_field, ]; } else { // Reduce the size and hide the label of the search input field. $administration_search_field['search']['#title_display'] = 'invisible'; $administration_search_field['search']['#size'] = 30; // The search field is always displayed in a specific tray under the 'Search' // tab menu item. This tab is hidden or shown with CSS styles depending on the // toolbar width breakpoint and the 'display_menu_item' setting. $items['administration_search']['tray'] = $administration_search_field; // Add the autocomplete search field directly in the toolbar by default, as // a toolbar item ('display_menu_item:false'). if (!$display_menu_item) { // The search field is displayed directly in the Toolbar without a tray. $items['administration_search'] += [ '#weight' => 110, 'tab' => $administration_search_field, ]; // Add toolbar item render array for the mobile search tab that displays the // search field in a custom tray, see module's CSS for styling. The display // of the mobile search tab is toggled with a CSS breakpoint at 769px. $items['administration_mobile_search'] = [ $items['administration_search_field'] = [ '#type' => 'toolbar_item', 'tab' => $administration_search_tab_link, // It is important the mobile search tab is displayed *before* the search // toolbar item otherwise module's CSS rules will not work. // Display the search field directly in the toolbar tab: Modify the search // field properties for the toolbar item by merging the new options with // the existing ones. 'tab' => NestedArray::mergeDeep($administration_search_field, [ 'search' => [ // Reduce the size and hide the label of the search input field. '#size' => 30, '#title_display' => 'invisible', // Set a different HTML ID for the search input field when displayed // directly in the toolbar. '#id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_field_input'], ], ]), // The search field toolbar item should be right before the main search // tab so it stays at the same position when the tab is hidden or shown. '#weight' => $items['administration_search']['#weight'] - 1, // Set the ID of the HTML element wrapping the toolbar item. '#wrapper_attributes' => [ 'id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_tab_mobile'], 'id' => AdminToolbarSearchConstants::ADMIN_TOOLBAR_SEARCH_HTML_IDS['search_field_tab'], ], // Set the cache metadata for the admin search field toolbar item. '#cache' => $toolbar_search_item_cache, ]; } Loading
admin_toolbar_search/css/admin_toolbar_search.css +42 −46 Original line number Diff line number Diff line /* CSS styles for the Admin Toolbar Search module. */ /* Styles for the search tab menu link and the mobile search tab. */ #admin-toolbar-search-tab, #admin-toolbar-mobile-search-tab { /* Styles for the search tab menu link used for desktop and mobile. */ #admin-toolbar-search-tab { /* Add a small magnifier icon before the search tab link. */ .toolbar-item { display: block; Loading @@ -13,41 +12,31 @@ } } /* Styles for the mobile search tab and its interaction with the search tab. */ #admin-toolbar-mobile-search-tab { /* These styles only work if the mobile tab is before the search tab. */ ~ #admin-toolbar-search-tab { /* Show the search tab and hide the search field by default on mobile. */ display: none; /* Set the search field to full width when visible. */ &.visible { display: block; width: 100%; } /* Add padding to the wrapper around the search label and input field. */ .js-form-item { margin: 0; padding: 0.3rem 1rem; } /* Make the search input field take the full width on mobile. */ #admin-toolbar-search-input { width: 100%; } } } /* Styles for the search JS autocomplete input text field. */ #admin-toolbar-search-input { /* Styles for the search JS autocomplete input text fields. */ #admin-toolbar-search-input, #admin-toolbar-search-field-input { height: 100%; min-height: 1.875rem; margin: 0; padding: 0 0.4rem; padding: 0 0.5rem; color: #3b3b3b; border: 1px solid #ccc; border-radius: unset; background: #fcfcfa; font-size: 0.813rem; line-height: 1.75rem; font-size: 0.8125rem; line-height: 1.625rem; } /* Styles for the field tab and its interactions with the search tab. */ #admin-toolbar-search-field-tab { /* Hide the field tab and show the search tab by default on mobile. */ display: none; .form-item { /* Unset default form item margin to prevent a scrollbar from appearing. */ margin-block: auto; /* Add padding to the wrapper around the search label and input field. */ padding: 0.3125rem 1rem; } } /* Styles for the autocomplete suggestion list. Class added through the JS. */ Loading @@ -56,7 +45,7 @@ vertical scrolling if needed. */ overflow-y: scroll; max-height: 18.75rem; font-size: 0.7rem; font-size: 0.8125rem; /* Styles for each suggestion item in the autocomplete list. */ .ui-menu-item { Loading Loading @@ -88,39 +77,46 @@ /* Styles for the search form within the admin toolbar tray. */ #toolbar-item-administration-search-tray { /* Add margin to the wrapper around the search label and input field. */ .js-form-item { margin: 0.6rem; .form-item { /* Unset default form item margin. */ margin-block: auto; /* Add padding to the wrapper around the search label and input field. */ padding: 0.625rem; } /* Basic styles for the search label and input field. */ label { display: inline-block; margin-right: 0.45rem; margin-right: 0.5rem; color: #000; font-weight: bold; } input { display: inline-block; padding: 0.3rem 0.5rem; font-size: 0.86rem; padding: 0.3125rem 0.5rem; font-size: 0.85rem; } } /* Mobile first media query for screens wider than 769px (desktop, tablets). */ @media only screen and (min-width: 769px) { .admin-toolbar-search-autocomplete-list { /* Increase font size of autocomplete suggestions for wider screens. */ font-size: 1rem; } #admin-toolbar-mobile-search-tab { /* Hide the mobile search tab on wider screens by default. */ display: none; /* Display the search field and adjust its styles for wider screens. */ ~ #admin-toolbar-search-tab { /* Display the search field and and hide the search tab for wider screens. */ #admin-toolbar-search-field-tab { display: block; /* Reset width to auto for wider screens so it fits in the toolbar. */ &.visible { width: auto; /* These styles only work if the search field is before the search tab. */ ~ #admin-toolbar-search-tab { /* Hide the search tab when the field tab is visible on wider screens. */ display: none; } } /* Add a bit more margin space on the left of the search label in the toolbar tray when displayed on wider screens ('display menu item'). */ #toolbar-item-administration-search-tray { label { margin-left: 0.45rem; } } }
admin_toolbar_search/js/admin_toolbar_search.js +12 −11 Original line number Diff line number Diff line Loading @@ -23,14 +23,14 @@ $(elements).each(function () { $self.links = []; var $searchTab = $(this).find('#admin-toolbar-search-tab') var $searchInput = $searchTab.find('#admin-toolbar-search-input'); var $searchInputs = $(this).find('#admin-toolbar-search-input, #admin-toolbar-search-field-input'); if ($searchInput.length === 0) { if ($searchInputs.length === 0) { return; } $searchInput.autocomplete({ $searchInputs.each(function (index, $searchInput) { $($searchInput).autocomplete({ minLength: 2, position: { collision : 'fit' }, source: function (request, response) { Loading Loading @@ -72,18 +72,19 @@ .append('<div ><a href="' + item.value + '">' + item.labelRaw + ' <span class="admin-toolbar-search-url">' + item.value + '</span></a></div>') .appendTo(ul); }); }); // Populate the links for search results when the input is pressed. $searchInput.focus(function () { $searchInputs.focus(function () { Drupal.behaviors.adminToolbarSearch.populateLinks($self); }); // Show/hide search input field when mobile tab item is pressed. $('#admin-toolbar-mobile-search-tab .toolbar-item', context).click(function (e) { // Focus the search input field when the search tab is pressed. context.querySelector('#admin-toolbar-search-tab .toolbar-item') .addEventListener('click', (e) => { e.preventDefault(); $(this).toggleClass('is-active'); $searchTab.toggleClass('visible'); $searchInput.focus(); const searchTabTray = e.target.nextElementSibling; searchTabTray.classList.toggle('is-active'); searchTabTray.querySelector('#admin-toolbar-search-input').focus(); }); }); }, Loading
admin_toolbar_search/js/admin_toolbar_search.keyboard_shortcut.js +32 −11 Original line number Diff line number Diff line Loading @@ -7,6 +7,10 @@ /** * Implements the Admin Toolbar Search configured keyboard shortcut. * * Depending on whether the search input field is displayed as a toolbar * menu tray or as a standalone input field, the behavior will focus on the * appropriate element when the keyboard shortcut is triggered. * * @type {Drupal~behavior} * * @prop {Drupal~behaviorAttach} attach Loading @@ -14,7 +18,7 @@ * shortcut combination of keys, currently defaults to: 'Alt + a'. */ Drupal.behaviors.adminToolbarSearchKeyboardShortcut = { attach: (context, settings) => { attach: (context) => { if (context !== document) { return; } Loading @@ -26,18 +30,35 @@ // Shortcut 'Alt + a' will focus on the search form. document.addEventListener('keydown', (event) => { if (event.altKey && (event.key === 'a' || event.keyCode === 65)) { const searchInputField = context.getElementById( 'admin-toolbar-search-input', // Get the search tab which should *always* be loaded. const searchTab = context.getElementById( 'admin-toolbar-search-tab', ); // Get the computed style of the search tab to check if it is // visible based on the toolbar width breakpoint. const searchTabStyle = window.getComputedStyle(searchTab); // Get the search field tab which could be empty ('null') if the // setting 'display_menu_item' is enabled. const searchFieldTab = context.getElementById( 'admin-toolbar-search-field-tab', ); // If the search input field is displayed as a toolbar menu tray, // toggle the toolbar item so the field could be focused. if (settings.adminToolbarSearch.displayMenuItem) { searchInputField .closest('.toolbar-tab') .querySelector('.toolbar-item') .click(); // If the search field tab is loaded and the search tab is not // visible, focus on the search input field directly. if (searchFieldTab !== null && searchTabStyle.display === 'none') { searchFieldTab .querySelector('#admin-toolbar-search-field-input') .focus(); } else { // If the search input field is displayed as a toolbar menu tray // and is not visible, toggle its display to focus its field. const searchTabToolbarItem = searchTab.querySelector('.toolbar-item'); if (!searchTabToolbarItem.classList.contains('is-active')) { searchTabToolbarItem.click(); } searchTab.querySelector('#admin-toolbar-search-input').focus(); } searchInputField.focus(); // Don't transmit the keystroke. event.preventDefault(); } Loading