# presentation/views/search.view.ts

> 40 lines of code and 6 definitions.

Tree: Site tree
Language: typescript
Layer: product
Canonical: https://banes-lab.com/anatomy/tree#file-presentation-views-search-view-ts
Source text: https://banes-lab.com/assets/sources/source.986f1122a972ea2793dc757b77c3bc5dbfeb4a04617c32032b619f7615fd19dc.generated.txt

## Definitions

- `fillResults` (lexical_declaration, line 15)
- `renderSearch` (lexical_declaration, line 24)
- `spreads` (lexical_declaration, line 16)
- `query` (lexical_declaration, line 25)
- `holder` (lexical_declaration, line 29)
- `PAGE` (lexical_declaration, line 37, exported)

## Uses

- [core/factories/element.factory.ts](https://banes-lab.com/source/tree/core/factories/element.factory.ts.md)
- [core/predicates/document.predicate.ts](https://banes-lab.com/source/tree/core/predicates/document.predicate.ts.md)

## Source

```typescript
import { SEARCH_DESCRIPTION, SEARCH_TITLE } from "#configuration/strings/page.strings";
import { SEARCH_EMPTY_SECTIONS, SEARCH_META, SEARCH_SECTIONS } from "#configuration/strings/search.strings";
import { SEARCH_MIN_QUERY_LENGTH, SEARCH_QUERY_PARAM } from "#configuration/constants/search.constants";
import { appendChildren, createElement } from "#core/factories/element.factory";
import type { PageDefinition } from "#types/page.types";
import { SEARCH_PAGE } from "#core/ids/page.ids";
import { isStaticRender } from "#core/predicates/document.predicate";
import { loadCorpus } from "#domain/loaders/search.loader";
import { queryValue } from "#assets/link.assets";
import { renderDocument } from "#presentation/renderers/document.renderer";
import { renderSpread } from "#presentation/renderers/search.renderer";
import { renderTabHeader } from "#presentation/renderers/tab.renderer";
import { searchSpreads } from "#domain/converters/search.converter";

const fillResults = async function fillResults(holder: Element, query: string): Promise<void> {
    const spreads = searchSpreads(await loadCorpus(), query);
    if (spreads.length === 0) {
        holder.replaceChildren(renderDocument(SEARCH_META, SEARCH_EMPTY_SECTIONS));
        return;
    }
    appendChildren(holder, spreads.map(renderSpread));
};

const renderSearch = function renderSearch(): Element {
    const query = queryValue(window.location.search, SEARCH_QUERY_PARAM).trim();
    if (isStaticRender() || query.length < SEARCH_MIN_QUERY_LENGTH) {
        return renderDocument(SEARCH_META, SEARCH_SECTIONS);
    }
    const holder = createElement("div", {
        children: [renderTabHeader({ subtitle: query, title: SEARCH_TITLE, version: SEARCH_META.version })],
        className: "tab-page-content",
    });
    void fillResults(holder, query);
    return holder;
};

export const PAGE: PageDefinition = {
    content: { kind: "document", meta: SEARCH_META, sections: SEARCH_SECTIONS },
    description: SEARCH_DESCRIPTION,
    id: SEARCH_PAGE,
    render: renderSearch,
    title: SEARCH_TITLE,
};
```
