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

feat(next): add gatsby-plugin-local-search #1464

Merged
merged 8 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions packages/gatsby-theme-carbon/config/local-search-options.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const defaultLocalSearchOptions = {
// A unique name for the search index. This should be descriptive of
// what the index contains. This is required.
name: 'pages',

// Set the search engine to create the index. This is required.
// The following engines are supported: flexsearch, lunr
engine: 'lunr',

// Provide options to the engine. This is optional and only recommended
// for advanced users.
//
// Note: Only the flexsearch engine supports options.
engineOptions: 'default',

// GraphQL query used to fetch all data for the search index. This is
// required.
query: `
{
allMdx {
nodes {
id
frontmatter {
description
title
}
body
internal {
contentFilePath
}
}
}
}
`,

// Field used as the reference value for each document.
// Default: 'id'.
ref: 'id',

// List of keys to index. The values of the keys are taken from the
// normalizer function below.
// Default: all fields
index: ['title', 'body'],

// List of keys to store and make available in your UI. The values of
// the keys are taken from the normalizer function below.
// Default: all fields
store: ['id', 'description', 'title', 'path'],

// Function used to map the result from the GraphQL query. This should
// return an array of items to index in the form of flat objects
// containing properties to index. The objects must contain the `ref`
// field above (default: 'id'). This is required.
normalizer: ({ data }) =>
data.allMdx.nodes.map((node) => ({
id: node.id,
description: node.frontmatter.description,
title: node.frontmatter.title,
body: node.body,
path: node.internal.contentFilePath,
})),
};
export default defaultLocalSearchOptions;
29 changes: 0 additions & 29 deletions packages/gatsby-theme-carbon/config/lunr-options.mjs

This file was deleted.

12 changes: 6 additions & 6 deletions packages/gatsby-theme-carbon/gatsby-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ More info - https://github.com/mdx-js/mdx/issues/2379#issuecomment-1933035305
*/
import remarkGfm from 'remark-gfm';
import { fileURLToPath } from 'url';
import defaultLunrOptions from './config/lunr-options.mjs';

/*
This is a rehype plugin that adds support for metadata to the fenced code block
Expand All @@ -18,6 +17,7 @@ import defaultLunrOptions from './config/lunr-options.mjs';
A metaData prop of format path=/directory/file.mdx src=https://gatsby.carbondesignsystem.com is added to the code block
*/
import rehypeAddCodeMetaData from 'rehype-mdx-fenced-code-meta-support';
import defaultLocalSearchOptions from './config/local-search-options.mjs';

const __dirname = dirname(fileURLToPath(import.meta.url));
const carbonThemes = {
Expand All @@ -43,7 +43,7 @@ export default (themeOptions) => {
iconPath,
mdxExtensions = ['.mdx', '.md'],
imageQuality = 75,
lunrOptions = defaultLunrOptions,
localSearchOptions = defaultLocalSearchOptions,
repository,
mediumAccount = '',
gatsbyRemarkPlugins = [],
Expand Down Expand Up @@ -108,10 +108,6 @@ export default (themeOptions) => {
`gatsby-remark-images`,
`gatsby-transformer-yaml`,
`gatsby-plugin-catch-links`,
{
resolve: 'gatsby-plugin-lunr',
options: lunrOptions,
},
{
resolve: `gatsby-source-filesystem`,
name: `Nav`,
Expand Down Expand Up @@ -183,6 +179,10 @@ export default (themeOptions) => {
: path.resolve('./src/images/favicon.svg'),
},
},
{
resolve: 'gatsby-plugin-local-search',
options: localSearchOptions,
},
].concat(optionalPlugins),
};
};
3 changes: 2 additions & 1 deletion packages/gatsby-theme-carbon/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"copy-to-clipboard": "^3.3.3",
"focus-trap-react": "^10.2.3",
"gatsby-plugin-catch-links": "^5.13.1",
"gatsby-plugin-lunr": "^1.5.2",
"gatsby-plugin-local-search": "^2.0.1",
"gatsby-plugin-manifest": "^5.13.1",
"gatsby-plugin-mdx": "^5.13.1",
"gatsby-plugin-offline": "^6.13.1",
Expand All @@ -60,6 +60,7 @@
"prism-react-renderer": "^2.3.1",
"prop-types": "^15.8.1",
"react-helmet": "^6.1.0",
"react-lunr": "^1.1.0",
"react-transition-group": "^4.4.5",
"react-use": "^17.5.0",
"rehype-mdx-fenced-code-meta-support": "^1.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import React, {
useMemo,
useCallback,
} from 'react';
import { useLunr } from 'react-lunr';
import { Close, Search } from '@carbon/react/icons';
import _throttle from 'lodash.throttle';
import { navigate } from 'gatsby';
import { graphql, navigate, useStaticQuery } from 'gatsby';
import cx from 'classnames';
import NavContext from '../../util/context/NavContext';
import { useOnClickOutside } from '../../util/hooks';
Expand All @@ -34,30 +35,28 @@ import Menu, { MenuContext } from './Menu';

const MAX_RESULT_LIST_SIZE = 8;

const search = _throttle((queryString) => {
if (window.__LUNR__) {
try {
const lunrIndex = window.__LUNR__.en;
const searchResults = lunrIndex.index
.search(`${queryString}*`)
.slice(0, MAX_RESULT_LIST_SIZE);
return searchResults.map(({ ref }) => lunrIndex.store[ref]);
} catch {
console.error(`Lunr is having issues querying for '${queryString}'`);
}
}
}, 150);

// TODO pass magnifying ref for escape/close? keep focus within outline for input,
const GlobalSearchInput = () => {
const data = useStaticQuery(graphql`
query {
localSearchPages {
index
store
}
}
`);

const index = data.localSearchPages.index;
const store = data.localSearchPages.store;

const optionsRef = useRef([]);
const [focusedItem, setFocusedItem] = useState(0);
const inputRef = useRef(null);
const containerRef = useRef(null);
const openButtonRef = useRef(null);
const [inputIsFocused, setInputIsFocused] = useState(false);
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const results = useLunr(query, index, store);
const { toggleNavState, searchIsOpen, isManagingFocus, setIsManagingFocus } =
useContext(NavContext);

Expand Down Expand Up @@ -86,18 +85,6 @@ const GlobalSearchInput = () => {
setQuery('');
});

useEffect(() => {
if (query) {
const searchResults = search(query) || [];
setResults(searchResults);
} else {
setResults([]);
}
return () => {
setResults([]);
};
}, [query]);

const onKeyDown = (e) => {
switch (e.key) {
case 'ArrowDown': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,38 @@ const MenuItem = ({ page, index, onKeyDown, id }) => {
[active]: focusedItem === index,
});

function convertFilePathToUrl(filePath) {
const pagesIndex = filePath.lastIndexOf('/pages/');
if (filePath.lastIndexOf('/pages/') === -1) return null;

const fileName = filePath.slice(
pagesIndex + '/pages/'.length,
-'.mdx'.length
);
const normalizedFileName = fileName.endsWith('/index')
? fileName.slice(0, -'/index'.length)
: fileName;
const urlPath = `/${normalizedFileName.split('/').join('/')}/`;

return urlPath;
}

const url = convertFilePathToUrl(page.path);

return (
<li role="none" key={page.path}>
<li role="none" key={page.id}>
<Link
onClick={clearAndClose}
onKeyDown={onKeyDown}
tabIndex="-1"
id={id}
role="menuitem"
className={className}
to={page.path}>
to={url}>
{page.title}&nbsp;
{page.tab && <span className={tab}>→ {page.tab} </span>}
{page.tab && (
<span className={tab}>→ {page.tab.replace(/\.mdx$/, '')} </span>
)}
{page.description && (
<span className={description}>– {page.description}</span>
)}
Expand Down
Loading