Skip to content

Commit

Permalink
feat: full text search initial
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed Jun 21, 2020
1 parent fe1f105 commit 342f660
Show file tree
Hide file tree
Showing 36 changed files with 311 additions and 203 deletions.
9 changes: 5 additions & 4 deletions core/core/src/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,13 @@ export const getDocPath = (
activeTab?: string,
): string => {
const { basePath = '' } = pagesConfig?.[pageType] || {};
return doc
const route = doc
? doc.route ||
`/${basePath}${
activeTab ? `${activeTab}/` : ''
}${doc.title?.toLowerCase()}/`
`/${basePath}${
activeTab ? `${activeTab}/` : ''
}${doc.title?.toLowerCase()}/`
: `/${basePath}${activeTab ? `${activeTab}/` : ''}${name}/`;
return route;
};

export const getStoryPath = (
Expand Down
12 changes: 12 additions & 0 deletions core/store/src/Store/Store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,18 @@ export class Store implements StoryStore {
return this.loadedStore?.config;
}

/**
* returns all pages(documents) in the store
*/
get pages(): Pages {
return this.loadedStore?.docs
? Object.keys(this.loadedStore.docs).map(
//@ts-ignore
key => this.loadedStore.docs[key],
)
: [];
}

/**
* returns the first document of a page type.
*/
Expand Down
1 change: 1 addition & 0 deletions core/store/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface StoryStore {
getPagesByCategory: (category: string, value?: any) => Pages;
getUniquesByCategory: (category: string) => { [key: string]: number };
config: RunConfiguration | undefined;
pages: Pages;
getFirstDocument: (pageType: PageType) => string | undefined;
getPagePath: (
pageType: PageType | undefined,
Expand Down
12 changes: 4 additions & 8 deletions plugins/axe-plugin/src/components/ResultsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { FC, useMemo, useCallback, useContext } from 'react';
import { jsx, Flex, Box, Text } from 'theme-ui';
import { Column } from 'react-table';
import Octicon, {
import {
ChevronRightIcon,
ChevronDownIcon,
TriangleRightIcon,
Expand Down Expand Up @@ -61,9 +61,7 @@ const ResultsTable: FC<ResultsTableProps> = ({ results, hideErrorColumns }) => {
id: 'expander', // Make sure it has an ID
Header: ({ getToggleAllRowsExpandedProps, isAllRowsExpanded }: any) => (
<span {...getToggleAllRowsExpandedProps()}>
<Octicon
icon={isAllRowsExpanded ? TriangleDownIcon : TriangleRightIcon}
/>
{isAllRowsExpanded ? <TriangleDownIcon /> : <TriangleRightIcon />}
</span>
),
width: 50,
Expand All @@ -74,9 +72,7 @@ const ResultsTable: FC<ResultsTableProps> = ({ results, hideErrorColumns }) => {
pl: 2,
}}
>
<Octicon
icon={row.isExpanded ? ChevronDownIcon : ChevronRightIcon}
/>{' '}
{row.isExpanded ? <ChevronDownIcon /> : <ChevronRightIcon />}
</Flex>
),
},
Expand Down Expand Up @@ -108,7 +104,7 @@ const ResultsTable: FC<ResultsTableProps> = ({ results, hideErrorColumns }) => {
color: impact ? impact.color : undefined,
}}
>
{impact && <Octicon icon={impact.icon} />}
{impact && <impact.icon />}
<Text
sx={{
pl: impact ? 2 : 0,
Expand Down
13 changes: 6 additions & 7 deletions ui/app/src/DocumentsList/DocumentsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
import { FC, useContext, useState, useMemo } from 'react';
import { jsx, Select, Label, Box } from 'theme-ui';
import { Pages } from '@component-controls/core';
import { BlockContext } from '@component-controls/blocks';
import { DocumentsListItem } from './DocumentsListItem';
import { BlockContext, DocumentItem } from '@component-controls/blocks';

export interface DocumentsListProps {
/**
Expand Down Expand Up @@ -51,17 +50,17 @@ export const DocumentsList: FC<DocumentsListProps> = ({ pages }) => {
<option value="title">By title</option>
</Select>
</Box>
<ul>
<Box as="ul" variant="documentslist.list">
{sortedPages.map(page => (
<li key={page?.title}>
<DocumentsListItem
<Box as="li" key={page?.title} variant="documentslist.listitem">
<DocumentItem
config={storeProvider.config}
link={storeProvider.getPagePath(page.type, page.title)}
page={page}
/>
</li>
</Box>
))}
</ul>
</Box>
</Box>
);
};
13 changes: 11 additions & 2 deletions ui/app/src/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
SidebarContext,
Header as AppHeader,
} from '@component-controls/components';
import { BlockContext } from '@component-controls/blocks';
import { BlockContext, Search } from '@component-controls/blocks';

/**
* application header component
Expand Down Expand Up @@ -49,7 +49,16 @@ export const Header: FC = () => {
: null}
</Box>
</Box>
{!responsive && <ColorMode />}
{!responsive && (
<Box variant="appheader.righthandrow">
<Box variant="appheader.righthanditem">
<Search />
</Box>
<Box variant="appheader.righthanditem">
<ColorMode />
</Box>
</Box>
)}
</AppHeader>
);
};
1 change: 0 additions & 1 deletion ui/app/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,3 @@ export * from './SEO';
export * from './Sidebar';
export * from './SidebarsPage';
export * from './SideContext';
export * from './TagsList';
3 changes: 3 additions & 0 deletions ui/blocks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
"copy-to-clipboard": "^3.2.1",
"global": "^4.3.2",
"js-string-escape": "^1.0.1",
"lunr": "^2.3.8",
"normalize-url": "^5.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-table": "^7.0.0",
Expand All @@ -49,6 +51,7 @@
"devDependencies": {
"@theme-ui/presets": "^0.3.0",
"@types/jest": "^25.1.2",
"@types/lunr": "^2.3.3",
"@types/mdx-js__react": "^1.5.1",
"@types/stringify-object": "^3.2.0",
"cross-env": "^5.2.1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,11 @@ export interface PageListItemProps {
/**
* displays a single doument item
*/
export const DocumentsListItem: FC<PageListItemProps> = ({
page,
link,
config,
}) => {
export const DocumentItem: FC<PageListItemProps> = ({ page, link, config }) => {
const { tags = [], date, type = defPageType } = page;
return (
<Box variant="documentlistitem.container">
<Box
sx={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}
>
<Box variant="documentitem.container">
<Box variant="documentitem.titlerow">
<Link href={link}>
<Subtitle>{page.title}</Subtitle>
</Link>
Expand All @@ -58,33 +47,19 @@ export const DocumentsListItem: FC<PageListItemProps> = ({
)}
</Box>
{page.description && <Markdown>{page.description}</Markdown>}
<Box variant="documentlistitem.info.container">
<Box variant="documentlistitem.info.inner">
<Box variant="documentitem.info.container">
<Box variant="documentitem.info.inner">
{date ? (
<Box variant="documentlistitem.info.date">{`created: ${dateToLocalString(
<Box variant="documentitem.info.date">{`created: ${dateToLocalString(
date,
)}`}</Box>
) : (
''
)}
{page.author && (
<Box variant="documentlistitem.info.author">
{date && (
<Text
sx={{
mr: 2,
}}
>
,
</Text>
)}
<Text
sx={{
mr: 1,
}}
>
by
</Text>
<Box variant="documentitem.info.author">
{date && <Text variant="documentitem.info.comma">,</Text>}
<Text variant="documentitem.info.by">by</Text>
<Link
href={getDocPath(
'author',
Expand Down
1 change: 1 addition & 0 deletions ui/blocks/src/DocumentItem/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './DocumentItem';
4 changes: 2 additions & 2 deletions ui/blocks/src/EditPage/EditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { jsx } from 'theme-ui';
import { FC } from 'react';
import { Box, Text } from 'theme-ui';
import Octicon, { MarkGithubIcon } from '@primer/octicons-react';
import { MarkGithubIcon } from '@primer/octicons-react';
import { ExternalLink } from '@component-controls/components';
import { useStoryContext } from '../context';

Expand All @@ -20,7 +20,7 @@ export const EditPage: FC = () => {
aria-label="edit this page"
>
<Box variant="editpage.inner">
<Octicon icon={MarkGithubIcon} />
<MarkGithubIcon />
<Text variant="editpage.text">Edit this page</Text>
</Box>
</ExternalLink>
Expand Down
8 changes: 4 additions & 4 deletions ui/blocks/src/Playground/Playground.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FC, Children, useContext } from 'react';
import Octicon, { PlusIcon, DashIcon, SyncIcon } from '@primer/octicons-react';
import { PlusIcon, DashIcon, SyncIcon } from '@primer/octicons-react';
import {
BackgroundType,
DirectionType,
Expand Down Expand Up @@ -58,7 +58,7 @@ export const Playground: FC<PlaygroundProps> = ({
{
title: (
<IconButton onClick={() => setScale(1)} aria-label="reset zoom">
<Octicon icon={SyncIcon} />
<SyncIcon />
</IconButton>
),
id: 'zoomreset',
Expand All @@ -70,7 +70,7 @@ export const Playground: FC<PlaygroundProps> = ({
onClick={() => setScale(Math.max(0.5, scale - 0.2))}
aria-label="zoom out"
>
<Octicon icon={DashIcon} />
<DashIcon />
</IconButton>
),
id: 'zoomout',
Expand All @@ -82,7 +82,7 @@ export const Playground: FC<PlaygroundProps> = ({
onClick={() => setScale(Math.min(3, scale + 0.2))}
aria-label="zoom in"
>
<Octicon icon={PlusIcon} />
<PlusIcon />
</IconButton>
),
id: 'zoomin',
Expand Down
14 changes: 14 additions & 0 deletions ui/blocks/src/Search/Search.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* eslint-disable react/display-name */
import React from 'react';
import { Search } from './Search';
import { MockContext } from '../test/MockContext';
export default {
title: 'Blocks/Search',
component: Search,
};

export const overview = () => (
<MockContext id="id-of-story">
<Search />
</MockContext>
);
90 changes: 90 additions & 0 deletions ui/blocks/src/Search/Search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/** @jsx jsx */
import { jsx, Theme } from 'theme-ui';
import { useState, useContext, useRef, useEffect } from 'react';
import lunr, { Index } from 'lunr';
import normalizeUrl from 'normalize-url';
import { SearchInput } from '@component-controls/components';
import {
PageType,
defPageType,
Pages,
StoriesDoc,
} from '@component-controls/core';
import { BlockContext } from '../context';
import { DocumentItem } from '../DocumentItem';

export interface SearchItem {
id: string;
title: string;
type: PageType;
component?: string;
description?: string;
body?: string;
}
export const Search = () => {
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('component');
storeProvider.pages.forEach(page => {
this.add({
id: page.title,
title: page.title.replace('/', ' '),
type: page.type || defPageType,
description: page.description,
body: page.source,
author: page.author,
component: Object.keys(page.components).join(' '),
});
});
});
}
const searchResults = lunrRef.current.search(search);
const newItems: Pages = searchResults
.slice(0, 10)
.map((item: { ref: string }) => {
const page = storeProvider.getStoryDoc(item.ref) as StoriesDoc;
return { ...page, id: page.title };
});
setItems(newItems);
}, [search, storeProvider]);
const onSearch = (search: string) => {
setSearch(search);
};
const onSelectItem = (item: StoriesDoc) => {
const newurl = `${window.location.origin}${storeProvider.getPagePath(
item.type,
item.title,
)}`;
if (normalizeUrl(window.location.href) !== normalizeUrl(newurl)) {
window.location.href = newurl;
}
};
return (
<SearchInput<StoriesDoc>
aria-label="full text search"
onSearch={onSearch}
items={items}
onSelect={onSelectItem}
placeholder="search..."
>
{props => (
<DocumentItem
sx={{ borderBottom: (t: Theme) => ` 1px solid ${t.colors?.shadow}` }}
config={storeProvider.config}
link={storeProvider.getPagePath(props.item.type, props.item.title)}
page={props.item}
/>
)}
</SearchInput>
);
};
1 change: 1 addition & 0 deletions ui/blocks/src/Search/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Search';
File renamed without changes.
Loading

0 comments on commit 342f660

Please sign in to comment.