Skip to content

Commit

Permalink
Move duplicated fn of gs to helpers (#3802)
Browse files Browse the repository at this point in the history
* Move duplicated fn of GS to helpers

* Move duplicated fn of GS to helpers

* Remove unused const

* Fix for displaySearchResult

* Fix keyDown and Escape and add unit test

* Fix keyDown and Escape and add unit test

* Apply Prettier

* Update variable names -luigiCustomSearchItemRenderer__slot and luigiCustomSearchItemRenderer__slotContainer

* Variable name update

* Update core/src/utilities/helpers/global-search-helpers.js

Co-authored-by: Johannes Doberer <[email protected]>

* Update core/src/utilities/helpers/global-search-helpers.js

Co-authored-by: Johannes Doberer <[email protected]>

---------

Co-authored-by: Anna Milewska <[email protected]>
Co-authored-by: Johannes Doberer <[email protected]>
Co-authored-by: Waldemar Mazurek <[email protected]>
  • Loading branch information
4 people authored Jul 8, 2024
1 parent 7ed726c commit 1cc7493
Show file tree
Hide file tree
Showing 6 changed files with 554 additions and 341 deletions.
14 changes: 7 additions & 7 deletions core/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
export let isSearchFieldVisible;
export let inputElem;
export let luigiCustomSearchRenderer__slot;
export let customSearchItemRendererSlot;
export let displaySearchResult;
export let searchResult;
export let storedUserSettings;
Expand Down Expand Up @@ -556,7 +556,7 @@
searchProvider.onSearchResultItemSelected(item);
}
};
searchProvider.customSearchResultRenderer(arr, luigiCustomSearchRenderer__slot, searchApiObj);
searchProvider.customSearchResultRenderer(arr, customSearchItemRendererSlot, searchApiObj);
} else {
displaySearchResult = true;
searchResult = arr;
Expand All @@ -571,9 +571,9 @@
if (checkSearchProvider(searchProvider)) {
displaySearchResult = false;
searchResult = [];
if (luigiCustomSearchRenderer__slot) {
while (luigiCustomSearchRenderer__slot.lastElementChild) {
luigiCustomSearchRenderer__slot.removeChild(luigiCustomSearchRenderer__slot.lastElementChild);
if (customSearchItemRendererSlot) {
while (customSearchItemRendererSlot.lastElementChild) {
customSearchItemRendererSlot.removeChild(customSearchItemRendererSlot.lastElementChild);
}
}
}
Expand Down Expand Up @@ -1880,7 +1880,7 @@
bind:displaySearchResult
bind:searchResult
bind:inputElem
bind:luigiCustomSearchRenderer__slot
bind:customSearchItemRendererSlot
{burgerTooltip}
/>
{/if}
Expand Down Expand Up @@ -2003,7 +2003,7 @@
bind:displaySearchResult
bind:searchResult
bind:inputElem
bind:luigiCustomSearchRenderer__slot
bind:customSearchItemRendererSlot
{burgerTooltip}
/>
{/if}
Expand Down
188 changes: 23 additions & 165 deletions core/src/navigation/GlobalSearch.svelte
Original file line number Diff line number Diff line change
@@ -1,190 +1,48 @@
<script>
import { beforeUpdate, createEventDispatcher, onMount } from 'svelte';
import { LuigiI18N } from '../core-api';
import { GenericHelpers } from '../utilities/helpers';
import { Routing } from '../services/routing';
import { KEYCODE_ARROW_UP, KEYCODE_ARROW_DOWN, KEYCODE_ENTER, KEYCODE_ESC } from '../utilities/keycode.js';
import { GlobalSearchHelperClass } from '../utilities/helpers/global-search-helpers';
export let isSearchFieldVisible;
export let searchResult = [];
export let displaySearchResult;
export let inputElem;
export let luigiCustomSearchRenderer__slot;
export let luigiCustomSearchItemRenderer__slotContainer;
export let customSearchItemRendererSlot;
export let customSearchItemRendererSlotContainer;
export let globalSearchConfig;
const dispatch = createEventDispatcher();
const searchApiObj = {
fireItemSelected: item => {
search.searchProvider.onSearchResultItemSelected(item);
}
};
let search = {};
let isCustomSearchRenderer;
let isCustomSearchResultItemRenderer;
let globalSearchHelper;
onMount(async () => {
search = globalSearchConfig;
let inputElement = inputElem;
const placeHolder = getSearchPlaceholder(search.searchProvider);
if (placeHolder) {
inputElement.placeholder = placeHolder;
}
getCustomRenderer();
globalSearchHelper.setSearchPlaceholder(inputElem);
globalSearchHelper.getCustomRenderer();
});
beforeUpdate(() => {
search = globalSearchConfig;
getCustomRenderer();
});
function getCustomRenderer() {
if (!search.searchProvider) return;
isCustomSearchRenderer = GenericHelpers.isFunction(search.searchProvider.customSearchResultRenderer);
isCustomSearchResultItemRenderer = GenericHelpers.isFunction(search.searchProvider.customSearchResultItemRenderer);
}
function getSearchPlaceholder(searchProvider) {
if (!searchProvider || !searchProvider.inputPlaceholder) {
return undefined;
}
const currentLocale = LuigiI18N.getCurrentLocale();
if (GenericHelpers.isFunction(searchProvider.inputPlaceholder)) {
return searchProvider.inputPlaceholder();
}
if (typeof searchProvider.inputPlaceholder === 'string') {
const translated = LuigiI18N.getTranslation(searchProvider.inputPlaceholder);
if (!!translated && translated.trim().length > 0) {
return translated;
}
return searchProvider.inputPlaceholder;
}
if (typeof searchProvider.inputPlaceholder === 'object') {
return searchProvider.inputPlaceholder[currentLocale];
if (!globalSearchHelper) {
globalSearchHelper = new GlobalSearchHelperClass(search, dispatch);
}
}
function renderCustomSearchItem(item, slotContainer, index) {
setTimeout(() => {
search.searchProvider.customSearchResultItemRenderer(item, slotContainer.children[index], searchApiObj);
});
return '';
}
globalSearchHelper.getCustomRenderer();
});
function closeSearchResult() {
dispatch('closeSearchResult');
}
function onKeyUp({ keyCode }) {
if (search && search.searchProvider) {
if (GenericHelpers.isFunction(search.searchProvider.onEnter) && keyCode === KEYCODE_ENTER) {
search.searchProvider.onEnter();
} else if (GenericHelpers.isFunction(search.searchProvider.onEscape) && keyCode === KEYCODE_ESC) {
search.searchProvider.onEscape();
} else if (keyCode === KEYCODE_ARROW_DOWN) {
if (displaySearchResult) {
document.querySelector('.luigi-search-result-item__0').childNodes[0].setAttribute('aria-selected', 'true');
document.querySelector('.luigi-search-result-item__0').focus();
}
} else if (GenericHelpers.isFunction(search.searchProvider.onInput)) {
search.searchProvider.onInput();
}
} else {
console.warn('GlobalSearch is not available.');
}
}
function calcSearchResultItemSelected(direction) {
let renderedSearchResultItems = luigiCustomSearchItemRenderer__slotContainer.children;
if (renderedSearchResultItems) {
for (let index = 0; index < renderedSearchResultItems.length; index++) {
let { childNodes, nextSibling, previousSibling } = renderedSearchResultItems[index];
let nodeSibling;
if (childNodes[0].getAttribute('aria-selected') === 'true') {
if (direction === KEYCODE_ARROW_DOWN) {
nodeSibling = nextSibling !== null ? nextSibling : renderedSearchResultItems[0];
}
if (direction === KEYCODE_ARROW_UP) {
nodeSibling =
previousSibling !== null
? previousSibling
: renderedSearchResultItems[renderedSearchResultItems.length - 1];
}
childNodes[0].setAttribute('aria-selected', 'false');
nodeSibling.childNodes[0].setAttribute('aria-selected', 'true');
nodeSibling.focus();
break;
}
}
}
globalSearchHelper.closeSearchResult();
}
function clearAriaSelected() {
let renderedSearchResultItems = luigiCustomSearchItemRenderer__slotContainer.children;
if (renderedSearchResultItems) {
for (let index = 0; index < renderedSearchResultItems.length; index++) {
let element = renderedSearchResultItems[index];
if (element.childNodes[0].getAttribute('aria-selected') === 'true') {
element.childNodes[0].setAttribute('aria-selected', 'false');
}
}
}
function onKeyUp(event) {
globalSearchHelper.onKeyUp(event, displaySearchResult);
}
function onSearchResultItemSelected(searchResultItem) {
if (search && GenericHelpers.isFunction(search.searchProvider.onSearchResultItemSelected)) {
search.searchProvider.onSearchResultItemSelected(searchResultItem);
} else if (GenericHelpers.isFunction(search.searchProvider.onEscape) && event.keyCode === KEYCODE_ESC) {
search.searchProvider.onEscape();
}
}
function handleKeydown(result, { keyCode }) {
if (keyCode === KEYCODE_ENTER) {
search.searchProvider.onSearchResultItemSelected(result);
}
if (keyCode === KEYCODE_ARROW_UP || keyCode === KEYCODE_ARROW_DOWN) {
calcSearchResultItemSelected(keyCode);
} else if (GenericHelpers.isFunction(search.searchProvider.onEscape) && keyCode === KEYCODE_ESC) {
clearAriaSelected();
setTimeout(() => {
inputElem.focus();
});
search.searchProvider.onEscape();
}
function handleKeydown(result, event) {
globalSearchHelper.handleKeydown(result, event, inputElem, customSearchItemRendererSlotContainer);
}
export function onActionClick(searchResultItem) {
let node = searchResultItem.pathObject;
if (node.externalLink) {
Routing.navigateToLink(node);
} else {
dispatch('handleSearchNavigation', { node });
}
}
function setFocusOnGlobalSearchFieldDesktop() {
if (inputElem) {
inputElem.focus();
}
globalSearchHelper.onActionClick(searchResultItem);
}
export function toggleSearch() {
if (!isSearchFieldVisible)
setTimeout(() => {
setFocusOnGlobalSearchFieldDesktop();
});
else {
displaySearchResult = false;
}
dispatch('toggleSearch', {
isSearchFieldVisible,
inputElem,
luigiCustomSearchRenderer__slot
});
if (search && search.searchProvider && GenericHelpers.isFunction(search.searchProvider.toggleSearch)) {
const fieldVisible = isSearchFieldVisible === undefined ? true : !isSearchFieldVisible;
search.searchProvider.toggleSearch(inputElem, fieldVisible);
}
globalSearchHelper.toggleSearch(isSearchFieldVisible, displaySearchResult, inputElem, customSearchItemRendererSlot);
}
</script>

Expand Down Expand Up @@ -223,23 +81,23 @@
{/if}
<div class="fd-shellbar__search-field-helper" />
</div>
{#if !isCustomSearchRenderer}
{#if !globalSearchHelper.isCustomSearchRenderer}
<div
class="fd-popover__body fd-popover__body--right luigi-search-popover__body"
aria-hidden={!displaySearchResult}
>
<nav class="fd-menu">
{#if searchResult}
<ul class="fd-menu__list fd-menu__list--top" bind:this={luigiCustomSearchItemRenderer__slotContainer}>
<ul class="fd-menu__list fd-menu__list--top" bind:this={customSearchItemRendererSlotContainer}>
{#each searchResult as result, index}
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<li
class="fd-menu__item luigi-search-result-item__{index}"
on:click={event => onSearchResultItemSelected(result, event)}
on:click={event => globalSearchHelper.onSearchResultItemSelected(result, event)}
on:keyup={event => handleKeydown(result, event)}
tabindex="0"
>
{#if !isCustomSearchResultItemRenderer}
{#if !globalSearchHelper.isCustomSearchResultItemRenderer}
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-missing-attribute -->
<a class="fd-menu__link" on:click|preventDefault={() => {}}>
Expand All @@ -249,7 +107,7 @@
</div>
</a>
{:else}
{@html renderCustomSearchItem(result, luigiCustomSearchItemRenderer__slotContainer, index)}
{@html globalSearchHelper.renderCustomSearchItem(result, customSearchItemRendererSlotContainer, index)}
{/if}
</li>
{/each}
Expand All @@ -258,7 +116,7 @@
</nav>
</div>
{:else}
<div bind:this={luigiCustomSearchRenderer__slot} />
<div bind:this={customSearchItemRendererSlot} />
{/if}
</div>
</div>
Expand Down
Loading

0 comments on commit 1cc7493

Please sign in to comment.