diff --git a/sample-app/src/App.tsx b/sample-app/src/App.tsx index 39bcc1c1..c04084c9 100644 --- a/sample-app/src/App.tsx +++ b/sample-app/src/App.tsx @@ -3,7 +3,7 @@ import VerticalSearchPage from './pages/VerticalSearchPage'; import UniversalSearchPage from './pages/UniversalSearchPage'; import PageRouter from './PageRouter'; import StandardLayout from './pages/StandardLayout'; -import { AnswersActionsProvider } from '@yext/answers-headless-react'; +import { AnswersHeadlessProvider } from '@yext/answers-headless-react'; import { universalResultsConfig } from './universalResultsConfig'; const routes = [ @@ -22,7 +22,7 @@ const routes = [ export default function App() { return ( - - + ); } diff --git a/sample-app/src/components/Facet.tsx b/sample-app/src/components/Facet.tsx index 1bf5c2e1..da848cd1 100644 --- a/sample-app/src/components/Facet.tsx +++ b/sample-app/src/components/Facet.tsx @@ -1,4 +1,4 @@ -import { useAnswersActions } from '@yext/answers-headless-react' +import { useAnswersUtilities } from '@yext/answers-headless-react' import { DisplayableFacet, DisplayableFacetOption } from '@yext/answers-core'; import { useState } from 'react'; import useCollapse from 'react-collapsed'; @@ -21,7 +21,7 @@ interface FacetProps extends FacetTextConfig { export default function Facet(props: FacetProps): JSX.Element { const { facet, onToggle, searchable, collapsible, defaultExpanded, placeholderText, label } = props; - const answersActions = useAnswersActions(); + const answersUtilities = useAnswersUtilities(); const hasSelectedFacet = !!facet.options.find(o => o.selected); const [ filterValue, setFilterValue ] = useState(''); const { getCollapseProps, getToggleProps } = useCollapse({ @@ -29,7 +29,7 @@ export default function Facet(props: FacetProps): JSX.Element { }); const facetOptions = searchable - ? answersActions.utilities.searchThroughFacet(facet, filterValue).options + ? answersUtilities.searchThroughFacet(facet, filterValue).options : facet.options; return ( diff --git a/sample-app/src/components/StaticFilters.tsx b/sample-app/src/components/StaticFilters.tsx index b42a20b2..532fe838 100644 --- a/sample-app/src/components/StaticFilters.tsx +++ b/sample-app/src/components/StaticFilters.tsx @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import { Filter, CombinedFilter, FilterCombinator, Matcher } from '@yext/answers-core'; -import { AnswersActionsContext } from '@yext/answers-headless-react'; +import { AnswersHeadlessContext } from '@yext/answers-headless-react'; interface CheckBoxProps { fieldId: string, @@ -115,4 +115,4 @@ function formatOrFilters(filters: Filter[]) { } } -StaticFilters.contextType = AnswersActionsContext; \ No newline at end of file +StaticFilters.contextType = AnswersHeadlessContext; \ No newline at end of file diff --git a/src/AnswersActionsContext.ts b/src/AnswersHeadlessContext.ts similarity index 64% rename from src/AnswersActionsContext.ts rename to src/AnswersHeadlessContext.ts index cf4d1028..c2d3504d 100644 --- a/src/AnswersActionsContext.ts +++ b/src/AnswersHeadlessContext.ts @@ -2,4 +2,4 @@ import { AnswersHeadless } from '@yext/answers-headless'; import { createContext } from 'react'; // The default is empty because we don't know the user's config yet -export const AnswersActionsContext = createContext({} as AnswersHeadless); +export const AnswersHeadlessContext = createContext({} as AnswersHeadless); diff --git a/src/AnswersActionsProvider.tsx b/src/AnswersHeadlessProvider.tsx similarity index 70% rename from src/AnswersActionsProvider.tsx rename to src/AnswersHeadlessProvider.tsx index 292ed965..60634054 100644 --- a/src/AnswersActionsProvider.tsx +++ b/src/AnswersHeadlessProvider.tsx @@ -1,20 +1,20 @@ import { ReactChild, ReactChildren } from 'react'; import { provideAnswersHeadless, AnswersHeadless } from '@yext/answers-headless'; import { AnswersConfig } from '@yext/answers-core'; -import { AnswersActionsContext } from './AnswersActionsContext'; +import { AnswersHeadlessContext } from './AnswersHeadlessContext'; interface Props extends AnswersConfig { children?: ReactChildren | ReactChild | (ReactChildren | ReactChild)[], verticalKey?: string } -export function AnswersActionsProvider(props: Props): JSX.Element { +export function AnswersHeadlessProvider(props: Props): JSX.Element { const { children, verticalKey, ...answersConfig } = props; const answers: AnswersHeadless = provideAnswersHeadless(answersConfig); verticalKey && answers.setVerticalKey(verticalKey); return ( - + {children} - + ); } diff --git a/src/index.ts b/src/index.ts index cf1e622a..c9a74bda 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,15 +1,18 @@ import { useAnswersActions, AnswersActions } from './useAnswersActions'; import { useAnswersState, StateSelector } from './useAnswersState'; +import { useAnswersUtilities, AnswersUtilities } from './useAnswersUtilities'; import { subscribeToStateUpdates } from './subscribeToStateUpdates'; -import { AnswersActionsProvider } from './AnswersActionsProvider'; -import { AnswersActionsContext } from './AnswersActionsContext'; +import { AnswersHeadlessProvider } from './AnswersHeadlessProvider'; +import { AnswersHeadlessContext } from './AnswersHeadlessContext'; export { - AnswersActionsContext, + AnswersHeadlessContext, subscribeToStateUpdates, useAnswersActions, useAnswersState, - AnswersActionsProvider, + useAnswersUtilities, + AnswersHeadlessProvider, AnswersActions, + AnswersUtilities, StateSelector }; diff --git a/src/subscribeToStateUpdates.tsx b/src/subscribeToStateUpdates.tsx index 16386c9b..b968a46e 100644 --- a/src/subscribeToStateUpdates.tsx +++ b/src/subscribeToStateUpdates.tsx @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { ComponentType, useReducer, useEffect, useContext } from 'react'; import { State } from '@yext/answers-headless/lib/esm/models/state'; -import { AnswersActionsContext } from './AnswersActionsContext'; +import { AnswersHeadlessContext } from './AnswersHeadlessContext'; import isShallowEqual from './utils/isShallowEqual'; type SubscriberGenerator = (WrappedComponent: ComponentType) => (props: any) => JSX.Element; @@ -26,7 +26,7 @@ export function subscribeToStateUpdates( */ let previousPropsFromState = {}; return function AnswersHeadlessSubscriber(props: Record) { - const answers = useContext(AnswersActionsContext); + const answers = useContext(AnswersHeadlessContext); const [mergedProps, dispatch] = useReducer(() => { return { ...props, diff --git a/src/useAnswersActions.ts b/src/useAnswersActions.ts index 224882ea..ec2b4b6e 100644 --- a/src/useAnswersActions.ts +++ b/src/useAnswersActions.ts @@ -1,9 +1,9 @@ import { AnswersHeadless } from '@yext/answers-headless'; import { useContext } from 'react'; -import { AnswersActionsContext } from './AnswersActionsContext'; +import { AnswersHeadlessContext } from './AnswersHeadlessContext'; export type AnswersActions = AnswersHeadless; export function useAnswersActions(): AnswersActions { - return useContext(AnswersActionsContext); + return useContext(AnswersHeadlessContext); } \ No newline at end of file diff --git a/src/useAnswersState.tsx b/src/useAnswersState.tsx index f6207acc..1d9e9901 100644 --- a/src/useAnswersState.tsx +++ b/src/useAnswersState.tsx @@ -1,6 +1,6 @@ import { useContext, useLayoutEffect, useRef, useState } from 'react'; import { State } from '@yext/answers-headless/lib/esm/models/state'; -import { AnswersActionsContext } from './AnswersActionsContext'; +import { AnswersHeadlessContext } from './AnswersHeadlessContext'; export type StateSelector = (s: State) => T; @@ -9,7 +9,7 @@ export type StateSelector = (s: State) => T; * Very similar to useSelector in react-redux. */ export function useAnswersState(stateSelector: StateSelector): T { - const answers = useContext(AnswersActionsContext); + const answers = useContext(AnswersHeadlessContext); // useRef stores values across renders without triggering additional ones const storedStoreState = useRef(answers.state); diff --git a/src/useAnswersUtilities.ts b/src/useAnswersUtilities.ts new file mode 100644 index 00000000..f1a77f5b --- /dev/null +++ b/src/useAnswersUtilities.ts @@ -0,0 +1,9 @@ +import { AnswersHeadless } from '@yext/answers-headless'; +import { useContext } from 'react'; +import { AnswersHeadlessContext } from './AnswersHeadlessContext'; + +export type AnswersUtilities = AnswersHeadless['utilities']; + +export function useAnswersUtilities(): AnswersUtilities { + return useContext(AnswersHeadlessContext).utilities; +} \ No newline at end of file diff --git a/tests/useAnswersState.test.tsx b/tests/useAnswersState.test.tsx index 36b87c3f..6f4be70b 100644 --- a/tests/useAnswersState.test.tsx +++ b/tests/useAnswersState.test.tsx @@ -4,7 +4,7 @@ import { Result } from '@yext/answers-core'; import { provideAnswersHeadless } from '@yext/answers-headless'; import { State } from '@yext/answers-headless/lib/esm/models/state'; import React, { useCallback, useReducer } from 'react'; -import { AnswersActionsContext, useAnswersActions, useAnswersState } from '../src'; +import { AnswersHeadlessContext, useAnswersActions, useAnswersState } from '../src'; it('does not perform extra renders/listener registrations for nested components', async () => { const parentStateUpdates: Result[][] = []; @@ -49,9 +49,9 @@ it('does not perform extra renders/listener registrations for nested components' expect(parentStateUpdates).toHaveLength(0); expect(childStateUpdates).toHaveLength(0); render( - + - + ); expect(addListenerSpy).toHaveBeenCalledTimes(1); expect(parentStateUpdates).toHaveLength(1); @@ -90,9 +90,9 @@ it('does not trigger render on unmounted component', async () => { const answers = createAnswersHeadless(); render( - + - + ); act(() => answers.setQuery('resultsWithFilter')); await act( () => answers.executeUniversalQuery()); @@ -122,9 +122,9 @@ describe('uses the most recent selector',() => { const answers = createAnswersHeadless(); render( - + - + ); expect(screen.getByTestId('selected-state')).toHaveTextContent('initial selector'); @@ -157,9 +157,9 @@ describe('uses the most recent selector',() => { answers.setQuery('initial value'); expect(stateUpdates).toHaveLength(0); render( - + - + ); expect(stateUpdates).toEqual(['initial value']);