React
The following is an example usage of the inline components from within React. The imports used are custom, but should be self-explanatory in context.
- GleanWebSDKGallery.tsx
- styles/GleanWebSDKGalleryStyles.ts
import { useEffect, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import injectScript from 'core/lib/injectScript';
import { QueryParam } from 'core/lib/QueryParam';
import { useLazyThunk } from 'core/redux/hooks';
import { selectBasePath } from 'core/redux/selectors/auth';
import { CreateAuthTokenResponse } from 'core/services/query_endpoint/models';
import { Theme } from 'embedded_search/Theme';
import { useQueryParam } from 'web/common/lib/hooks';
import { getWebAppUrl } from 'web/routing/lib/paths';
import styles from './styles/GleanWebSDKStyles';
const loginThunks = () => import('web/login/lib/thunks');
const light: Theme = {
borderLight: '#eaebed',
hover: '#f5fcfc',
primaryHighlight: '#087d76',
primaryHover: '#1ca99e',
selected: '#e8fcfb',
textPrimary: '#1b2126',
textSecondary: '#71747d',
visited: '#7400be',
};
interface GleanWebSDKProps {
authToken?: CreateAuthTokenResponse;
}
const GleanSearch = ({ authToken }: GleanWebSDKProps) => {
const [query, setQuery] = useQueryParam(QueryParam.QUERY);
const [datasource] = useQueryParam(QueryParam.TAB);
const elementRef = useRef<HTMLDivElement>(null);
const basePath = useSelector(selectBasePath);
useEffect(() => {
if (!elementRef.current) return;
window.GleanWebSDK.renderSearchBox(elementRef.current, {
authToken,
backend: basePath,
datasource,
onSearch: setQuery,
query,
searchBoxCustomizations: {
borderRadius: 10,
boxShadow: 'none',
horizontalMargin: 0,
placeholderText: 'Search for anything (Beta)',
verticalMargin: 0,
},
theme: { light },
});
}, [authToken, basePath, datasource, query, setQuery]);
return <div ref={elementRef} style={styles.searchBox} />;
};
const GleanSearchResultsPage = ({ authToken }: GleanWebSDKProps) => {
const [query, setQuery] = useQueryParam(QueryParam.QUERY);
const [datasource, setDatasource] = useQueryParam(QueryParam.TAB);
const elementRef = useRef<HTMLDivElement>(null);
const basePath = useSelector(selectBasePath);
useEffect(() => {
if (!elementRef.current) return;
window.GleanWebSDK.renderSearchResults(elementRef.current, {
authToken,
backend: basePath,
datasource,
onDatasourceChange: setDatasource,
onSearch: setQuery,
query,
theme: { light },
});
}, [authToken, basePath, datasource, query, setDatasource, setQuery]);
return <div ref={elementRef} style={styles.serp} />;
};
const GleanWebSDKGallery = () => {
const fetchAuthTokenThunk = useLazyThunk(loginThunks, 'fetchAuthToken');
const [authToken, setAuthToken] = useState<
CreateAuthTokenResponse | undefined
>();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
(async () => {
setAuthToken(await fetchAuthTokenThunk());
})();
injectScript({
id: 'embedded_search',
src: getWebAppUrl('/embedded-search-latest.min.js'),
}).then(() => setIsLoading(false));
}, [fetchAuthTokenThunk]);
if (isLoading) return null;
return (
<div style={styles.container}>
<GleanSearch authToken={authToken} />
<GleanSearchResultsPage authToken={authToken} />
</div>
);
};
export default GleanWebSDKGallery;
import * as Fonts from 'core/theme/Fonts.css';
import Stylesheet from 'core/types/Stylesheet';
export default Stylesheet({
container: {
padding: 40,
},
group: {
marginBottom: 20,
},
label: {
...Fonts.mediumHeader,
},
});