From 20b53206584add262ee95ce86df25e26a6310f4e Mon Sep 17 00:00:00 2001 From: Manjila Singh Date: Wed, 8 Apr 2026 16:56:18 -0500 Subject: [PATCH 01/43] added a banner and moved layer menu to header --- reactapp/App.scss | 53 +++++++++++++++++++ .../DataStream/components/menus/LayersMenu.js | 19 +++++-- .../DataStream/components/menus/MainMenu.js | 2 - .../Tethys/components/layout/Header.js | 9 ++-- .../Tethys/components/layout/Layout.js | 17 ++++++ 5 files changed, 88 insertions(+), 12 deletions(-) diff --git a/reactapp/App.scss b/reactapp/App.scss index 8c4a116..e9a79ca 100644 --- a/reactapp/App.scss +++ b/reactapp/App.scss @@ -245,6 +245,59 @@ body { padding-top: var(--ts-header-height); } +.experimental-banner { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + position: sticky; + top: var(--ts-header-height); + z-index: 1100; + padding: 0.85rem 1.25rem; + margin: 0; + background: linear-gradient(90deg, rgba(255, 193, 7, 0.22), rgba(255, 138, 61, 0.18)); + border-bottom: 1px solid rgba(214, 165, 0, 0.35); + box-shadow: 0 4px 16px rgba(15, 23, 42, 0.08); + color: #5b3d00; + font-weight: 600; + letter-spacing: 0.01em; +} + +.experimental-banner__content { + min-width: 0; +} + +.experimental-banner__close { + appearance: none; + border: 0; + background: transparent; + color: inherit; + cursor: pointer; + flex: 0 0 auto; + font-size: 1.4rem; + font-weight: 700; + line-height: 1; + padding: 0 0.25rem; +} + +.experimental-banner__close:hover { + opacity: 0.75; +} + +.experimental-banner__close:focus-visible { + outline: 2px solid currentColor; + outline-offset: 2px; +} + +@media (prefers-color-scheme: dark) { + .experimental-banner { + background: linear-gradient(90deg, rgba(245, 158, 11, 0.22), rgba(251, 146, 60, 0.18)); + border-bottom-color: rgba(251, 191, 36, 0.35); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.24); + color: #fff2cc; + } +} + .form-switch .form-check-input { width: 3em; height: 1.5em; diff --git a/reactapp/features/DataStream/components/menus/LayersMenu.js b/reactapp/features/DataStream/components/menus/LayersMenu.js index 5beed11..017cfc0 100644 --- a/reactapp/features/DataStream/components/menus/LayersMenu.js +++ b/reactapp/features/DataStream/components/menus/LayersMenu.js @@ -1,11 +1,14 @@ import React, { Fragment, useCallback, useState } from 'react'; import { LayerControl } from '../map/LayersControl'; import { LayersContainer, LayerButton } from '../styles/Styles'; -import { IoLayers, IoClose } from "react-icons/io5"; +import { IoLayers } from "react-icons/io5"; -export const LayersMenu = () => { +export const LayersMenu = ({ inline = false }) => { const [open, setIsOpen] = useState(false); const toggle = useCallback(() => setIsOpen(o => !o), []); + const buttonStyle = inline + ? { position: 'static', top: 'auto', right: 'auto', marginTop: 0 } + : undefined; return ( @@ -14,8 +17,11 @@ export const LayersMenu = () => { - + @@ -23,7 +29,12 @@ export const LayersMenu = () => { ) : ( - setIsOpen(prev => !prev)}> + setIsOpen(prev => !prev)} + aria-label="Open layer options" + title="Open layer options" + style={buttonStyle} + > )} diff --git a/reactapp/features/DataStream/components/menus/MainMenu.js b/reactapp/features/DataStream/components/menus/MainMenu.js index 83bee43..ccf3231 100644 --- a/reactapp/features/DataStream/components/menus/MainMenu.js +++ b/reactapp/features/DataStream/components/menus/MainMenu.js @@ -1,13 +1,11 @@ import React, { Fragment } from 'react'; import ForecastMenu from 'features/DataStream/components/menus/ForecastMenu'; -import { LayersMenu } from './LayersMenu'; import { CacheMenu } from './CacheMenu'; const MainMenu = () => { return ( - ); diff --git a/reactapp/features/Tethys/components/layout/Header.js b/reactapp/features/Tethys/components/layout/Header.js index d10b9f4..28a568e 100644 --- a/reactapp/features/Tethys/components/layout/Header.js +++ b/reactapp/features/Tethys/components/layout/Header.js @@ -1,13 +1,12 @@ import Container from 'react-bootstrap/Container'; -import Form from 'react-bootstrap/Form'; import Navbar from 'react-bootstrap/Navbar'; import PropTypes from 'prop-types'; import { useContext, useState } from 'react'; -import { BsX, BsInfoCircle } from 'react-icons/bs'; +import { BsInfoCircle } from 'react-icons/bs'; import { LinkContainer } from 'react-router-bootstrap'; -import HeaderButton from 'features/Tethys/components/buttons/HeaderButton'; import SearchBar from 'features/DataStream/components/map/SearchBar'; +import { LayersMenu } from 'features/DataStream/components/menus/LayersMenu'; import { AppContext } from 'features/Tethys/context/context'; import { CustomNavBar, CustomDiv, StyledButton } from 'features/Tethys/components/Styles'; import { GeneralInfoModal } from 'features/DataStream/components/Modals'; @@ -38,9 +37,7 @@ const Header = ({onNavChange}) => { setModalGeneralInfoShow(true)}> -
- -
+
export default function Layout({ navLinks = [], routes = [], children }) { const { tethysApp } = useContext(AppContext); const [navVisible, setNavVisible] = useState(false); + const [bannerVisible, setBannerVisible] = useState(true); /** Close the off-canvas smoothly */ const closeNav = () => startTransition(() => setNavVisible(false)); @@ -23,6 +24,22 @@ export default function Layout({ navLinks = [], routes = [], children }) {
+ {bannerVisible && ( +
+
+ Experimental Streamflow Predictions: These results are preliminary and may not represent accurate forecasts. +
+ +
+ )} +