diff --git a/packages/autocomplete-js/src/__tests__/render.test.ts b/packages/autocomplete-js/src/__tests__/render.test.ts index e3b86667d..c9b858a46 100644 --- a/packages/autocomplete-js/src/__tests__/render.test.ts +++ b/packages/autocomplete-js/src/__tests__/render.test.ts @@ -3,7 +3,7 @@ import { createElement as preactCreateElement, Fragment, Fragment as PreactFragment, - render, + render as preactRender, } from 'preact'; import { autocomplete } from '../autocomplete'; @@ -80,7 +80,7 @@ describe('render', () => { ]; }, render({ createElement }, root) { - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, }); @@ -126,7 +126,7 @@ describe('render', () => { expect(panelContainer.querySelector('.aa-Panel')).toBe( root ); - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, }); }); @@ -168,7 +168,7 @@ describe('render', () => { completion: null, }); - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, }); @@ -238,7 +238,7 @@ describe('render', () => { }), }); - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, }); @@ -308,7 +308,7 @@ describe('render', () => { }), ]); - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, }); @@ -379,7 +379,7 @@ describe('render', () => { }, }) ); - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, }); @@ -422,7 +422,7 @@ describe('render', () => { }, render({ createElement }, root) { expect(createElement).toBe(preactCreateElement); - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, }); }); @@ -455,11 +455,56 @@ describe('render', () => { }, render({ createElement, Fragment }, root) { expect(Fragment).toBe(PreactFragment); - render(createElement(Fragment, null, 'testSource'), root); + preactRender(createElement(Fragment, null, 'testSource'), root); }, }); }); + test('provides a default render', async () => { + const container = document.createElement('div'); + const panelContainer = document.createElement('div'); + + document.body.appendChild(panelContainer); + autocomplete<{ label: string }>({ + container, + panelContainer, + initialState: { + isOpen: true, + }, + getSources() { + return [ + { + sourceId: 'testSource', + getItems() { + return [{ label: '1' }]; + }, + templates: { + item({ item }) { + return item.label; + }, + }, + }, + ]; + }, + render({ children, render }, root) { + expect(render).toBe(preactRender); + render(children, root); + }, + }); + + const input = container.querySelector('.aa-Input'); + + fireEvent.input(input, { target: { value: 'a' } }); + + await waitFor(() => { + expect( + panelContainer.querySelector('.aa-Panel') + ).toBeInTheDocument(); + + expect(panelContainer).toHaveTextContent('1'); + }); + }); + test('retrieves the custom createElement from the renderer', () => { const container = document.createElement('div'); const panelContainer = document.createElement('div'); @@ -489,7 +534,7 @@ describe('render', () => { }, render({ createElement }, root) { expect(createElement).toBe(mockCreateElement); - render(createElement('div', null, 'testSource'), root); + preactRender(createElement('div', null, 'testSource'), root); }, renderer: { createElement: mockCreateElement, @@ -527,7 +572,7 @@ describe('render', () => { }, render({ createElement, Fragment }, root) { expect(Fragment).toBe(CustomFragment); - render(createElement(Fragment, null, 'testSource'), root); + preactRender(createElement(Fragment, null, 'testSource'), root); }, renderer: { createElement: preactCreateElement, diff --git a/packages/autocomplete-js/src/render.tsx b/packages/autocomplete-js/src/render.tsx index 3c1767746..fc1353700 100644 --- a/packages/autocomplete-js/src/render.tsx +++ b/packages/autocomplete-js/src/render.tsx @@ -2,8 +2,9 @@ import { AutocompleteApi as AutocompleteCoreApi, AutocompleteScopeApi, + BaseItem, } from '@algolia/autocomplete-core'; -import { BaseItem } from '@algolia/autocomplete-core/src'; +import { render as preactRender } from 'preact'; import { AutocompleteClassNames, @@ -195,6 +196,7 @@ export function renderPanel( elements, createElement, Fragment, + render: preactRender, components, ...autocompleteScopeApi, }, diff --git a/packages/autocomplete-js/src/types/AutocompleteRender.ts b/packages/autocomplete-js/src/types/AutocompleteRender.ts index 46f449ef4..b1545e00b 100644 --- a/packages/autocomplete-js/src/types/AutocompleteRender.ts +++ b/packages/autocomplete-js/src/types/AutocompleteRender.ts @@ -4,6 +4,8 @@ import { AutocompleteComponents } from './AutocompleteComponents'; import { Pragma, PragmaFrag, VNode } from './AutocompleteRenderer'; import { AutocompleteState } from './AutocompleteState'; +import { ComponentChild } from '.'; + export type AutocompleteRender = ( params: AutocompleteScopeApi & { children: VNode; @@ -13,6 +15,11 @@ export type AutocompleteRender = ( components: AutocompleteComponents; createElement: Pragma; Fragment: PragmaFrag; + render: ( + vnode: ComponentChild, + containerNode: Element | Document | ShadowRoot | DocumentFragment, + replaceNode?: Element | Text | undefined + ) => void; }, root: HTMLElement ) => void; diff --git a/packages/autocomplete-js/src/types/AutocompleteRenderer.ts b/packages/autocomplete-js/src/types/AutocompleteRenderer.ts index 5504f463b..c8a2431b2 100644 --- a/packages/autocomplete-js/src/types/AutocompleteRenderer.ts +++ b/packages/autocomplete-js/src/types/AutocompleteRenderer.ts @@ -5,7 +5,7 @@ export type Pragma = ( ) => JSX.Element; export type PragmaFrag = any; -type ComponentChild = +export type ComponentChild = | VNode | object | string