diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-18 11:17:02 +0300 |
commit | b39512ed755239198a9c294b6a45e65c05900235 (patch) | |
tree | d234a3efade1de67c46b9e5a38ce813627726aa7 /app/assets/javascripts/header_search | |
parent | d31474cf3b17ece37939d20082b07f6657cc79a9 (diff) |
Add latest changes from gitlab-org/gitlab@15-3-stable-eev15.3.0-rc42
Diffstat (limited to 'app/assets/javascripts/header_search')
-rw-r--r-- | app/assets/javascripts/header_search/components/app.vue | 51 | ||||
-rw-r--r-- | app/assets/javascripts/header_search/constants.js | 4 | ||||
-rw-r--r-- | app/assets/javascripts/header_search/index.js | 11 |
3 files changed, 44 insertions, 22 deletions
diff --git a/app/assets/javascripts/header_search/components/app.vue b/app/assets/javascripts/header_search/components/app.vue index 0c4f9640972..f4b939fb20f 100644 --- a/app/assets/javascripts/header_search/components/app.vue +++ b/app/assets/javascripts/header_search/components/app.vue @@ -23,6 +23,9 @@ import { SEARCH_SHORTCUTS_MIN_CHARACTERS, SCOPE_TOKEN_MAX_LENGTH, INPUT_FIELD_PADDING, + IS_SEARCHING, + IS_FOCUSED, + IS_NOT_FOCUSED, } from '../constants'; import HeaderSearchAutocompleteItems from './header_search_autocomplete_items.vue'; import HeaderSearchDefaultItems from './header_search_default_items.vue'; @@ -65,6 +68,7 @@ export default { data() { return { showDropdown: false, + isFocused: false, currentFocusIndex: SEARCH_BOX_INDEX, }; }, @@ -92,20 +96,18 @@ export default { if (!this.showDropdown || !this.isLoggedIn) { return false; } - return this.searchOptions?.length > 0; }, showDefaultItems() { return !this.searchText; }, - showScopes() { + searchTermOverMin() { return this.searchText?.length > SEARCH_SHORTCUTS_MIN_CHARACTERS; }, defaultIndex() { if (this.showDefaultItems) { return SEARCH_BOX_INDEX; } - return FIRST_DROPDOWN_INDEX; }, @@ -132,12 +134,15 @@ export default { count: this.searchOptions.length, }); }, - searchBarStateIndicator() { - const hasIcon = - this.searchContext?.project || this.searchContext?.group ? 'has-icon' : 'has-no-icon'; - const isSearching = this.showScopes ? 'is-searching' : 'is-not-searching'; - const isActive = this.showSearchDropdown ? 'is-active' : 'is-not-active'; - return `${isActive} ${isSearching} ${hasIcon}`; + searchBarClasses() { + return { + [IS_SEARCHING]: this.searchTermOverMin, + [IS_FOCUSED]: this.isFocused, + [IS_NOT_FOCUSED]: !this.isFocused, + }; + }, + showScopeHelp() { + return this.searchTermOverMin && this.isFocused; }, searchBarItem() { return this.searchOptions?.[0]; @@ -158,11 +163,22 @@ export default { ...mapActions(['setSearch', 'fetchAutocompleteOptions', 'clearAutocomplete']), openDropdown() { this.showDropdown = true; - this.$emit('toggleDropdown', this.showDropdown); + this.isFocused = true; + this.$emit('expandSearchBar', true); }, closeDropdown() { this.showDropdown = false; - this.$emit('toggleDropdown', this.showDropdown); + }, + collapseAndCloseSearchBar() { + // we need a delay on this method + // for the search bar not to remove + // the clear button from dom + // and register clicks on dropdown items + setTimeout(() => { + this.showDropdown = false; + this.isFocused = false; + this.$emit('collapseSearchBar'); + }, 200); }, submitSearch() { if (this.search?.length <= SEARCH_SHORTCUTS_MIN_CHARACTERS && this.currentFocusIndex < 0) { @@ -171,6 +187,7 @@ export default { return visitUrl(this.currentFocusedOption?.url || this.searchQuery); }, getAutocompleteOptions: debounce(function debouncedSearch(searchTerm) { + this.openDropdown(); if (!searchTerm) { this.clearAutocomplete(); } else { @@ -201,7 +218,7 @@ export default { role="search" :aria-label="$options.i18n.searchGitlab" class="header-search gl-relative gl-rounded-base gl-w-full" - :class="searchBarStateIndicator" + :class="searchBarClasses" data-testid="header-search-form" > <gl-search-box-by-type @@ -217,12 +234,13 @@ export default { :aria-describedby="$options.SEARCH_INPUT_DESCRIPTION" @focus="openDropdown" @click="openDropdown" + @blur="collapseAndCloseSearchBar" @input="getAutocompleteOptions" @keydown.enter.stop.prevent="submitSearch" @keydown.esc.stop.prevent="closeDropdown" /> <gl-token - v-if="showScopes" + v-if="showScopeHelp" v-gl-resize-observer-directive="observeTokenWidth" class="in-search-scope-help" :view-only="true" @@ -242,6 +260,7 @@ export default { }} </gl-token> <kbd + v-show="!isFocused" v-gl-tooltip.bottom.hover.html class="gl-absolute gl-right-3 gl-top-0 gl-z-index-1 keyboard-shortcut-helper" :title="$options.i18n.kbdHelp" @@ -262,9 +281,9 @@ export default { <div v-if="showSearchDropdown" data-testid="header-search-dropdown-menu" - class="header-search-dropdown-menu gl-absolute gl-w-full gl-bg-white gl-border-1 gl-rounded-base gl-border-solid gl-border-gray-200 gl-shadow-x0-y2-b4-s0" + class="header-search-dropdown-menu gl-overflow-y-auto gl-absolute gl-w-full gl-bg-white gl-border-1 gl-rounded-base gl-border-solid gl-border-gray-200 gl-shadow-x0-y2-b4-s0 gl-mt-3" > - <div class="header-search-dropdown-content gl-overflow-y-auto gl-py-2"> + <div class="header-search-dropdown-content gl-py-2"> <dropdown-keyboard-navigation v-model="currentFocusIndex" :max="searchOptions.length - 1" @@ -278,7 +297,7 @@ export default { /> <template v-else> <header-search-scoped-items - v-if="showScopes" + v-if="searchTermOverMin" :current-focused-option="currentFocusedOption" /> <header-search-autocomplete-items :current-focused-option="currentFocusedOption" /> diff --git a/app/assets/javascripts/header_search/constants.js b/app/assets/javascripts/header_search/constants.js index a026386b2bd..3a20fb0216d 100644 --- a/app/assets/javascripts/header_search/constants.js +++ b/app/assets/javascripts/header_search/constants.js @@ -51,3 +51,7 @@ export const SCOPE_TOKEN_MAX_LENGTH = 36; export const INPUT_FIELD_PADDING = 52; export const HEADER_INIT_EVENTS = ['input', 'focus']; + +export const IS_SEARCHING = 'is-searching'; +export const IS_FOCUSED = 'is-focused'; +export const IS_NOT_FOCUSED = 'is-not-focused'; diff --git a/app/assets/javascripts/header_search/index.js b/app/assets/javascripts/header_search/index.js index b2c505d569f..f6f5c6a14fa 100644 --- a/app/assets/javascripts/header_search/index.js +++ b/app/assets/javascripts/header_search/index.js @@ -26,12 +26,11 @@ export const initHeaderSearchApp = (search = '') => { render(createElement) { return createElement(HeaderSearchApp, { on: { - toggleDropdown: (isVisible = false) => { - if (isVisible) { - navBarEl?.classList.add('header-search-is-active'); - } else { - navBarEl?.classList.remove('header-search-is-active'); - } + expandSearchBar: () => { + navBarEl?.classList.add('header-search-is-active'); + }, + collapseSearchBar: () => { + navBarEl?.classList.remove('header-search-is-active'); }, }, }); |