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(sourceId): Add sourceId to provide data-autocomplete-source-id on section source container #429

Merged
merged 8 commits into from
Feb 5, 2021
Merged
3 changes: 3 additions & 0 deletions examples/js/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ insightsClient('init', { appId, apiKey });

const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ insightsClient });
const recentSearchesPlugin = createLocalStorageRecentSearchesPlugin({
sourceId: 'recentSearchesPlugin',
shortcuts marked this conversation as resolved.
Show resolved Hide resolved
key: 'search',
limit: 3,
});
const querySuggestionsPlugin = createQuerySuggestionsPlugin({
searchClient,
sourceId: 'querySuggestionsPlugin',
shortcuts marked this conversation as resolved.
Show resolved Hide resolved
indexName: 'instant_search_demo_query_suggestions',
getSearchParams({ state }) {
return recentSearchesPlugin.data.getAlgoliaSearchParams({
Expand Down Expand Up @@ -62,6 +64,7 @@ autocomplete({

return [
{
sourceId: 'algoliaHits',
shortcuts marked this conversation as resolved.
Show resolved Hide resolved
getItems() {
return getAlgoliaHits<Product>({
searchClient,
Expand Down
1 change: 1 addition & 0 deletions examples/js/shortcutsPlugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const shortcutsPlugin: AutocompletePlugin<DarkModeItem> = {

return [
{
sourceId: 'shortcutsPlugin',
getItems() {
return [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe.skip('concurrency', () => {
return defer(() => {
return [
{
sourceId: 'testSource',
shortcuts marked this conversation as resolved.
Show resolved Hide resolved
getItems() {
return [{ label: query }];
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,7 @@ describe('getInputProps', () => {
{ label: '2', url: '#2' },
],
source: {
sourceId: 'testSource',
shortcuts marked this conversation as resolved.
Show resolved Hide resolved
getItemInputValue: expect.any(Function),
getItemUrl: expect.any(Function),
getItems: expect.any(Function),
Expand Down
4 changes: 4 additions & 0 deletions packages/autocomplete-core/src/__tests__/getSources.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ describe('getSources', () => {
getSources: () => {
return [
{
sourceId: 'testSource',
getItems() {
return [];
},
Expand Down Expand Up @@ -78,6 +79,7 @@ describe('getSources', () => {
templates: expect.objectContaining({
item: expect.any(Function),
}),
sourceId: expect.any(String),
},
}),
]),
Expand All @@ -92,6 +94,7 @@ describe('getSources', () => {
getSources: () => {
return [
{
sourceId: 'pluginSource',
getItems() {
return [];
},
Expand All @@ -107,6 +110,7 @@ describe('getSources', () => {
getSources: () => {
return [
{
sourceId: 'testSource',
getItems() {
return [];
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('stallThreshold', () => {
return defer(() => {
return [
{
sourceId: 'testSource',
getItems() {
return [{ label: '1' }, { label: 2 }];
},
Expand Down Expand Up @@ -60,6 +61,7 @@ describe('stallThreshold', () => {
return defer(() => {
return [
{
sourceId: 'testSource',
getItems() {
return [{ label: '1' }, { label: 2 }];
},
Expand Down
4 changes: 4 additions & 0 deletions packages/autocomplete-core/src/types/AutocompleteSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export interface AutocompleteSource<TItem extends BaseItem> {
* You can trigger different behaviors based on the event `type`.
*/
onActive?(params: OnHighlightParams<TItem>): void;
/**
* Applied to data-autocomplete-source-id on the section source container
shortcuts marked this conversation as resolved.
Show resolved Hide resolved
*/
sourceId: string;
}

export type InternalAutocompleteSource<TItem extends BaseItem> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getNormalizedSources } from '../getNormalizedSources';

describe('getNormalizedSources', () => {
test('returns a promise of sources', async () => {
const getSources = () => [{ getItems: () => [] }];
const getSources = () => [{ sourceId: 'testSource', getItems: () => [] }];
const params = {
query: '',
state: createState({
Expand All @@ -23,12 +23,17 @@ describe('getNormalizedSources', () => {
getItems: expect.any(Function),
onActive: expect.any(Function),
onSelect: expect.any(Function),
sourceId: 'testSource',
},
]);
});

test('filters out falsy sources', async () => {
const getSources = () => [{ getItems: () => [] }, false, undefined];
const getSources = () => [
{ sourceId: 'testSource', getItems: () => [] },
false,
undefined,
];
const params = {
query: '',
state: createState({
Expand All @@ -44,6 +49,7 @@ describe('getNormalizedSources', () => {
getItems: expect.any(Function),
onActive: expect.any(Function),
onSelect: expect.any(Function),
sourceId: 'testSource',
},
]);
});
Expand All @@ -64,8 +70,33 @@ describe('getNormalizedSources', () => {
);
});

test('with missing sourceId triggers invariant', async () => {
const getSources = () => [
{
getItems() {
return [];
},
templates: {
item() {},
},
},
];
const params = {
query: '',
state: createState({}),
...createScopeApi(),
};

// @ts-expect-error
await expect(getNormalizedSources(getSources, params)).rejects.toEqual(
new Error(
'[Autocomplete] The `getSources` function must return a `sourceId` string but returned type "undefined":\n\nundefined'
)
);
});

test('provides a default implementation for getItemInputValue which returns the query', async () => {
const getSources = () => [{ getItems: () => [] }];
const getSources = () => [{ sourceId: 'testSource', getItems: () => [] }];
const params = {
query: '',
state: createState({
Expand All @@ -82,7 +113,7 @@ describe('getNormalizedSources', () => {
});

test('provides a default implementation for getItemUrl', async () => {
const getSources = () => [{ getItems: () => [] }];
const getSources = () => [{ sourceId: 'testSource', getItems: () => [] }];
const params = {
query: '',
state: createState({}),
Expand All @@ -97,7 +128,7 @@ describe('getNormalizedSources', () => {
});

test('provides a default implementation for onSelect', async () => {
const getSources = () => [{ getItems: () => [] }];
const getSources = () => [{ sourceId: 'testSource', getItems: () => [] }];
const params = {
query: '',
state: createState({}),
Expand All @@ -119,7 +150,7 @@ describe('getNormalizedSources', () => {
});

test('provides a default implementation for onActive', async () => {
const getSources = () => [{ getItems: () => [] }];
const getSources = () => [{ sourceId: 'testSource', getItems: () => [] }];
const params = {
query: '',
state: createState({}),
Expand Down
7 changes: 7 additions & 0 deletions packages/autocomplete-core/src/utils/getNormalizedSources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ export function getNormalizedSources<TItem extends BaseItem>(
Boolean(maybeSource)
)
.map((source) => {
invariant(
source.sourceId !== undefined,
`The \`getSources\` function must return a \`sourceId\` string but returned type ${JSON.stringify(
typeof source.sourceId
)}:\n\n${JSON.stringify(source.sourceId, null, 2)}`
shortcuts marked this conversation as resolved.
Show resolved Hide resolved
);

const normalizedSource: InternalAutocompleteSource<TItem> = {
getItemInputValue({ state }) {
return state.query;
Expand Down
11 changes: 11 additions & 0 deletions packages/autocomplete-js/src/__tests__/autocomplete.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [
{ label: 'Item 1' },
Expand Down Expand Up @@ -167,6 +168,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [];
},
Expand Down Expand Up @@ -206,6 +208,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [];
},
Expand Down Expand Up @@ -245,6 +248,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [];
},
Expand Down Expand Up @@ -290,6 +294,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [];
},
Expand Down Expand Up @@ -338,6 +343,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [];
},
Expand Down Expand Up @@ -383,6 +389,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [
{ label: 'Item 1' },
Expand Down Expand Up @@ -418,6 +425,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [
{ label: 'Item 1' },
Expand Down Expand Up @@ -449,6 +457,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [
{ label: 'Item 1' },
Expand Down Expand Up @@ -482,6 +491,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [
{ label: 'Item 1' },
Expand Down Expand Up @@ -512,6 +522,7 @@ describe('autocomplete-js', () => {
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return [
{ label: 'Item 1' },
Expand Down
1 change: 1 addition & 0 deletions packages/autocomplete-js/src/__tests__/positioning.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const querySuggestionsFixturePlugin: AutocompletePlugin<
getSources() {
return [
{
sourceId: 'testSource',
getItems() {
return querySuggestions;
},
Expand Down
6 changes: 5 additions & 1 deletion packages/autocomplete-js/src/render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ export function renderPanel<TItem extends BaseItem>(
dom.panel.classList.toggle('aa-Panel--stalled', state.status === 'stalled');

const sections = state.collections.map(({ source, items }, sourceIndex) => (
<section key={sourceIndex} className={classNames.source}>
<section
key={sourceIndex}
className={classNames.source}
data-autocomplete-source-id={source.sourceId}
>
{source.templates.header && (
<div className={classNames.sourceHeader}>
{source.templates.header({
Expand Down
1 change: 1 addition & 0 deletions packages/autocomplete-js/src/types/AutocompleteSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type AutocompleteSource<TItem extends BaseItem> = WithTemplates<
AutocompleteCoreSource<TItem>,
TItem
>;

export type InternalAutocompleteSource<TItem extends BaseItem> = WithTemplates<
InternalAutocompleteCoreSource<TItem>,
TItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export type CreateQuerySuggestionsPluginParams<
> = {
searchClient: SearchClient;
indexName: string;
sourceId: string;
getSearchParams?(params: { state: AutocompleteState<TItem> }): SearchOptions;
getTemplates?(params: GetTemplatesParams<TItem>): SourceTemplates<TItem>;
};
Expand All @@ -26,6 +27,7 @@ export function createQuerySuggestionsPlugin<
>({
searchClient,
indexName,
sourceId,
getSearchParams = () => ({}),
getTemplates = defaultGetTemplates,
}: CreateQuerySuggestionsPluginParams<TItem>): AutocompletePlugin<
Expand All @@ -36,6 +38,7 @@ export function createQuerySuggestionsPlugin<
getSources({ query, setQuery, refresh, state }) {
return [
{
sourceId,
getItemInputValue({ item }) {
return item.query;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export type CreateRecentSearchesLocalStorageOptions<
* Function to search in the recent items.
*/
search?(params: SearchParams<TItem>): Array<Highlighted<TItem>>;
/**
* Applied to data-autocomplete-source-id on the section source container
*/
sourceId: string;
};

type LocalStorageRecentSearchesPluginOptions<
Expand All @@ -48,6 +52,7 @@ export function createLocalStorageRecentSearchesPlugin<
limit = 5,
getTemplates,
search = defaultSearch,
sourceId,
}: LocalStorageRecentSearchesPluginOptions<TItem>): AutocompletePlugin<
TItem,
RecentSearchesPluginData
Expand All @@ -56,10 +61,12 @@ export function createLocalStorageRecentSearchesPlugin<
key: [LOCAL_STORAGE_KEY, key].join(':'),
limit,
search,
sourceId,
});

return createRecentSearchesPlugin({
getTemplates,
storage,
sourceId,
});
}
Loading