diff --git a/packages/autocomplete-plugin-query-suggestions/src/__tests__/createQuerySuggestionsPlugin.test.ts b/packages/autocomplete-plugin-query-suggestions/src/__tests__/createQuerySuggestionsPlugin.test.ts index 1b2cbfb96..26a1f071b 100644 --- a/packages/autocomplete-plugin-query-suggestions/src/__tests__/createQuerySuggestionsPlugin.test.ts +++ b/packages/autocomplete-plugin-query-suggestions/src/__tests__/createQuerySuggestionsPlugin.test.ts @@ -645,4 +645,140 @@ describe('createQuerySuggestionsPlugin', () => { }, ]); }); + + test('accepts translation', async () => { + const querySuggestionsPlugin = createQuerySuggestionsPlugin({ + searchClient, + indexName: 'indexName', + translations: { + fillQueryTitle: (query) => `TEST FILL "${query}"`, + }, + }); + + const container = document.createElement('div'); + const panelContainer = document.createElement('div'); + + document.body.appendChild(panelContainer); + + autocomplete({ + container, + panelContainer, + plugins: [querySuggestionsPlugin], + }); + + const input = container.querySelector('.aa-Input'); + + fireEvent.input(input, { target: { value: 'a' } }); + + await waitFor(() => { + expect( + within( + panelContainer.querySelector( + '[data-autocomplete-source-id="querySuggestionsPlugin"]' + ) + ) + .getAllByRole('option') + .map((option) => option.children) + ).toMatchInlineSnapshot(` + Array [ + HTMLCollection [ +
+
+
+ + + +
+
+
+ cooktop +
+
+
+
+ +
+
, + ], + HTMLCollection [ +
+
+
+ + + +
+
+
+ range +
+
+
+
+ +
+
, + ], + ] + `); + }); + }); }); diff --git a/packages/autocomplete-plugin-query-suggestions/src/constants.ts b/packages/autocomplete-plugin-query-suggestions/src/constants.ts new file mode 100644 index 000000000..c7a488c69 --- /dev/null +++ b/packages/autocomplete-plugin-query-suggestions/src/constants.ts @@ -0,0 +1,6 @@ +import { AutocompleteSuggestionsPluginTranslations } from './types'; + +export const defaultTranslations: Required = + { + fillQueryTitle: (text: string) => `Fill query with "${text}"`, + }; diff --git a/packages/autocomplete-plugin-query-suggestions/src/createQuerySuggestionsPlugin.ts b/packages/autocomplete-plugin-query-suggestions/src/createQuerySuggestionsPlugin.ts index d6927be16..0f85e6b0c 100644 --- a/packages/autocomplete-plugin-query-suggestions/src/createQuerySuggestionsPlugin.ts +++ b/packages/autocomplete-plugin-query-suggestions/src/createQuerySuggestionsPlugin.ts @@ -8,8 +8,13 @@ import { getAttributeValueByPath } from '@algolia/autocomplete-shared'; import { SearchOptions } from '@algolia/client-search'; import { SearchClient } from 'algoliasearch/lite'; +import { defaultTranslations } from './constants'; import { getTemplates } from './getTemplates'; -import { AutocompleteQuerySuggestionsHit, QuerySuggestionsHit } from './types'; +import { + AutocompleteQuerySuggestionsHit, + AutocompleteSuggestionsPluginTranslations, + QuerySuggestionsHit, +} from './types'; export type CreateQuerySuggestionsPluginParams< TItem extends QuerySuggestionsHit @@ -64,6 +69,13 @@ export type CreateQuerySuggestionsPluginParams< * @link https://www.algolia.com/doc/ui-libraries/autocomplete/api-reference/autocomplete-plugin-query-suggestions/createQuerySuggestionsPlugin/#param-categoriesperitem */ categoriesPerItem?: number; + + /** + * A mapping of translation strings. + * + * Defaults to English values. + */ + translations?: Partial; }; export function createQuerySuggestionsPlugin< @@ -79,6 +91,7 @@ export function createQuerySuggestionsPlugin< categoryAttribute, itemsWithCategories, categoriesPerItem, + translations, } = getOptions(options); return { @@ -156,7 +169,7 @@ export function createQuerySuggestionsPlugin< }, }); }, - templates: getTemplates({ onTapAhead }), + templates: getTemplates({ onTapAhead, translations }), }, onTapAhead, state: state as AutocompleteState, @@ -176,5 +189,9 @@ function getOptions( itemsWithCategories: 1, categoriesPerItem: 1, ...options, + translations: { + ...defaultTranslations, + ...options.translations, + }, }; } diff --git a/packages/autocomplete-plugin-query-suggestions/src/getTemplates.tsx b/packages/autocomplete-plugin-query-suggestions/src/getTemplates.tsx index a693133b8..d813bdbf0 100644 --- a/packages/autocomplete-plugin-query-suggestions/src/getTemplates.tsx +++ b/packages/autocomplete-plugin-query-suggestions/src/getTemplates.tsx @@ -2,14 +2,19 @@ /** @jsx createElement */ import { SourceTemplates } from '@algolia/autocomplete-js'; -import { QuerySuggestionsHit } from './types'; +import { + AutocompleteSuggestionsPluginTranslations, + QuerySuggestionsHit, +} from './types'; export type GetTemplatesParams = { onTapAhead(item: TItem): void; + translations: AutocompleteSuggestionsPluginTranslations; }; export function getTemplates({ onTapAhead, + translations, }: GetTemplatesParams): SourceTemplates { return { item({ item, createElement, components }) { @@ -48,7 +53,7 @@ export function getTemplates({
+ +
+ , + ], + ] + `); + }); + }); + + test('accepts partial translated strings', async () => { + const storage = createInMemoryStorage([ + { + id: 'query', + label: 'query', + }, + ]); + + const recentSearchesPlugin = createRecentSearchesPlugin({ + storage, + translations: { + removeSearchTitle: 'TEST REMOVE', + }, + }); + + const container = document.createElement('div'); + const panelContainer = document.createElement('div'); + + document.body.appendChild(panelContainer); + + autocomplete({ + container, + panelContainer, + openOnFocus: true, + plugins: [recentSearchesPlugin], + }); + + const input = container.querySelector('.aa-Input'); + + fireEvent.input(input, { target: { value: 'a' } }); + + await waitFor(() => { + expect( + within( + panelContainer.querySelector( + '[data-autocomplete-source-id="recentSearchesPlugin"]' + ) + ) + .getAllByRole('option') + .map((option) => option.children) + ).toMatchInlineSnapshot(` + Array [ + HTMLCollection [ +
+
+
+ + + +
+
+
+ query +
+
+
+
+ + +
+
, + ], + ] + `); + }); + }); + test('supports custom templates', async () => { const storage = createInMemoryStorage([ { diff --git a/packages/autocomplete-plugin-recent-searches/src/constants.ts b/packages/autocomplete-plugin-recent-searches/src/constants.ts index dea5dec49..ce64ee9f4 100644 --- a/packages/autocomplete-plugin-recent-searches/src/constants.ts +++ b/packages/autocomplete-plugin-recent-searches/src/constants.ts @@ -1,3 +1,11 @@ +import { AutocompleteRecentSearchesPluginTranslations } from './types'; + export const LOCAL_STORAGE_KEY = 'AUTOCOMPLETE_RECENT_SEARCHES'; export const LOCAL_STORAGE_KEY_TEST = '__AUTOCOMPLETE_RECENT_SEARCHES_PLUGIN_TEST_KEY__'; + +export const defaultTranslations: AutocompleteRecentSearchesPluginTranslations = + { + removeSearchTitle: 'Remove this search', + fillQueryTitle: (text: string) => `Fill query with "${text}"`, + }; diff --git a/packages/autocomplete-plugin-recent-searches/src/createLocalStorageRecentSearchesPlugin.ts b/packages/autocomplete-plugin-recent-searches/src/createLocalStorageRecentSearchesPlugin.ts index 4834051f6..4d77edde9 100644 --- a/packages/autocomplete-plugin-recent-searches/src/createLocalStorageRecentSearchesPlugin.ts +++ b/packages/autocomplete-plugin-recent-searches/src/createLocalStorageRecentSearchesPlugin.ts @@ -1,6 +1,6 @@ import { AutocompletePlugin } from '@algolia/autocomplete-js'; -import { LOCAL_STORAGE_KEY } from './constants'; +import { defaultTranslations, LOCAL_STORAGE_KEY } from './constants'; import { createLocalStorage } from './createLocalStorage'; import { createRecentSearchesPlugin, @@ -49,7 +49,7 @@ export type CreateRecentSearchesLocalStorageOptions< type LocalStorageRecentSearchesPluginOptions = Pick< CreateRecentSearchesPluginParams, - 'transformSource' | 'subscribe' + 'transformSource' | 'subscribe' | 'translations' > & CreateRecentSearchesLocalStorageOptions; @@ -87,5 +87,9 @@ function getOptions( search: defaultSearch, transformSource: ({ source }) => source, ...options, + translations: { + ...defaultTranslations, + ...options.translations, + }, }; } diff --git a/packages/autocomplete-plugin-recent-searches/src/createRecentSearchesPlugin.ts b/packages/autocomplete-plugin-recent-searches/src/createRecentSearchesPlugin.ts index 78b374923..6c33482aa 100644 --- a/packages/autocomplete-plugin-recent-searches/src/createRecentSearchesPlugin.ts +++ b/packages/autocomplete-plugin-recent-searches/src/createRecentSearchesPlugin.ts @@ -7,9 +7,15 @@ import { import { createRef, MaybePromise, warn } from '@algolia/autocomplete-shared'; import { SearchOptions } from '@algolia/client-search'; +import { defaultTranslations } from './constants'; import { createStorageApi } from './createStorageApi'; import { getTemplates } from './getTemplates'; -import { RecentSearchesItem, Storage, StorageApi } from './types'; +import { + RecentSearchesItem, + Storage, + StorageApi, + AutocompleteRecentSearchesPluginTranslations, +} from './types'; export interface RecentSearchesPluginData extends StorageApi { @@ -44,6 +50,13 @@ export type CreateRecentSearchesPluginParams = onTapAhead(item: TItem): void; }): AutocompleteSource; subscribe?(params: PluginSubscribeParams): void; + + /** + * A mapping of translation strings. + * + * Defaults to English values. + */ + translations?: Partial; }; function getDefaultSubscribe( @@ -68,7 +81,8 @@ function getDefaultSubscribe( export function createRecentSearchesPlugin( options: CreateRecentSearchesPluginParams ): AutocompletePlugin> { - const { storage, transformSource, subscribe } = getOptions(options); + const { storage, transformSource, subscribe, translations } = + getOptions(options); const store = createStorageApi(storage); const lastItemsRef = createRef>([]); @@ -114,7 +128,7 @@ export function createRecentSearchesPlugin( getItems() { return items; }, - templates: getTemplates({ onRemove, onTapAhead }), + templates: getTemplates({ onRemove, onTapAhead, translations }), }, onRemove, onTapAhead, @@ -164,5 +178,9 @@ function getOptions( return { transformSource: ({ source }) => source, ...options, + translations: { + ...defaultTranslations, + ...options.translations, + }, }; } diff --git a/packages/autocomplete-plugin-recent-searches/src/getTemplates.tsx b/packages/autocomplete-plugin-recent-searches/src/getTemplates.tsx index bed4196ef..9b343cf67 100644 --- a/packages/autocomplete-plugin-recent-searches/src/getTemplates.tsx +++ b/packages/autocomplete-plugin-recent-searches/src/getTemplates.tsx @@ -2,16 +2,21 @@ /** @jsx createElement */ import { SourceTemplates } from '@algolia/autocomplete-js'; -import { RecentSearchesItem } from './types'; +import { + RecentSearchesItem, + AutocompleteRecentSearchesPluginTranslations, +} from './types'; export type GetTemplatesParams = { onRemove(id: string): void; onTapAhead(item: TItem): void; + translations: AutocompleteRecentSearchesPluginTranslations; }; export function getTemplates({ onRemove, onTapAhead, + translations, }: GetTemplatesParams): SourceTemplates { return { item({ item, createElement, components }) { @@ -40,7 +45,7 @@ export function getTemplates({