PageSourceSearch

https://www.ul.ie/themes/custom/ul_lite/components/header-search/header-search.js?tlq4h2

js ul.ie collected 2026-10-01 08:40:38 UTC 3,250 bytes, 77 lines download raw bytes

1/**
2 * Show, focus and dismiss the header search input.
3 */
4((Drupal) => {
5  Drupal.behaviors.headerSearch = {
6    attach(context) {
7
8      // Only run if the relevant search input is found.
9      if (context.querySelector('#header-search')) {
10
11        // Get the necessary elements.
12        const searchDisplay = context.querySelector('#header-search-show');
13        const searchDismiss = context.querySelector('#header-search-dismiss');
14        const searchDismissIcon = context.querySelector('#search-dismiss-icon');
15        const searchElement = context.querySelector('#header-search');
16        const searchInput = context.querySelector('#header-search-input');
17        const searchTrigger = context.querySelector('#header-search-trigger');
18        const headerActions = context.querySelector('#header-actions');
19
20        // Disable tabbing until visible, to prevent layout shift.
21        searchInput.tabIndex = '-1';
22        searchDismiss.tabIndex = '-1';
23        searchTrigger.tabIndex = '-1';
24
25        // Run the rotate transform while invisible to avoid sluggishness on first trigger.
26        searchDismissIcon.style.transform = 'rotate(360deg)';
27
28        // Show and focus the header search input.
29        function handleSearchDisplay() {
30          headerActions.classList.add('opacity-0');
31          searchElement.classList.remove('translate-x-full');
32          searchElement.classList.remove('opacity-0');
33          searchDismissIcon.style.transform = 'rotate(-360deg)';
34
35          // Allow relevant elements to receive focus.
36          searchInput.removeAttribute('tabindex');
37          searchDismiss.removeAttribute('tabindex');
38          searchTrigger.removeAttribute('tabindex');
39
40          // Set the focus to the search input.
41          searchInput.focus({ preventScroll: true });
42        }
43
44        // Handle the actual search.
45        function handleSearch() {
46          if (searchInput.value !== '') {
47            window.location = '/global-search?search=' + searchInput.value;
48          }
49        }
50
51        // Dismiss the search element.
52        function handleSearchDismiss() {
53          searchDismissIcon.style.transform = 'rotate(360deg)';
54          setTimeout(() => {
55            headerActions.classList.remove('opacity-0');
56            searchElement.classList.add('translate-x-full');
57            searchElement.classList.add('opacity-0');
58            searchInput.value = '';
59
60            // Prevent focus when dismissed.
61            searchInput.tabIndex = '-1';
62            searchDismiss.tabIndex = '-1';
63            searchTrigger.tabIndex = '-1';
64          }, 200);
65        }
66
67        // Attach the event handlers to both click and keyboard events.
68        searchTrigger.addEventListener('click', handleSearch);
69        searchDisplay.addEventListener('click', handleSearchDisplay);
70        searchDismiss.addEventListener('click', handleSearchDismiss);
71        searchInput.addEventListener('keydown', (event) => { if (event.key === 'Enter') handleSearch() });
72        searchDisplay.addEventListener('keydown', (event) => { if (event.key === 'Enter') handleSearchDisplay() });
73        searchDismiss.addEventListener('keydown', (event) => { if (event.key === 'Enter') handleSearchDismiss() });
74      }
75    }
76  };
77})(Drupal);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.