Skip to content

Commit

Permalink
feat: use Renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
SophieManley03 committed Jun 13, 2022
1 parent cf0254c commit 3f8ded1
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 16 deletions.
229 changes: 229 additions & 0 deletions packages/recommend-js/src/__tests__/templates.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/** @jsx h */
//import { frequentlyBoughtTogether } from '@algolia/recommend-js';
import { fireEvent, waitFor, within } from '@testing-library/dom';
import { createMultiSearchResponse } from '../../../../test/utils/createApiResponse';
import {
createRecommendClient,
hit,
} from '../../../../test/utils/createRecommendClient';
import { frequentlyBoughtTogether } from '../../dist/esm';

function createMockedRecommendClient() {
const recommendClient = createRecommendClient({
getFrequentlyBoughtTogether: jest.fn(() =>
Promise.resolve(
createMultiSearchResponse({
hits: [hit],
})
)
),
});

return {
recommendClient,
};
}

describe('templates', () => {
beforeEach(() => {
document.body.innerHTML = '';
});

test('renders JSX templates', async () => {
const panelContainer = document.createElement('div');
panelContainer.setAttribute('id', 'frequentlyBoughtTogether');

const { recommendClient } = createMockedRecommendClient();

document.body.appendChild(panelContainer);

frequentlyBoughtTogether<any>({
container: '#frequentlyBoughtTogether',
recommendClient,
indexName: 'products',
objectIDs: ['D06270-9132-995'],
itemComponent: ({ item }) => <div>{item.objectID}</div>,
});

await waitFor(() => {
expect(within(panelContainer).getByText('1').parentNode)
.toMatchInlineSnapshot(`
<ul
aria-labelledby="autocomplete-0-label"
class="aa-List"
id="autocomplete-0-list"
role="listbox"
>
<li
aria-selected="false"
class="aa-Item"
id="autocomplete-0-item-0"
role="option"
>
<div
class="MyCustomItemClass"
>
1
</div>
</li>
</ul>
`);
});

// fireEvent.input(input, { target: { value: 'nothing' } });

// await waitFor(() => {
// expect(within(panelContainer).getByText('No results').parentNode)
// .toMatchInlineSnapshot(`
// <div
// class="aa-SourceNoResults"
// >
// <div
// class="MyCustomNoResultsClass"
// >
// No results
// </div>
// </div>
// `);
// });
});

// test('renders templates using `createElement`', async () => {
// const container = document.createElement('div');
// const panelContainer = document.createElement('div');

// document.body.appendChild(panelContainer);

// autocomplete<{ label: string }>({
// container,
// panelContainer,
// id: 'autocomplete-0',
// getSources() {
// return [
// {
// sourceId: 'testSource',
// getItems({ query }) {
// return [{ label: '1' }].filter(({ label }) =>
// label.includes(query)
// );
// },
// templates: {
// header({ createElement }) {
// return createElement(
// 'header',
// { className: 'MyCustomHeaderClass' },
// 'Header'
// );
// },
// item({ item, createElement }) {
// return createElement(
// 'div',
// { className: 'MyCustomItemClass' },
// item.label
// );
// },
// footer({ createElement }) {
// return createElement(
// 'footer',
// { className: 'MyCustomFooterClass' },
// 'Footer'
// );
// },
// noResults({ createElement }) {
// return createElement(
// 'div',
// { className: 'MyCustomNoResultsClass' },
// 'No results'
// );
// },
// },
// },
// ];
// },
// });

// const input = container.querySelector<HTMLInputElement>('.aa-Input');

// fireEvent.input(input, { target: { value: '1' } });

// await waitFor(() => {
// expect(within(panelContainer).getByRole('banner')).toMatchInlineSnapshot(`
// <header
// class="MyCustomHeaderClass"
// >
// Header
// </header>
// `);
// expect(within(panelContainer).getByRole('listbox'))
// .toMatchInlineSnapshot(`
// <ul
// aria-labelledby="autocomplete-0-label"
// class="aa-List"
// id="autocomplete-0-list"
// role="listbox"
// >
// <li
// aria-selected="false"
// class="aa-Item"
// id="autocomplete-0-item-0"
// role="option"
// >
// <div
// class="MyCustomItemClass"
// >
// 1
// </div>
// </li>
// </ul>
// `);
// expect(within(panelContainer).getByRole('contentinfo'))
// .toMatchInlineSnapshot(`
// <footer
// class="MyCustomFooterClass"
// >
// Footer
// </footer>
// `);
// });

// fireEvent.input(input, { target: { value: 'nothing' } });

// await waitFor(() => {
// expect(within(panelContainer).getByText('No results').parentNode)
// .toMatchInlineSnapshot(`
// <div
// class="aa-SourceNoResults"
// >
// <div
// class="MyCustomNoResultsClass"
// >
// No results
// </div>
// </div>
// `);
// });
// });
});

function htmlShim(template: Array<string | any> | string, html: HTMLTemplate) {
if (typeof template === 'string') {
return html(([template] as unknown) as TemplateStringsArray);
}

const [strings, variables] = template.reduce(
(acc, part, index) => {
const isEven = index % 2 === 0;

acc[Math.abs(Number(!isEven))].push(part);

return acc;
},
[[], []]
);

// Before TypeScript 2, `TemplateStringsArray` was assignable to `string[]`.
// This is no longer the case, but `htm` does accept `string[]`.
// Since this solution is for IE11 users who don't have a build step, it isn't
// necessary to complexify the function to make it type-safe.
return html((strings as unknown) as TemplateStringsArray, ...variables);
}
3 changes: 0 additions & 3 deletions packages/recommend-vdom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
"build": "yarn build:clean && yarn build:esm && yarn build:umd && yarn build:types",
"prepare": "yarn build:esm && yarn build:types"
},
"dependencies": {
"preact": "^10.0.0"
},
"devDependencies": {
"@algolia/recommend-core": "1.3.1"
}
Expand Down
16 changes: 5 additions & 11 deletions packages/recommend-vdom/src/types/RecommendComponentProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,14 @@ import { FacetsViewProps } from './FacetsViewProps';
import { RecommendClassNames } from './RecommendClassNames';
import { RecommendStatus } from './RecommendStatus';
import { RecommendTranslations } from './RecommendTranslations';
import { Pragma, PragmaFrag } from './Renderer';
import { Renderer } from './Renderer';
import { ViewProps } from './ViewProps';

export type ItemComponentProps<TObject> = {
item: TObject;
} & RenderProps;
} & Renderer;

export type RenderProps = {
createElement: Pragma;
Fragment: PragmaFrag;
};

export type HeaderComponentProps<TObject> = RenderProps &
ComponentProps<TObject>;
export type HeaderComponentProps<TObject> = Renderer & ComponentProps<TObject>;

export type ComponentProps<TObject> = {
classNames: RecommendClassNames;
Expand All @@ -37,7 +31,7 @@ export type RecommendComponentProps<TObject> = {
items: Array<RecordWithObjectID<TObject>>;
classNames?: RecommendClassNames;
children?(props: ChildrenProps<TObject>): JSX.Element;
fallbackComponent?(props: RenderProps): JSX.Element;
fallbackComponent?(props: Renderer): JSX.Element;
headerComponent?(props: HeaderComponentProps<TObject>): JSX.Element;
status: RecommendStatus;
translations?: RecommendTranslations;
Expand All @@ -55,7 +49,7 @@ export type TrendingComponentProps<TObject> = {
items: Array<FacetEntry<TObject>>;
classNames?: RecommendClassNames;
children?(props: ChildrenProps<TObject>): JSX.Element;
fallbackComponent?(props: RenderProps): JSX.Element;
fallbackComponent?(props: Renderer): JSX.Element;
headerComponent?(props: HeaderComponentProps<TObject>): JSX.Element;
status: RecommendStatus;
translations?: RecommendTranslations;
Expand Down
4 changes: 2 additions & 2 deletions packages/recommend-vdom/src/types/ViewProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export type ViewProps<
classNames: TClassNames;
itemComponent({
item: TItem,
createElement: Pragma,
Fragment: PragmaFrag,
createElement: TPragma,
Fragment: TPragmaFrag,
}): JSX.Element;
items: TItem[];
translations: TTranslations;
Expand Down

0 comments on commit 3f8ded1

Please sign in to comment.