Skip to content

Commit

Permalink
fix: optimize initial search loading
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Jul 8, 2020
1 parent 2016f4b commit 2624c55
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 46 deletions.
83 changes: 42 additions & 41 deletions ui/blocks/src/Search/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @jsx jsx */
import { jsx, Theme } from 'theme-ui';
import { FC, useState, useContext, useRef, useEffect } from 'react';
import { FC, useState, useContext, useRef, useCallback } from 'react';
import lunr, { Index } from 'lunr';
import { SearchInput, SearchInputProps } from '@component-controls/components';
import { DocType, defDocType, Pages, Document } from '@component-controls/core';
Expand All @@ -20,51 +20,52 @@ export const Search: FC<Omit<
'items' | 'onSearch'
>> = props => {
const [items, setItems] = useState<Pages>([]);
const [search, setSearch] = useState<string>('');
const { storeProvider } = useContext(BlockContext);
const lunrRef = useRef<Index | undefined>(undefined);

useEffect(() => {
if (!lunrRef.current) {
lunrRef.current = lunr(function() {
this.field('title');
this.field('description');
this.field('body');
this.field('author');
this.field('stories');
this.field('component');
storeProvider.pages.forEach(page => {
this.add({
id: page.title,
title: page.title.replace('/', ' '),
type: page.type || defDocType,
description: page.description,
body: page.source,
author: page.author,
stories: page.stories
?.map(story => story.split('-').join(' '))
.join(' '),
component: Object.keys(page.componentsLookup).join(' '),
const onSearch = useCallback(
(search: string) => {
if (!lunrRef.current) {
lunrRef.current = lunr(function() {
this.field('title');
this.field('description');
this.field('body');
this.field('author');
this.field('stories');
this.field('component');
this.field('tags');
storeProvider.pages.forEach(page => {
this.add({
id: page.title,
title: page.title.replace('/', ' '),
type: page.type || defDocType,
description: page.description,
body: page.source,
author: page.author,
stories: page.stories
?.map(story => story.split('-').join(' '))
.join(' '),
tags: page.tags ? page.tags.join(' ') : '',
component: Object.keys(page.componentsLookup).join(' '),
});
});
});
});
}
const searchResults = lunrRef.current.search(search);
const newItems: Pages = searchResults
.slice(0, 20)
.filter(
(item: { ref: string }) =>
storeProvider.getStoryDoc(item.ref) as Document,
)
.map((item: { ref: string }) => {
const page = storeProvider.getStoryDoc(item.ref) as Document;
return { ...page, id: page.title };
});
setItems(newItems);
}, [search, storeProvider]);
const onSearch = (search: string) => {
setSearch(search);
};
}
const searchResults = lunrRef.current.search(search);
const newItems: Pages = searchResults
.slice(0, 20)
.filter(
(item: { ref: string }) =>
storeProvider.getStoryDoc(item.ref) as Document,
)
.map((item: { ref: string }) => {
const page = storeProvider.getStoryDoc(item.ref) as Document;
return { ...page, id: page.title };
});
setItems(newItems);
},
[storeProvider],
);
const onSelectItem = (item: Document) => {
const newurl = `${window.location.origin}${storeProvider.getPagePath(
item.type,
Expand Down
14 changes: 9 additions & 5 deletions ui/components/src/SearchInput/SearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,15 @@ export const SearchInput = <ItemType extends SearchInputItemType>({
}: SearchInputProps<ItemType>) => {
const [selected, setSelected] = useState<number | undefined>(undefined);
const [isOpen, setIsOpen] = useState<boolean>(false);
const [search, setSearch] = useState<string>('');
const [search, setSearch] = useState<string | undefined>(undefined);
const updateIsOpen = (newIsOpen: boolean) => {
setIsOpen(newIsOpen && items.length > 0);
// if first time open, send a onSearch message to collect items
if (newIsOpen && search === undefined && items.length === 0) {
onSearch('');
} else {
setIsOpen(newIsOpen && items.length > 0);
}
};

useEffect(() => {
setIsOpen(items.length > 0 && search !== '');
}, [items, search]);
Expand Down Expand Up @@ -157,7 +161,7 @@ export const SearchInput = <ItemType extends SearchInputItemType>({
item,
index,
isOpen,
search,
search: search || '',
selected,
selectItem,
};
Expand Down Expand Up @@ -189,7 +193,7 @@ export const SearchInput = <ItemType extends SearchInputItemType>({
<div sx={{ position: 'relative' }}>
<Input
aria-label="type some text to start searching"
value={search}
value={search || ''}
onBlur={() => {
setTimeout(() => {
updateIsOpen(false);
Expand Down

0 comments on commit 2624c55

Please sign in to comment.