From 55a6b91bdcef53fbd7a3fd7b9c6a7d960432163f Mon Sep 17 00:00:00 2001 From: adamleithp Date: Wed, 18 Dec 2024 11:04:07 +0000 Subject: [PATCH] fixed search bar layout and ux: can now click on search results on desktop, new layout results in less janky keyboard navigation --- .../lib/components/CommandBar/SearchBar.tsx | 4 +- .../components/CommandBar/SearchResult.tsx | 52 +++++++++++-------- .../CommandBar/SearchResultPreview.tsx | 52 ++++++++++++++----- .../components/CommandBar/SearchResults.tsx | 28 +++------- .../lib/components/CommandBar/SearchTabs.tsx | 6 ++- .../components/CommandBar/searchBarLogic.ts | 2 + frontend/src/lib/constants.tsx | 8 +++ .../lib/lemon-ui/LemonInput/LemonInput.scss | 6 +++ 8 files changed, 100 insertions(+), 58 deletions(-) diff --git a/frontend/src/lib/components/CommandBar/SearchBar.tsx b/frontend/src/lib/components/CommandBar/SearchBar.tsx index 3eba8e50e2aad..dd9e2585e7a40 100644 --- a/frontend/src/lib/components/CommandBar/SearchBar.tsx +++ b/frontend/src/lib/components/CommandBar/SearchBar.tsx @@ -13,9 +13,9 @@ export const SearchBar = (): JSX.Element => { const inputRef = useRef(null) return ( -
+
-
+
diff --git a/frontend/src/lib/components/CommandBar/SearchResult.tsx b/frontend/src/lib/components/CommandBar/SearchResult.tsx index 354470759518e..6bb04fce0693c 100644 --- a/frontend/src/lib/components/CommandBar/SearchResult.tsx +++ b/frontend/src/lib/components/CommandBar/SearchResult.tsx @@ -1,6 +1,8 @@ import { LemonSkeleton } from '@posthog/lemon-ui' import clsx from 'clsx' import { useActions, useValues } from 'kea' +import { TAILWIND_BREAKPOINTS } from 'lib/constants' +import { useWindowSize } from 'lib/hooks/useWindowSize' import { capitalizeFirstLetter } from 'lib/utils' import { useLayoutEffect, useRef } from 'react' import { useSummarizeInsight } from 'scenes/insights/summarizeInsight' @@ -22,10 +24,12 @@ type SearchResultProps = { export const SearchResult = ({ result, resultIndex, focused }: SearchResultProps): JSX.Element => { const { aggregationLabel } = useValues(searchBarLogic) - const { openResult } = useActions(searchBarLogic) + const { setActiveResultIndex, openResult } = useActions(searchBarLogic) const ref = useRef(null) + const { width } = useWindowSize() + useLayoutEffect(() => { if (focused) { // :HACKY: This uses the non-standard scrollIntoViewIfNeeded api @@ -40,27 +44,33 @@ export const SearchResult = ({ result, resultIndex, focused }: SearchResultProps }, [focused]) return ( -
{ - openResult(resultIndex) - }} - ref={ref} - > -
- - {result.type !== 'group' - ? tabToName[result.type] - : `${capitalizeFirstLetter(aggregationLabel(result.extra_fields.group_type_index).plural)}`} - - - - + <> +
{ + if (width && width <= TAILWIND_BREAKPOINTS.md) { + openResult(resultIndex) + } else { + setActiveResultIndex(resultIndex) + } + }} + ref={ref} + > +
+ + {result.type !== 'group' + ? tabToName[result.type] + : `${capitalizeFirstLetter(aggregationLabel(result.extra_fields.group_type_index).plural)}`} + + + + +
-
+ ) } diff --git a/frontend/src/lib/components/CommandBar/SearchResultPreview.tsx b/frontend/src/lib/components/CommandBar/SearchResultPreview.tsx index 498150ebada3a..af4e70df0a08a 100644 --- a/frontend/src/lib/components/CommandBar/SearchResultPreview.tsx +++ b/frontend/src/lib/components/CommandBar/SearchResultPreview.tsx @@ -1,11 +1,15 @@ -import { useValues } from 'kea' +import { useActions, useValues } from 'kea' import { ResultDescription, ResultName } from 'lib/components/CommandBar/SearchResult' +import { LemonButton } from 'lib/lemon-ui/LemonButton' + +import { KeyboardShortcut } from '~/layout/navigation-3000/components/KeyboardShortcut' import { tabToName } from './constants' import { searchBarLogic, urlForResult } from './searchBarLogic' export const SearchResultPreview = (): JSX.Element | null => { const { activeResultIndex, combinedSearchResults } = useValues(searchBarLogic) + const { openResult } = useActions(searchBarLogic) if (!combinedSearchResults || combinedSearchResults.length === 0) { return null @@ -14,17 +18,41 @@ export const SearchResultPreview = (): JSX.Element | null => { const result = combinedSearchResults[activeResultIndex] return ( -
-
{tabToName[result.type]}
-
- -
- - {location.host} - {urlForResult(result)} - -
- +
+
+
+
{tabToName[result.type as keyof typeof tabToName]}
+
+ +
+ + {location.host} + {urlForResult(result)} + +
+ +
+
+
+ { + openResult(activeResultIndex) + }} + tooltip={ + <> + Open + + } + aria-label="Open search result" + > + Open + +
+ Open +
+
) diff --git a/frontend/src/lib/components/CommandBar/SearchResults.tsx b/frontend/src/lib/components/CommandBar/SearchResults.tsx index 2dde6f78cbead..923011890c423 100644 --- a/frontend/src/lib/components/CommandBar/SearchResults.tsx +++ b/frontend/src/lib/components/CommandBar/SearchResults.tsx @@ -1,6 +1,4 @@ -import clsx from 'clsx' import { useValues } from 'kea' -import { useResizeBreakpoints } from 'lib/hooks/useResizeObserver' import { DetectiveHog } from '../hedgehogs' import { searchBarLogic } from './searchBarLogic' @@ -10,27 +8,17 @@ import { SearchResultPreview } from './SearchResultPreview' export const SearchResults = (): JSX.Element => { const { combinedSearchResults, combinedSearchLoading, activeResultIndex } = useValues(searchBarLogic) - const { ref, size } = useResizeBreakpoints({ - 0: 'small', - 550: 'normal', - }) - return ( -
+
{!combinedSearchLoading && combinedSearchResults?.length === 0 ? ( -
+

No results

This doesn't happen often, but we're stumped!

) : ( -
-
+
+
{combinedSearchLoading && ( <> @@ -48,11 +36,9 @@ export const SearchResults = (): JSX.Element => { /> ))}
- {size !== 'small' ? ( -
- -
- ) : null} +
+ +
)}
diff --git a/frontend/src/lib/components/CommandBar/SearchTabs.tsx b/frontend/src/lib/components/CommandBar/SearchTabs.tsx index 37ff41ff30a53..aa3ddb67e8496 100644 --- a/frontend/src/lib/components/CommandBar/SearchTabs.tsx +++ b/frontend/src/lib/components/CommandBar/SearchTabs.tsx @@ -12,11 +12,13 @@ type SearchTabsProps = { export const SearchTabs = ({ inputRef }: SearchTabsProps): JSX.Element | null => { const { tabsGrouped } = useValues(searchBarLogic) return ( -
+
{Object.entries(tabsGrouped).map(([group, tabs]) => (
{group !== 'all' && ( - {groupToName[group]} + + {groupToName[group as keyof typeof groupToName]} + )} {tabs.map((tab) => ( diff --git a/frontend/src/lib/components/CommandBar/searchBarLogic.ts b/frontend/src/lib/components/CommandBar/searchBarLogic.ts index b3576ac482d10..1b96c64c34b81 100644 --- a/frontend/src/lib/components/CommandBar/searchBarLogic.ts +++ b/frontend/src/lib/components/CommandBar/searchBarLogic.ts @@ -61,6 +61,7 @@ export const searchBarLogic = kea([ onArrowUp: (activeIndex: number, maxIndex: number) => ({ activeIndex, maxIndex }), onArrowDown: (activeIndex: number, maxIndex: number) => ({ activeIndex, maxIndex }), openResult: (index: number) => ({ index }), + setActiveResultIndex: (index: number) => ({ index }), }), loaders(({ values, actions }) => ({ rawSearchResponse: [ @@ -208,6 +209,7 @@ export const searchBarLogic = kea([ openResult: () => 0, onArrowUp: (_, { activeIndex, maxIndex }) => (activeIndex > 0 ? activeIndex - 1 : maxIndex), onArrowDown: (_, { activeIndex, maxIndex }) => (activeIndex < maxIndex ? activeIndex + 1 : 0), + setActiveResultIndex: (_, { index }) => index, }, ], activeTab: [ diff --git a/frontend/src/lib/constants.tsx b/frontend/src/lib/constants.tsx index d41a232518b18..ae93860525488 100644 --- a/frontend/src/lib/constants.tsx +++ b/frontend/src/lib/constants.tsx @@ -314,3 +314,11 @@ export const SESSION_REPLAY_MINIMUM_DURATION_OPTIONS: LemonSelectOptions