diff --git a/cypress/e2e/permalink.cy.js b/cypress/e2e/permalink.cy.js
index 7e4983c61..1bf67432c 100644
--- a/cypress/e2e/permalink.cy.js
+++ b/cypress/e2e/permalink.cy.js
@@ -64,7 +64,9 @@ describe("permalink", () => {
),
);
cy.url().should("match", /lang=de/);
- cy.url().should("match", /layers=&/);
+ cy.url().should("match", /[?&]layers=(&|$)/);
+ // cy.url().then((url) => console.log(url));
+
// eslint-disable-next-line prefer-regex-literals
cy.url().should("match", new RegExp("x=928460&y=5908948&z=8.5"));
});
diff --git a/src/WebComponent.scss b/src/WebComponent.scss
index 88d1fb553..7ed7d8987 100644
--- a/src/WebComponent.scss
+++ b/src/WebComponent.scss
@@ -35,6 +35,7 @@
@import "./components/Menu/MenuItemHeader.scss";
@import "./components/Search/Search.scss";
@import "./components/Search/SearchToggle.scss";
+@import "./components/Search/SearchInput.scss";
@import "./components/Share/Share.scss";
@import "./components/TopicMenu/TopicMenu.scss";
@import "./components/TopicsMenu/TopicsMenu.scss";
diff --git a/src/components/MapControls/MapControls.js b/src/components/MapControls/MapControls.js
index e4fa6250c..ccda51502 100644
--- a/src/components/MapControls/MapControls.js
+++ b/src/components/MapControls/MapControls.js
@@ -90,6 +90,7 @@ function MapControls({
const dispatch = useDispatch();
const overlayWidth = useOverlayWidth();
const screenHeight = useSelector((state) => state.app.screenHeight);
+ const activeTopic = useSelector((state) => state.app.activeTopic);
const isSmallHeight = useMemo(() => {
return ["xs", "s"].includes(screenHeight);
}, [screenHeight]);
@@ -153,7 +154,7 @@ function MapControls({
className={`wkp-map-controls ${classes.mapControls}`}
data-testid="map-controls-wrapper"
>
- {menuToggler && }
+ {menuToggler && (activeTopic?.menuToggler ?? )}
}
diff --git a/src/components/MapControls/MenuToggler/MenuToggler.js b/src/components/MapControls/MenuToggler/MenuToggler.js
index a7ebfef74..c74d65784 100644
--- a/src/components/MapControls/MenuToggler/MenuToggler.js
+++ b/src/components/MapControls/MenuToggler/MenuToggler.js
@@ -2,6 +2,7 @@ import React from "react";
import { useDispatch, useSelector } from "react-redux";
import { makeStyles } from "@mui/styles";
import { useTranslation } from "react-i18next";
+import PropTypes from "prop-types";
import MapButton from "../../MapButton";
import { ReactComponent as MenuOpen } from "../../../img/sbb/040_hamburgermenu_102_36.svg";
import { ReactComponent as MenuClosed } from "../../../img/sbb/040_schliessen_104_36.svg";
@@ -11,21 +12,27 @@ const useStyles = makeStyles({
displayMenuToggler: { padding: "8px" },
});
-function MenuToggler() {
+function MenuToggler({ children, ...props }) {
const classes = useStyles();
const { t } = useTranslation();
const displayMenu = useSelector((state) => state.app.displayMenu);
const dispatch = useDispatch();
+
return (
dispatch(setDisplayMenu(!displayMenu))}
- title={t("Menü")}
+ title={displayMenu ? t("Schliessen") : t("Menü")}
data-testid="map-controls-menu-toggler"
+ {...props}
>
- {displayMenu ? : }
+ {children ?? (displayMenu ? : )}
);
}
+MenuToggler.propTypes = {
+ children: PropTypes.node,
+};
+
export default MenuToggler;
diff --git a/src/components/Search/Search.js b/src/components/Search/Search.js
index 6bba624fd..10a393a79 100644
--- a/src/components/Search/Search.js
+++ b/src/components/Search/Search.js
@@ -1,249 +1,16 @@
-/* eslint-disable react/jsx-props-no-spreading */
-import React, { useEffect, useState, useRef } from "react";
-import { useSelector, useDispatch } from "react-redux";
-import Autosuggest from "react-autosuggest";
-import { FaSearch, FaAngleDown, FaAngleUp } from "react-icons/fa";
-import { useTranslation } from "react-i18next";
-import { IconButton, Typography } from "@mui/material";
-import { setFeatureInfo, setSearchOpen } from "../../model/app/actions";
-import useHasScreenSize from "../../utils/useHasScreenSize";
+import React, { useRef } from "react";
+import SearchInput from "./SearchInput";
import SearchToggle from "./SearchToggle";
import "./Search.scss";
-import CloseButton from "../CloseButton";
-import { trackEvent } from "../../utils/trackingUtils";
-
-const mobileMapPadding = [50, 50, 50, 50];
function Search() {
- const [suggestions, setSuggestions] = useState([]);
- const [value, setValue] = useState("");
- const map = useSelector((state) => state.app.map);
- const featureInfo = useSelector((state) => state.app.featureInfo);
- const searchService = useSelector((state) => state.app.searchService);
- const activeTopic = useSelector((state) => state.app.activeTopic);
- const isMobile = useHasScreenSize();
const searchContainerRef = useRef();
- const { t } = useTranslation();
- const dispatch = useDispatch();
-
- useEffect(() => {
- if (!searchService) {
- return;
- }
- searchService.setUpsert((section, items, position) => {
- setSuggestions((oldSuggestions) => {
- const index = oldSuggestions.findIndex((s) => s.section === section);
- const start = index === -1 ? position : index;
- const deleteCount = index === -1 ? 0 : 1;
- const newSuggestions = [...oldSuggestions];
- newSuggestions.splice(start, deleteCount, { section, items });
- return newSuggestions;
- });
- });
- }, [searchService, setSuggestions]);
-
- useEffect(
- () => searchService && map && searchService.setMap(map),
- [searchService, map],
- );
-
- if (!searchService || !Object.keys(searchService.searches || []).length) {
- return null;
- }
return (
-
+
- val.trim().length > 2}
- suggestions={suggestions}
- onSuggestionsFetchRequested={(evt) => {
- searchService.search(evt.value);
- }}
- onSuggestionsClearRequested={() => {
- setSuggestions([]);
- }}
- onSuggestionHighlighted={({ suggestion }) =>
- searchService.highlight(suggestion)
- }
- onSuggestionSelected={(e, thing) => {
- const { suggestion } = thing;
- trackEvent(
- {
- eventType: "action",
- componentName: "search result",
- label: searchService.value(suggestion),
- variant: suggestion.section,
- location: t(activeTopic?.name, { lng: "de" }),
- eventName: e.type,
- },
- activeTopic,
- );
- dispatch(setFeatureInfo());
- searchService.select(
- suggestion,
- isMobile ? mobileMapPadding : undefined,
- );
- dispatch(setSearchOpen(false));
- }}
- getSuggestionValue={(suggestion) => searchService.value(suggestion)}
- renderSuggestion={(suggestion) => searchService.render(suggestion)}
- renderSectionTitle={({ section }) => {
- const count = searchService.countItems(section);
- return (
- count > 0 && (
- searchService.toggleSection(section)}
- onKeyPress={() => searchService.toggleSection(section)}
- role="button"
- tabIndex={0}
- >
-
-
- {t(section)}:{" "}
-
-
- {t("overallResult", { count })}
-
-
- {searchService.sectionCollapsed(section) ? (
-
- ) : (
-
- )}
-
- )
- );
- }}
- getSectionSuggestions={(result) => {
- return (
- result?.items?.map((i) => ({ ...i, section: result.section })) ||
- []
- );
- }}
- inputProps={{
- autoFocus: true,
- tabIndex: 0,
- "aria-label": t("Suchmaske"),
- onChange: (e, { newValue }) => setValue(newValue),
- onKeyUp: (e) => {
- const { key } = e;
- if (key === "Enter") {
- trackEvent(
- {
- eventType: "action",
- componentName: "search input",
- label: t("Suche starten"),
- location: t(activeTopic?.name, { lng: "de" }),
- variant: "Suche starten",
- },
- activeTopic,
- );
- const filtered = suggestions.filter((s) => s.items.length > 0);
- if (filtered.length > 0) {
- const { items, section } = filtered[0];
- dispatch(setSearchOpen(false));
- searchService.select(
- { ...items[0], section },
- isMobile ? mobileMapPadding : undefined,
- );
- }
- } else if (key === "ArrowDown" || key === "ArrowUp") {
- searchService.highlightSection(); // for improved accessibility
- }
- },
- placeholder: searchService.getPlaceholder(t),
- value,
- }}
- renderInputComponent={(inputProps) => {
- return (
-
-
- {value && (
- {
- setValue("");
- searchService.clearHighlight();
- searchService.clearSelect();
- const searchFeatureInfos = searchService.clearPopup();
-
- // We remove the stations feature infos from the current list of feature infos.
- if (featureInfo?.length && searchFeatureInfos?.length) {
- (searchFeatureInfos || []).forEach(
- (searchFeatureInfo) => {
- const index = featureInfo?.findIndex((info) => {
- return info === searchFeatureInfo;
- });
- if (index > -1) {
- featureInfo.splice(index, 1);
- }
- },
- );
- dispatch(setFeatureInfo([...featureInfo]));
- }
- }}
- />
- )}
- {
- trackEvent(
- {
- eventType: "action",
- componentName: "search button",
- label: t("Suche starten"),
- location: t(activeTopic?.name, { lng: "de" }),
- variant: "Suche starten",
- },
- activeTopic,
- );
-
- if (!value) {
- // Hide the search input on small screen
- dispatch(setSearchOpen(false));
- }
-
- if (searchService.selectItem) {
- // Will zoom on the current selected feature
- searchService.select(
- searchService.selectItem,
- isMobile ? mobileMapPadding : undefined,
- );
- }
-
- // Launch a search
- if (value) {
- searchService.search(value).then((searchResults) => {
- const result = searchResults.find(
- (results) => results.items.length > 0,
- );
- if (result) {
- const { items, section } = result;
- dispatch(setSearchOpen(false));
- searchService.select(
- { ...items[0], section },
- isMobile ? mobileMapPadding : undefined,
- );
- }
- });
- }
- }}
- >
-
-
-
- );
- }}
- />
+
);
diff --git a/src/components/Search/Search.scss b/src/components/Search/Search.scss
index b75c53e0c..3d710fe20 100644
--- a/src/components/Search/Search.scss
+++ b/src/components/Search/Search.scss
@@ -1,5 +1,5 @@
/* stylelint-disable selector-class-pattern */
-@import '../../globals.scss';
+@import "../../globals.scss";
.wkp-search {
position: absolute;
@@ -7,135 +7,4 @@
z-index: 2; /* To be above header div, in order to be clickable. */
right: 480px;
left: 400px;
-
- .wkp-search-input {
- display: flex;
- justify-content: center;
- align-items: center;
- background-color: white;
- border: 2px solid #b7b7b7;
- height: 42px;
- }
-
- .wkp-search-button {
- display: flex;
- align-items: center;
- justify-content: center;
- border: none;
- color: white;
- height: 42px;
- width: 46px;
- position: absolute;
- top: 4px;
- right: 52px;
- font-size: 16px;
-
- &.wkp-search-button-clear {
- background: none;
- color: #666;
- right: 98px;
- }
-
- &.wkp-search-button-submit {
- background-color: $brand-primary;
- }
- }
-
- .react-autosuggest__input {
- border: 0;
- font-size: 14px;
- padding-left: 15px;
- border-radius: 0;
- appearance: none;
- flex: 2 1 auto;
- height: 90%;
-
- &::-ms-clear {
- display: none;
- }
- }
-
- .react-autosuggest__suggestions-container--open {
- box-sizing: border-box;
- background: white;
- border: 2px solid #666;
- margin-top: 5px;
- width: 100%;
- max-height: calc(100vh - 150px);
- overflow: auto;
- }
-
- .react-autosuggest__section-title {
- span {
- color: #666;
- }
-
- .wkp-search-section-header {
- & > span:first-child {
- color: black;
- }
- }
-
- .wkp-search-section-opener {
- display: flex;
- align-items: center;
- justify-content: space-between;
- background-color: #f5f5f5;
- padding: 10px 15px;
- }
-
- :hover {
- svg,
- .MuiTypography-subtitle1 {
- color: $brand-primary-hover;
- }
- }
- }
-
- .react-autosuggest__suggestions-list {
- list-style: none;
- padding: 0;
- margin: 0;
-
- li:first-child {
- padding-top: 5px;
- }
-
- li:last-child {
- padding-bottom: 5px;
- }
- }
-
- .react-autosuggest__suggestion {
- padding: 0 15px;
- cursor: pointer;
-
- .wkp-search-suggestion,
- .wkp-search-suggestion-subtitled {
- display: flex;
- flex-direction: column;
- justify-content: center;
- }
-
- .wkp-search-suggestion {
- min-height: 25px;
- padding: 3px 0;
- }
-
- .wkp-search-suggestion-subtitled {
- min-height: 50px;
- }
-
- &.react-autosuggest__suggestion--highlighted {
- p {
- color: $brand-primary-hover !important;
- }
- }
-
- &:hover {
- p {
- color: $brand-primary-hover !important;
- }
- }
- }
}
diff --git a/src/components/Search/SearchInfo.js b/src/components/Search/SearchInfo.js
index e06b623ed..6ef278c6e 100644
--- a/src/components/Search/SearchInfo.js
+++ b/src/components/Search/SearchInfo.js
@@ -1,5 +1,5 @@
/* eslint-disable react/jsx-props-no-spreading */
-import React, { useEffect, useCallback } from "react";
+import React, { useEffect, useCallback, useRef } from "react";
import PropTypes from "prop-types";
import { useSelector, useDispatch } from "react-redux";
import { useTranslation } from "react-i18next";
@@ -55,6 +55,7 @@ const useStyles = makeStyles((theme) => {
searchInfoBox: {
zIndex: 1500,
left: "10px !important",
+ top: "-44px !important",
width: "32vw",
maxWidth: (props) => (props.screenWidth !== "xl" ? 258 : 420),
},
@@ -86,7 +87,7 @@ const propTypes = {
anchorEl: PropTypes.instanceOf(Element),
};
-function SearchInfo({ anchorEl }) {
+function SearchInfo() {
const dispatch = useDispatch();
const { t } = useTranslation();
const screenWidth = useSelector((state) => state.app.screenWidth);
@@ -94,6 +95,7 @@ function SearchInfo({ anchorEl }) {
const searchOpen = useSelector((state) => state.app.searchOpen);
const searchInfoOpen = useSelector((state) => state.app.searchInfoOpen);
const activeTopic = useSelector((state) => state.app.activeTopic);
+ const anchorEl = useRef(null);
const togglePopup = useCallback(() => {
if (!searchInfoOpen) {
@@ -129,15 +131,16 @@ function SearchInfo({ anchorEl }) {
className={classes.searchInfoBtn}
onClick={togglePopup}
title={t("Suche-Info")}
+ ref={anchorEl}
>
{anchorEl && (
{({ TransitionProps }) => (
diff --git a/src/components/Search/SearchInput.js b/src/components/Search/SearchInput.js
new file mode 100644
index 000000000..928247009
--- /dev/null
+++ b/src/components/Search/SearchInput.js
@@ -0,0 +1,249 @@
+/* eslint-disable react/jsx-props-no-spreading */
+import React, { useEffect, useState, useRef } from "react";
+import { useSelector, useDispatch } from "react-redux";
+import Autosuggest from "react-autosuggest";
+import { FaSearch, FaAngleDown, FaAngleUp } from "react-icons/fa";
+import { useTranslation } from "react-i18next";
+import { IconButton, Typography } from "@mui/material";
+import { setFeatureInfo, setSearchOpen } from "../../model/app/actions";
+import useHasScreenSize from "../../utils/useHasScreenSize";
+
+import "./SearchInput.scss";
+import CloseButton from "../CloseButton";
+import { trackEvent } from "../../utils/trackingUtils";
+
+const mobileMapPadding = [50, 50, 50, 50];
+
+function SearchInput() {
+ const [value, setValue] = useState("");
+ const [suggestions, setSuggestions] = useState([]);
+ const map = useSelector((state) => state.app.map);
+ const featureInfo = useSelector((state) => state.app.featureInfo);
+ const searchService = useSelector((state) => state.app.searchService);
+ const activeTopic = useSelector((state) => state.app.activeTopic);
+ const isMobile = useHasScreenSize();
+ const searchContainerRef = useRef();
+ const { t } = useTranslation();
+ const dispatch = useDispatch();
+
+ useEffect(() => {
+ if (!searchService) {
+ return;
+ }
+ searchService.setUpsert((section, items, position) => {
+ setSuggestions((oldSuggestions) => {
+ const index = oldSuggestions.findIndex((s) => s.section === section);
+ const start = index === -1 ? position : index;
+ const deleteCount = index === -1 ? 0 : 1;
+ const newSuggestions = [...oldSuggestions];
+ newSuggestions.splice(start, deleteCount, { section, items });
+ return newSuggestions;
+ });
+ });
+ }, [searchService, setSuggestions]);
+
+ useEffect(
+ () => searchService && map && searchService.setMap(map),
+ [searchService, map],
+ );
+
+ if (!searchService || !Object.keys(searchService.searches || []).length) {
+ return null;
+ }
+
+ return (
+ val.trim().length > 2}
+ suggestions={suggestions}
+ onSuggestionsFetchRequested={(evt) => {
+ searchService.search(evt.value);
+ }}
+ onSuggestionsClearRequested={() => {
+ setSuggestions([]);
+ }}
+ onSuggestionHighlighted={({ suggestion }) =>
+ searchService.highlight(suggestion)
+ }
+ onSuggestionSelected={(e, thing) => {
+ const { suggestion } = thing;
+ trackEvent(
+ {
+ eventType: "action",
+ componentName: "search result",
+ label: searchService.value(suggestion),
+ variant: suggestion.section,
+ location: t(activeTopic?.name, { lng: "de" }),
+ eventName: e.type,
+ },
+ activeTopic,
+ );
+ dispatch(setFeatureInfo());
+ searchService.select(
+ suggestion,
+ isMobile ? mobileMapPadding : undefined,
+ );
+ dispatch(setSearchOpen(false));
+ }}
+ getSuggestionValue={(suggestion) => searchService.value(suggestion)}
+ renderSuggestion={(suggestion) => searchService.render(suggestion)}
+ renderSectionTitle={({ section }) => {
+ const count = searchService.countItems(section);
+ return (
+ count > 0 && (
+ searchService.toggleSection(section)}
+ onKeyPress={() => searchService.toggleSection(section)}
+ role="button"
+ tabIndex={0}
+ >
+
+
+ {t(section)}:{" "}
+
+
+ {t("overallResult", { count })}
+
+
+ {searchService.sectionCollapsed(section) ? (
+
+ ) : (
+
+ )}
+
+ )
+ );
+ }}
+ getSectionSuggestions={(result) => {
+ return (
+ result?.items?.map((i) => ({ ...i, section: result.section })) || []
+ );
+ }}
+ containerProps={{ className: "wkp-autosuggest" }}
+ inputProps={{
+ autoFocus: true,
+ tabIndex: 0,
+ "aria-label": t("Suchmaske"),
+ onChange: (e, { newValue }) => setValue(newValue),
+ onKeyUp: (e) => {
+ const { key } = e;
+ if (key === "Enter") {
+ trackEvent(
+ {
+ eventType: "action",
+ componentName: "search input",
+ label: t("Suche starten"),
+ location: t(activeTopic?.name, { lng: "de" }),
+ variant: "Suche starten",
+ },
+ activeTopic,
+ );
+ const filtered = suggestions.filter((s) => s.items.length > 0);
+ if (filtered.length > 0) {
+ const { items, section } = filtered[0];
+ dispatch(setSearchOpen(false));
+ searchService.select(
+ { ...items[0], section },
+ isMobile ? mobileMapPadding : undefined,
+ );
+ }
+ } else if (key === "ArrowDown" || key === "ArrowUp") {
+ searchService.highlightSection(); // for improved accessibility
+ }
+ },
+ placeholder: searchService.getPlaceholder(t),
+ value,
+ }}
+ renderInputComponent={({ key, ...inputProps }) => {
+ return (
+
+
+ {value && (
+ {
+ setValue("");
+ searchService.clearHighlight();
+ searchService.clearSelect();
+ const searchFeatureInfos = searchService.clearPopup();
+
+ // We remove the stations feature infos from the current list of feature infos.
+ if (featureInfo?.length && searchFeatureInfos?.length) {
+ (searchFeatureInfos || []).forEach((searchFeatureInfo) => {
+ const index = featureInfo?.findIndex((info) => {
+ return info === searchFeatureInfo;
+ });
+ if (index > -1) {
+ featureInfo.splice(index, 1);
+ }
+ });
+ dispatch(setFeatureInfo([...featureInfo]));
+ }
+ }}
+ />
+ )}
+ {
+ trackEvent(
+ {
+ eventType: "action",
+ componentName: "search button",
+ label: t("Suche starten"),
+ location: t(activeTopic?.name, { lng: "de" }),
+ variant: "Suche starten",
+ },
+ activeTopic,
+ );
+
+ if (!value) {
+ // Hide the search input on small screen
+ dispatch(setSearchOpen(false));
+ }
+
+ if (searchService.selectItem) {
+ // Will zoom on the current selected feature
+ searchService.select(
+ searchService.selectItem,
+ isMobile ? mobileMapPadding : undefined,
+ );
+ }
+
+ // Launch a search
+ if (value) {
+ searchService.search(value).then((searchResults) => {
+ const result = searchResults.find(
+ (results) => results.items.length > 0,
+ );
+ if (result) {
+ const { items, section } = result;
+ dispatch(setSearchOpen(false));
+ searchService.select(
+ { ...items[0], section },
+ isMobile ? mobileMapPadding : undefined,
+ );
+ }
+ });
+ }
+ }}
+ >
+
+
+
+ );
+ }}
+ />
+ );
+}
+
+export default SearchInput;
diff --git a/src/components/Search/SearchInput.scss b/src/components/Search/SearchInput.scss
new file mode 100644
index 000000000..5df171f29
--- /dev/null
+++ b/src/components/Search/SearchInput.scss
@@ -0,0 +1,135 @@
+/* stylelint-disable selector-class-pattern */
+@import "../../globals.scss";
+
+.wkp-autosuggest {
+ .wkp-search-input {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: white;
+ border: 2px solid #b7b7b7;
+ height: 42px;
+ }
+
+ .wkp-search-button {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: none;
+ color: white;
+ height: 42px;
+ width: 46px;
+ position: absolute;
+ top: 4px;
+ right: 52px;
+ font-size: 16px;
+
+ &.wkp-search-button-clear {
+ background: none;
+ color: #666;
+ right: 98px;
+ }
+
+ &.wkp-search-button-submit {
+ background-color: $brand-primary;
+ }
+ }
+
+ .react-autosuggest__input {
+ border: 0;
+ font-size: 14px;
+ padding-left: 15px;
+ border-radius: 0;
+ appearance: none;
+ flex: 2 1 auto;
+ height: 90%;
+
+ &::-ms-clear {
+ display: none;
+ }
+ }
+
+ .react-autosuggest__suggestions-container--open {
+ box-sizing: border-box;
+ background: white;
+ border: 2px solid #666;
+ margin-top: 5px;
+ width: 100%;
+ max-height: calc(100vh - 150px);
+ overflow: auto;
+ }
+
+ .react-autosuggest__section-title {
+ span {
+ color: #666;
+ }
+
+ .wkp-search-section-header {
+ & > span:first-child {
+ color: black;
+ }
+ }
+
+ .wkp-search-section-opener {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ background-color: #f5f5f5;
+ padding: 10px 15px;
+ }
+
+ :hover {
+ svg,
+ .MuiTypography-subtitle1 {
+ color: $brand-primary-hover;
+ }
+ }
+ }
+
+ .react-autosuggest__suggestions-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+
+ li:first-child {
+ padding-top: 5px;
+ }
+
+ li:last-child {
+ padding-bottom: 5px;
+ }
+ }
+
+ .react-autosuggest__suggestion {
+ padding: 0 15px;
+ cursor: pointer;
+
+ .wkp-search-suggestion,
+ .wkp-search-suggestion-subtitled {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ }
+
+ .wkp-search-suggestion {
+ min-height: 25px;
+ padding: 3px 0;
+ }
+
+ .wkp-search-suggestion-subtitled {
+ min-height: 50px;
+ }
+
+ &.react-autosuggest__suggestion--highlighted {
+ p {
+ color: $brand-primary-hover !important;
+ }
+ }
+
+ &:hover {
+ p {
+ color: $brand-primary-hover !important;
+ }
+ }
+ }
+}
diff --git a/src/components/Search/SearchToggle.js b/src/components/Search/SearchToggle.js
index 9b213c0f2..95105ab84 100644
--- a/src/components/Search/SearchToggle.js
+++ b/src/components/Search/SearchToggle.js
@@ -6,12 +6,7 @@ import { setSearchOpen } from "../../model/app/actions";
import { ReactComponent as SearchIcon } from "./Search.svg";
import SearchInfo from "./SearchInfo";
-const propTypes = {
- children: PropTypes.node,
- popupAnchor: PropTypes.instanceOf(Element),
-};
-
-function SearchToggle({ popupAnchor, children }) {
+function SearchToggle({ children }) {
const searchOpen = useSelector((state) => state.app.searchOpen);
const { t } = useTranslation();
const dispatch = useDispatch();
@@ -21,7 +16,7 @@ function SearchToggle({ popupAnchor, children }) {
className={`wkp-search-toggle-container${searchOpen ? "--open" : ""}`}
>
{children}
-
+
{!searchOpen && (
+ setAnchorEl(null)}
+ transitionDuration="auto"
+ MenuListProps={{
+ autoFocusItem: false,
+ }}
+ data-testid="sts-menu-popover"
>
- {t("Direct trains to Switzerland")}
-
-
-
- {activeMenu === "sts" && }
- {activeMenu === "dv" && }
-
- >
- }
- title={activeMenu === "dv" && }
- body={
- <>
- {!isMobile && }
- {activeMenu === "sts" && (
-
- )}
- {activeMenu === "dv" && }
- >
- }
- />
+ onChange("sts")}
+ data-testid="sts-menu-sts"
+ >
+ {t("Validity of Swiss Travel Pass")}
+
+ onChange("dv")}
+ data-testid="sts-menu-dv"
+ >
+ {t("Direct trains to Switzerland")}
+
+
+
+ {activeMenu === "sts" && }
+ {activeMenu === "dv" && }
+
+ >
+ }
+ title={activeMenu === "dv" && }
+ body={
+ <>
+ {!isMobile && }
+ {activeMenu === "sts" && (
+
+ )}
+ {activeMenu === "dv" && }
+ >
+ }
+ />
+ >
);
}
-StsTopicMenu.propTypes = {};
+StsMenu.propTypes = {};
-export default StsTopicMenu;
+export default StsMenu;
diff --git a/src/menus/StsMenu/StsMenu.test.js b/src/menus/StsMenu/StsMenu.test.js
index d58d695f1..a67b274cb 100644
--- a/src/menus/StsMenu/StsMenu.test.js
+++ b/src/menus/StsMenu/StsMenu.test.js
@@ -11,6 +11,10 @@ import { sts } from "../../config/topics";
import stsLayers from "../../config/ch.sbb.sts";
import highlightPointStyle from "../../utils/highlightPointStyle";
import theme from "../../themes/default";
+import SearchService from "../../components/Search/SearchService";
+
+const searchService = new SearchService();
+searchService.setSearches(sts.searches);
describe("StsMenu", () => {
let store;
@@ -29,11 +33,12 @@ describe("StsMenu", () => {
activeTopic: sts,
featureInfo: [],
displayMenu: true,
+ searchService,
},
});
});
- test("should render the menu opener and sts validity layerswitcher on load", () => {
+ test("should render the search, menu opener and sts validity layerswitcher on load", () => {
const { getByTestId } = render(
@@ -42,6 +47,8 @@ describe("StsMenu", () => {
,
);
+ const search = getByTestId("wkp-search-input");
+ expect(search).toBeTruthy();
const opener = getByTestId("sts-menu-opener");
expect(opener).toBeTruthy();
const { getByText } = within(opener);