Skip to content

Commit 1f49032

Browse files
committed
[graph-search] allow to override minisearch option in constructor and search function
1 parent 3da3813 commit 1f49032

File tree

4 files changed

+63
-20
lines changed

4 files changed

+63
-20
lines changed
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import React, { FC } from 'react';
22

33
import { GraphSearchInput, GraphSearchInputProps } from './GraphSearchInput';
4-
import { GraphSearchContextProvider } from './context';
4+
import { GraphSearchContextProvider, GraphSearchContextProviderProps } from './context';
55

66
/**
77
* Component that display the search.
88
* It is the main component of this package, you can only use this one.
99
*
1010
* @category Component
1111
*/
12-
export const GraphSearch: FC<GraphSearchInputProps> = (props) => (
13-
<GraphSearchContextProvider>
12+
export const GraphSearch: FC<GraphSearchInputProps & GraphSearchContextProviderProps> = ({
13+
minisearchOptions,
14+
...props
15+
}) => (
16+
<GraphSearchContextProvider minisearchOptions={minisearchOptions}>
1417
<GraphSearchInput {...props} />
1518
</GraphSearchContextProvider>
1619
);

packages/graph-search/src/assets/index.css

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
:root {
2+
--sigma-grey-color: #ccc;
3+
}
4+
15
.react-sigma .option.hoverable {
26
cursor: pointer !important;
37
}
@@ -13,7 +17,7 @@
1317
}
1418

1519
.react-sigma .text-muted {
16-
color: #CCC;
20+
color: var(--sigma-grey-color)
1721
}
1822

1923
.react-sigma .text-italic {
@@ -38,7 +42,7 @@
3842
}
3943

4044
.react-sigma .graph-search .option.selected {
41-
background-color: #ccc;
45+
background-color: var(--sigma-grey-color)
4246
}
4347

4448
.react-sigma .node .render {
@@ -47,7 +51,7 @@
4751
width: 1em;
4852
height: 1em;
4953
border-radius: 1em;
50-
background-color: #ccc;
54+
background-color: var(--sigma-grey-color);
5155
margin-right: 8px;
5256
}
5357

packages/graph-search/src/context.tsx

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { useSigma } from '@react-sigma/core';
22
import { Attributes } from 'graphology-types';
3-
import MiniSearch from 'minisearch';
3+
import MiniSearch, { Options } from 'minisearch';
44
import React from 'react';
55
import { FC, PropsWithChildren, createContext, useEffect, useState } from 'react';
66

7+
import { Document } from './types';
78
import { edgeToDocument, nodeToDocument } from './utils';
89

910
export interface GraphSearchContextType {
@@ -18,27 +19,58 @@ const initialContext: GraphSearchContextType = {
1819
*/
1920
export const GraphSearchContext = createContext(initialContext);
2021

22+
export interface GraphSearchContextProviderProps {
23+
/**
24+
* The minisearch options for its construtor.
25+
*/
26+
minisearchOptions?: Partial<Options<Document>>;
27+
}
2128
/**
2229
* Search context provider.
2330
* It exposes the minisearch instance to search in the graph and
2431
* is also responsible to keep the index up to date with the graph.
2532
*
33+
* You can override the minisearch options by passing them in the `minisearchOptions` prop.
34+
*
35+
* Documents in the index have the type {@link Document} :
36+
* - `id` is node or edge key in the graph
37+
* - `type` is "nodes" or "edges"
38+
* - `itemId` is the unique id in the index (concatenation of type and id)
39+
* - `label` is the label of the node or edge in the graph
40+
* - every attributes of the node or edge are also in the index, prefixed by `prop_`
41+
*
42+
*
2643
* @category Component
2744
*/
28-
export const GraphSearchContextProvider: FC<PropsWithChildren> = ({ children }) => {
45+
export const GraphSearchContextProvider: FC<PropsWithChildren<GraphSearchContextProviderProps>> = ({
46+
children,
47+
minisearchOptions,
48+
}) => {
2949
const [context, setContext] = useState(initialContext);
3050
const sigma = useSigma();
3151

3252
useEffect(() => {
33-
const index = new MiniSearch({
53+
const index = new MiniSearch<Document>({
54+
...minisearchOptions,
3455
idField: 'itemId',
35-
fields: ['label'],
36-
storeFields: ['itemId', 'id', 'type'],
37-
processTerm: (term, _fieldName) =>
38-
term
39-
.normalize('NFD')
40-
.replace(/[\u0300-\u036f]/g, '')
41-
.toLowerCase(),
56+
fields: minisearchOptions?.fields
57+
? ['label', ...minisearchOptions.fields.filter((e) => e !== 'label')]
58+
: ['label'],
59+
storeFields: minisearchOptions?.storeFields
60+
? [
61+
'itemId',
62+
'id',
63+
'type',
64+
...minisearchOptions.storeFields.filter((e) => !['itemId', 'id', 'type'].includes(e)),
65+
]
66+
: ['itemId', 'id', 'type'],
67+
processTerm: minisearchOptions?.processTerm
68+
? minisearchOptions?.processTerm
69+
: (term, _fieldName) =>
70+
term
71+
.normalize('NFD')
72+
.replace(/[\u0300-\u036f]/g, '')
73+
.toLowerCase(),
4274
});
4375

4476
// index all
@@ -88,7 +120,7 @@ export const GraphSearchContextProvider: FC<PropsWithChildren> = ({ children })
88120
graph.off('edgeAttributesUpdated', indexEdge);
89121
graph.off('edgeDropped', deleteEdge);
90122
};
91-
}, [sigma]);
123+
}, [sigma, minisearchOptions]);
92124

93125
return <GraphSearchContext.Provider value={context}>{children}</GraphSearchContext.Provider>;
94126
};

packages/graph-search/src/useGraphSearch.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SearchOptions } from 'minisearch';
12
import { useCallback, useContext } from 'react';
23

34
import { GraphSearchContext } from './context';
@@ -7,9 +8,11 @@ import { GraphSearchOption, ItemType } from './types';
78
* Hooks that returns a function to search in the graph index.
89
* This hook must be used in a component that is a descendant of `GraphSearchContextProvider`.
910
*
11+
* @param searchOption - Options passed to the minisearch search function. Per default we use `{ prefix: true, fuzzy: 0.2, boost: { label: 2 } }`
12+
*
1013
* @category Hook
1114
*/
12-
export function useGraphSearch() {
15+
export function useGraphSearch(searchOption?: SearchOptions) {
1316
const { index } = useContext(GraphSearchContext);
1417

1518
const search = useCallback(
@@ -18,15 +21,16 @@ export function useGraphSearch() {
1821
.search(query, {
1922
prefix: true,
2023
fuzzy: 0.2,
21-
filter: type ? (result) => result.type === type : undefined,
2224
boost: {
2325
label: 2,
2426
},
27+
...(searchOption || {}),
28+
filter: type ? (result) => result.type === type : undefined,
2529
})
2630
.map((item) => ({ id: item.id, type: item.type }));
2731
return result;
2832
},
29-
[index],
33+
[index, searchOption],
3034
);
3135

3236
return { search };

0 commit comments

Comments
 (0)