UNPKG

terriajs

Version:

Geospatial data visualization platform.

124 lines (122 loc) 4.8 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { observer } from "mobx-react"; import Mustache from "mustache"; import { useCallback, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useVirtual } from "react-virtual"; import styled from "styled-components"; import Box from "../../../Styled/Box"; import Button from "../../../Styled/Button"; import parseCustomMarkdownToReact from "../../Custom/parseCustomMarkdownToReact"; import MapEffects from "./MapEffects"; const SearchResults = (props) => { const { item, results } = props; const [currentMapEffect, setCurrentMapEffect] = useState({ is: "highlightAll" }); const selectedResult = currentMapEffect.is === "highlightSingleResult" ? currentMapEffect.result : undefined; const parentRef = useRef(null); const list = useVirtual({ size: results.length, parentRef, estimateSize: useCallback(() => 50, []) }); const [t] = useTranslation(); const toggleSelection = (newSelection) => { if (currentMapEffect.is === newSelection.is && currentMapEffect.result === newSelection.result) { setCurrentMapEffect({ is: "none" }); } else { setCurrentMapEffect(newSelection); } }; return (_jsxs(Wrapper, { children: [_jsx(ResultsCount, { count: results.length }), _jsxs(ActionMenu, { children: [_jsx(ActionButton, { selected: currentMapEffect.is === "highlightAll", onClick: () => toggleSelection({ is: "highlightAll" }), children: t("itemSearchTool.actions.highlightAll") }), _jsx(ActionButton, { selected: currentMapEffect.is === "showMatchingOnly", onClick: () => toggleSelection({ is: "showMatchingOnly" }), children: t("itemSearchTool.actions.showMatchingOnly") })] }), _jsx(List, { ref: parentRef, height: `250px`, children: _jsx(ListInner, { height: `${list.totalSize}px`, children: list.virtualItems.map(({ index, ...row }) => (_jsx(Result, { result: results[index], isSelected: results[index].id === selectedResult?.id, isEven: index % 2 === 0, onClick: () => toggleSelection({ is: "highlightSingleResult", result: results[index] }), template: props.template, style: { position: "absolute", top: 0, left: 0, width: "100%", height: `${row.size}px`, transform: `translateY(${row.start}px)` } }, results[index].id))) }) }), _jsx(MapEffects, { effect: currentMapEffect, item: item, results: results })] })); }; export const Result = observer((props) => { const { result, template, isEven, isSelected, style } = props; const content = template ? parseCustomMarkdownToReact(Mustache.render(template, result.properties)) : result.id; const onClick = (e) => { try { props.onClick(result); } finally { e.preventDefault(); } }; return (_jsx(ClickableItem, { role: "button", isEven: isEven, isSelected: isSelected, onClick: onClick, style: style, children: content })); }); const ClickableItem = styled.a ` display: block; box-sizing: border-box; padding: 5px 10px; cursor: pointer; ${(p) => `background-color: ${p.isSelected ? p.theme.toolPrimaryColor : p.isEven ? p.theme.dark : p.theme.darkLighter};`} `; const List = styled.div ` ${(p) => `height: ${p.height}`}; width: 100%; overflow: auto; `; const ListInner = styled.div ` ${(p) => `height: ${p.height}`}; width: 100%; position: relative; `; const Wrapper = styled(Box).attrs({ column: true, flex: 1 }) ` > :only-child { flex: 1; align-self: center; align-items: center; } `; export const ResultsCount = ({ count }) => { const [t] = useTranslation(); return (_jsx(Box, { css: ` margin-bottom: 1em; ${count === 0 ? "align-self: center;" : ""} `, children: t(`itemSearchTool.resultsCount`, { count }) })); }; const ActionButton = styled(Button).attrs((props) => ({ primary: props.selected, secondary: !props.selected, textProps: { medium: true } })) ` min-height: 20px; padding: 1em; padding-top: 2px; padding-bottom: 2px; border: 0px; border-radius: 5px; `; const ActionMenu = styled.div ` display: flex; justify-content: flex-end; padding: 0.5em; background-color: ${(p) => p.theme.charcoalGrey}; border-top-left-radius: 5px; border-top-right-radius: 5px; > ${ActionButton}:first-child { margin-right: 1em; } `; export default SearchResults; //# sourceMappingURL=SearchResults.js.map