search: fix tour blocking monaco autocomplete (#26132)

Monaco search autocomplete now shows over the onboarding tour.

This required upgrading Shepherd.js to 8.1+, which adds the `stepsContainer` parameter which allows attaching the tour to someplace other than the end of the body. Attaching the tour to somewhere in the DOM tree above the search box will render the tour before the search box and allow the search box suggestions to show over the tour without any z-index fandangling.

Fixes #25618
This commit is contained in:
Juliana Peña 2021-10-15 13:22:30 -07:00 committed by GitHub
parent 1f99dcc908
commit 2cbf7dbfa0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 16 deletions

View File

@ -1,5 +1,5 @@
import * as H from 'history'
import React, { useState, useCallback, useEffect, useMemo } from 'react'
import React, { useState, useCallback, useEffect, useMemo, useRef } from 'react'
import { Form } from 'reactstrap'
import { ActivationProps } from '@sourcegraph/shared/src/components/activation/Activation'
@ -80,11 +80,14 @@ export const SearchPageInput: React.FunctionComponent<Props> = (props: Props) =>
])
const showOnboardingTour = props.showOnboardingTour && isHomepage
const tourContainer = useRef<HTMLDivElement>(null)
const { shouldFocusQueryInput, ...onboardingTourQueryInputProps } = useSearchOnboardingTour({
...props,
showOnboardingTour,
queryState: userQueryState,
setQueryState: setUserQueryState,
stepsContainer: tourContainer.current ?? undefined,
})
const onSubmit = useCallback(
(event?: React.FormEvent<HTMLFormElement>): void => {
@ -104,6 +107,9 @@ export const SearchPageInput: React.FunctionComponent<Props> = (props: Props) =>
<div className="d-flex flex-row flex-shrink-past-contents">
<Form className="flex-grow-1 flex-shrink-past-contents" onSubmit={onSubmit}>
<div className="search-page__input-container">
{/* Search onboarding tour must be rendered before the SearchBox so
the Monaco autocomplete suggestions are not blocked by the tour. */}
<div ref={tourContainer} />
<SearchBox
{...props}
{...onboardingTourQueryInputProps}

View File

@ -59,6 +59,7 @@ const closeIconSvg =
/**
* Generates the content for the first step in the tour.
*
* @param tour the Shepherd tour to attach the step to
* @param languageButtonHandler the handler for the "search a language" button.
* @param repositoryButtonHandler the handler for the "search a repository" button.
*/
@ -71,8 +72,8 @@ function generateStep1(
content.className = 'd-flex align-items-center'
content.innerHTML = `
<div class="tour-card__title">Get started</div>
<button class="btn btn-link p-0 tour-card__link tour-language-button">Search a language</button>
<button class="btn btn-link p-0 tour-card__link tour-repo-button">Search a repository</button>
<button type="button" class="btn btn-link p-0 tour-card__link tour-language-button">Search a language</button>
<button type="button" class="btn btn-link p-0 tour-card__link tour-repo-button">Search a repository</button>
`
content.querySelector('.tour-language-button')?.addEventListener('click', () => {
languageButtonHandler()
@ -170,8 +171,11 @@ const generateStepContent = (title: string, description: string): HTMLElement =>
return element
}
const useTourWithSteps = ({ setQueryState }: Pick<UseSearchOnboardingTourOptions, 'setQueryState'>): Tour => {
const tour = useMemo(() => new Shepherd.Tour(tourOptions), [])
const useTourWithSteps = ({
setQueryState,
stepsContainer,
}: Pick<UseSearchOnboardingTourOptions, 'setQueryState' | 'stepsContainer'>): Tour => {
const tour = useMemo(() => new Shepherd.Tour({ ...tourOptions, stepsContainer }), [stepsContainer])
useEffect(() => {
tour.addSteps([
{
@ -304,6 +308,11 @@ interface UseSearchOnboardingTourOptions {
queryState: QueryState
history: H.History
location: H.Location
/**
* HTML element where the steps should be attached to
*/
stepsContainer?: HTMLElement
}
/**
@ -330,8 +339,9 @@ export const useSearchOnboardingTour = ({
showOnboardingTour,
queryState,
setQueryState,
stepsContainer,
}: UseSearchOnboardingTourOptions): UseSearchOnboardingTourReturnValue => {
const tour = useTourWithSteps({ setQueryState })
const tour = useTourWithSteps({ setQueryState, stepsContainer })
// True when the user has manually cancelled the tour
const [hasCancelledTour, setHasCancelledTour] = useTemporarySetting('search.onboarding.tourCancelled', false)
const [daysActiveCount] = useTemporarySetting('user.daysActiveCount', 0)

View File

@ -403,7 +403,7 @@
"rxjs": "^6.6.3",
"sanitize-html": "^2.0.0",
"semver": "^7.3.2",
"shepherd.js": "^8.0.2",
"shepherd.js": "^8.3.1",
"string-score": "^1.0.1",
"tabbable": "^5.1.5",
"tagged-template-noop": "^2.1.1",

View File

@ -2862,10 +2862,10 @@
qs "^6.7.0"
url-parse "^1.4.7"
"@popperjs/core@^2.4.4", "@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0":
version "2.9.2"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353"
integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==
"@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0", "@popperjs/core@^2.9.2":
version "2.10.2"
resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==
"@reach/accordion@^0.10.2":
version "0.10.2"
@ -21235,12 +21235,12 @@ shellwords@^0.1.1:
resolved "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
shepherd.js@^8.0.2:
version "8.0.2"
resolved "https://registry.npmjs.org/shepherd.js/-/shepherd.js-8.0.2.tgz#30675a68883c474b5c7b4056b98f2423b577708f"
integrity sha512-qFt5vrnVoshg6fS5gKGQznYGyIaEclyKKSl1Siw6gO7GyKnCEJ2aBDrp8pxKusMfZo5J5dtgeKJtsRav5cimjA==
shepherd.js@^8.3.1:
version "8.3.1"
resolved "https://registry.npmjs.org/shepherd.js/-/shepherd.js-8.3.1.tgz#131eeefc5eb2bc44c9e23d0da139db46b2b55339"
integrity sha512-IhxZNhnK2m/pNTXudNfYrcwvcZNWkeYngQbQee8nC3xJ2GjeIatGqivhdZAMZ+LeogZvKMakB931d/V534uhrw==
dependencies:
"@popperjs/core" "^2.4.4"
"@popperjs/core" "^2.9.2"
deepmerge "^4.2.2"
smoothscroll-polyfill "^0.4.4"