Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement: auto focus search #3271

Open
Blargian opened this issue Feb 16, 2025 · 7 comments
Open

Improvement: auto focus search #3271

Blargian opened this issue Feb 16, 2025 · 7 comments
Assignees
Labels
good first issue missing or needs improvement Docs that are not written, or not complete P3

Comments

@Blargian
Copy link
Member

Issue:

When using the Algolia search popup, the search bar does not focus automatically.

Desired behaviour:

the search input should automatically focus when the pop up opens.

steps to reproduce:

  • Open the ClickHouse docs page using a new Chrome tab (https://clickhouse.com/docs)
  • Press CMD+K (this opens the Algolia search popup). However, the text input box in the popup is not automatically focused.
  • Manually click on the text input box.
  • Type in a string to filter the content.
@Blargian Blargian added good first issue missing or needs improvement Docs that are not written, or not complete labels Feb 16, 2025
@gneo0
Copy link

gneo0 commented Feb 17, 2025

I would love to help solve that issue. Would you like assigning it to me?

@gneo0
Copy link

gneo0 commented Feb 18, 2025

I've been investigating this issue and noticed that the text input of Algolia search popup focuses correctly. The problem of this happens when the user presses Ctrl + K on the initial render, the Algolia search popup is being rendered three times instead of once. However, on initial render clicking inside the search input once to trigger Algolia popup, after closing the Algolia search popup and then pressing Ctrl + K works correctly and renders the Algolia search popup only once as expected.

How to reproduce that:

  1. On initial render of Clickhouse docs, press Ctrl + K.
  2. Type some text on your keyboard.
  3. Then, click two times on background div element of Algolia popup like you are going to close it.
  4. Now, you must be able to see the text that you had typed.

I suspect that the event listener for Ctrl + K might be attached multiple times, but I haven't been able to locate where this event is handled in the codebase.

If anyone is familiar with how the Algolia search popup is triggered, could you point me to the relevant file/component? Any help would be greatly appreciated!

Thanks in advance!

@Blargian
Copy link
Member Author

Hey @gneo0, appreciate you picking this up! The handler for the search is here I believe:

const handleClick = () => {
if (hit.queryID) {
aa('clickedObjectIDsAfterSearch', {
eventName: 'Search Result Clicked',
index: hit.__autocomplete_indexName,
queryID: hit.queryID,
objectIDs: [hit.objectID],
positions: [hit.index+1], // algolia indexes from 1
});
}
};
return <Link onClick={handleClick} to={hit.url}>{children}</Link>;

It's also used here for the knowledge base page search, but without an event handler.

<SearchBar className={styles.blogsSearch}/>

@gneo0
Copy link

gneo0 commented Feb 19, 2025

Hey @Blargian , the bug doesn't appear when user clicks on search bar but on Ctrl + K keydown event happens and only at the initial render of the clickhouse docs website. The problem is that I can't locate where on the code this keydown event happens. Thanks for your provided answer and I'm looking forward if you could help me further where Ctrl + K event happens!

@Blargian
Copy link
Member Author

Blargian commented Feb 19, 2025

@gneo0 Apologies, you're right. The event handler itself looks like its defined as part of docsearch. I found it as minified JS only by searching through node_modules for "cmd + k". Unminified reads as:

function useDocSearchKeyboardEvents({
  isOpen,
  onOpen,
  onClose,
  onInput,
  searchButtonRef,
}: { // UseDocSearchKeyboardEventsProps - this type was missing
  isOpen: boolean;
  onOpen: () => void;
  onClose: () => void;
  onInput: (event: KeyboardEvent) => void;
  searchButtonRef: React.RefObject<HTMLButtonElement>;
}): void {
  React.useEffect(() => {
    function onKeyDown(event: KeyboardEvent): void {
      const isEditingContent = (event: KeyboardEvent): boolean => {
        // Check if the user is currently editing content in an input, textarea, or select element.
        const activeElement = document.activeElement;
        if (activeElement instanceof HTMLInputElement ||
            activeElement instanceof HTMLTextAreaElement ||
            activeElement instanceof HTMLSelectElement) {
            return true;
        }
        return false;
      };

      if (
        (event.code === 'Escape' && isOpen) ||
        // The `Cmd+K` shortcut both opens and closes the modal.
        // We need to check for `event.key` because it can be `undefined` with
        // Chrome's autofill feature.
        // See https://github.com/paperjs/paper.js/issues/1398
        (event.key?.toLowerCase() === 'k' && (event.metaKey || event.ctrlKey)) ||
        // The `/` shortcut opens but doesn't close the modal because it's
        // a character.
        (!isEditingContent(event) && event.key === '/' && !isOpen)
      ) {
        event.preventDefault();

        if (isOpen) {
          onClose();
        } else if (!document.body.classList.contains('DocSearch--active')) {
          // We check that no other DocSearch modal is showing before opening
          // another one.
          onOpen();
        }

        return;
      }

      if (searchButtonRef && searchButtonRef.current === document.activeElement && onInput) {
        if (/[a-zA-Z0-9]/.test(String.fromCharCode(event.keyCode))) {
          onInput(event);
        }
      }
    }

    window.addEventListener('keydown', onKeyDown);

    return (): void => {
      window.removeEventListener('keydown', onKeyDown);
    };
  }, [isOpen, onOpen, onClose, onInput, searchButtonRef]);
}

We import this function in src/theme/SearchBar/index.js and use it here:

useDocSearchKeyboardEvents({
isOpen,
onOpen,
onClose,
onInput,
searchButtonRef,
});

@gneo0
Copy link

gneo0 commented Feb 20, 2025

Hmm, great point @Blargian. So this bug should happen from Algolia? What's your thinking about that??

@Blargian
Copy link
Member Author

Hmm, great point @Blargian. So this bug should happen from Algolia? What's your thinking about that??

Possible but I'm thinking more likely something wrong with the way we are using the component. DocSearch is quite commonly used so I would imagine this issue would be raised already if it was an algolia bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue missing or needs improvement Docs that are not written, or not complete P3
Projects
None yet
Development

No branches or pull requests

3 participants