Skip to content

Commit

Permalink
added board select to nav, permalink according to #72
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Thieme-Garmann committed Jan 21, 2025
1 parent ebc3ac8 commit d3c17a5
Show file tree
Hide file tree
Showing 18 changed files with 504 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/components/BoardDropdown/BoardDropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const BoardDropdown = () => {
const handleBoardChange = (selectedBoard) => {
// Verwende die setBoard-Funktion direkt, um das Board im Store zu aktualisieren
useBoardStore.setState({ board: selectedBoard });
console.log(selectedBoard, useBoardStore((state) => state.board))
// Hier kannst du weitere Aktionen ausführen, wenn sich das Board ändert
};

Expand Down
53 changes: 53 additions & 0 deletions src/theme/BoardDropdown/BoardDropdown.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// BoardDropdown.jsx

import React, { useState } from "react";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@site/src/components/ui/select";
import { useBoardStore } from "@site/src/lib/stores/store";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMicrochip } from "@fortawesome/free-solid-svg-icons";
const BoardDropdown = () => {
const board = useBoardStore((state) => state.board);
const handleBoardChange = (selectedBoard) => {
// Verwende die setBoard-Funktion direkt, um das Board im Store zu aktualisieren
useBoardStore.setState({ board: selectedBoard });
// Hier kannst du weitere Aktionen ausführen, wenn sich das Board ändert
};

return (
<Select onValueChange={(value) => handleBoardChange(value)} default>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder={board ? board : "Board auswählen"} />
</SelectTrigger>
<SelectContent>
<SelectItem value=":edu">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:edu
</SelectItem>
<SelectItem value=":edu S2">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:edu S2
</SelectItem>
<SelectItem value=":home">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:home
</SelectItem>
<SelectItem value=":bike">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:bike
</SelectItem>
<SelectItem value=":CO2Traffic">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
CO2 Traffic Light
</SelectItem>
</SelectContent>
</Select>
);
};

export default BoardDropdown;
22 changes: 22 additions & 0 deletions src/theme/Navbar/ColorModeToggle/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import {useColorMode, useThemeConfig} from '@docusaurus/theme-common';
import ColorModeToggle from '@theme/ColorModeToggle';
import styles from './styles.module.css';
export default function NavbarColorModeToggle({className}) {
const navbarStyle = useThemeConfig().navbar.style;
const disabled = useThemeConfig().colorMode.disableSwitch;
const {colorMode, setColorMode} = useColorMode();
if (disabled) {
return null;
}
return (
<ColorModeToggle
className={className}
buttonClassName={
navbarStyle === 'dark' ? styles.darkNavbarColorModeToggle : undefined
}
value={colorMode}
onChange={setColorMode}
/>
);
}
3 changes: 3 additions & 0 deletions src/theme/Navbar/ColorModeToggle/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.darkNavbarColorModeToggle:hover {
background: var(--ifm-color-gray-800);
}
144 changes: 144 additions & 0 deletions src/theme/Navbar/Content/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import React, { useEffect, useState } from 'react';
import { useThemeConfig, ErrorCauseBoundary } from '@docusaurus/theme-common';
import {
splitNavbarItems,
useNavbarMobileSidebar,
} from '@docusaurus/theme-common/internal';
import NavbarItem from '@theme/NavbarItem';
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
import SearchBar from '@theme/SearchBar';
import NavbarMobileSidebarToggle from '@theme/Navbar/MobileSidebar/Toggle';
import NavbarLogo from '@theme/Navbar/Logo';
import NavbarSearch from '@theme/Navbar/Search';
import styles from './styles.module.css';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@site/src/components/ui/select";
import { useBoardStore } from "@site/src/lib/stores/store";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMicrochip } from "@fortawesome/free-solid-svg-icons";
import { useNavigate, useLocation } from 'react-router-dom'; // Verwende useLocation

function useNavbarItems() {
return useThemeConfig().navbar.items;
}

function NavbarItems({ items }) {
return (
<>
{items.map((item, i) => (
<ErrorCauseBoundary
key={i}
onError={(error) =>
new Error(
`A theme navbar item failed to render.
Please double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:
${JSON.stringify(item, null, 2)}`,
{ cause: error },
)
}
>
<NavbarItem {...item} />
</ErrorCauseBoundary>
))}
</>
);
}

function NavbarContentLayout({ left, right }) {
return (
<div className="navbar__inner">
<div className="navbar__items">{left}</div>
<div className="navbar__items navbar__items--right">{right}</div>
</div>
);
}

const BoardDropdown = () => {
const board = useBoardStore((state) => state.board);
const location = useLocation();

const handleBoardChange = (selectedBoard) => {
// Verwende die setBoard-Funktion direkt, um das Board im Store zu aktualisieren
console.log(selectedBoard)
useBoardStore.setState({ board: selectedBoard });
// Hier kannst du weitere Aktionen ausführen, wenn sich das Board ändert
};

useEffect(() => {
const searchParams = new URLSearchParams(location.search);
const currentBoard = searchParams.get('board');
const validBoards = ['home', 'edu', 'edu S2', 'bike', 'CO2 Ampel'];
if (currentBoard && validBoards.includes(currentBoard)) {
// Wenn der aktuelle `board`-Parameter gültig ist, setze ihn als ausgewählten Wert
useBoardStore.setState({ board: ":"+currentBoard });
} else {
console.log('Ungültiger Board-Parameter:', currentBoard);
}
}, [location.search]); // Überwache Änderungen an den Query-Parametern

return (
<Select onValueChange={(value) => handleBoardChange(value)} default>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder={board ? board : "Board auswählen"} />
</SelectTrigger>
<SelectContent>
<SelectItem value=":edu">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:edu
</SelectItem>
<SelectItem value=":edu S2">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:edu S2
</SelectItem>
<SelectItem value=":home">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:home
</SelectItem>
<SelectItem value=":bike">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
:bike
</SelectItem>
<SelectItem value=":CO2 Ampel">
<FontAwesomeIcon icon={faMicrochip} className="mr-2" />
CO2 Traffic Light
</SelectItem>
</SelectContent>
</Select>
);
};

export default function NavbarContent() {
const mobileSidebar = useNavbarMobileSidebar();
const items = useNavbarItems();
const [leftItems, rightItems] = splitNavbarItems(items);
const searchBarItem = items.find((item) => item.type === 'search');

return (
<NavbarContentLayout
left={
<>
{!mobileSidebar.disabled && <NavbarMobileSidebarToggle />}
<NavbarLogo />
<NavbarItems items={leftItems} />
</>
}
right={
<>
<BoardDropdown />
<NavbarItems items={rightItems} />
<NavbarColorModeToggle className={styles.colorModeToggle} />
{!searchBarItem && (
<NavbarSearch>
<SearchBar />
</NavbarSearch>
)}
</>
}
/>
);
}
8 changes: 8 additions & 0 deletions src/theme/Navbar/Content/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Hide color mode toggle in small viewports
*/
@media (max-width: 996px) {
.colorModeToggle {
display: none;
}
}
52 changes: 52 additions & 0 deletions src/theme/Navbar/Layout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import clsx from 'clsx';
import {useThemeConfig} from '@docusaurus/theme-common';
import {
useHideableNavbar,
useNavbarMobileSidebar,
} from '@docusaurus/theme-common/internal';
import {translate} from '@docusaurus/Translate';
import NavbarMobileSidebar from '@theme/Navbar/MobileSidebar';
import styles from './styles.module.css';
function NavbarBackdrop(props) {
return (
<div
role="presentation"
{...props}
className={clsx('navbar-sidebar__backdrop', props.className)}
/>
);
}
export default function NavbarLayout({children}) {
const {
navbar: {hideOnScroll, style},
} = useThemeConfig();
const mobileSidebar = useNavbarMobileSidebar();
const {navbarRef, isNavbarVisible} = useHideableNavbar(hideOnScroll);
return (
<nav
ref={navbarRef}
aria-label={translate({
id: 'theme.NavBar.navAriaLabel',
message: 'Main',
description: 'The ARIA label for the main navigation',
})}
className={clsx(
'navbar',
'navbar--fixed-top',
hideOnScroll && [
styles.navbarHideable,
!isNavbarVisible && styles.navbarHidden,
],
{
'navbar--dark': style === 'dark',
'navbar--primary': style === 'primary',
'navbar-sidebar--show': mobileSidebar.shown,
},
)}>
{children}
<NavbarBackdrop onClick={mobileSidebar.toggle} />
<NavbarMobileSidebar />
</nav>
);
}
7 changes: 7 additions & 0 deletions src/theme/Navbar/Layout/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.navbarHideable {
transition: transform var(--ifm-transition-fast) ease;
}

.navbarHidden {
transform: translate3d(0, calc(-100% - 2px), 0);
}
11 changes: 11 additions & 0 deletions src/theme/Navbar/Logo/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import Logo from '@theme/Logo';
export default function NavbarLogo() {
return (
<Logo
className="navbar__brand"
imageClassName="navbar__logo"
titleClassName="navbar__title text--truncate"
/>
);
}
31 changes: 31 additions & 0 deletions src/theme/Navbar/MobileSidebar/Header/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal';
import {translate} from '@docusaurus/Translate';
import NavbarColorModeToggle from '@theme/Navbar/ColorModeToggle';
import IconClose from '@theme/Icon/Close';
import NavbarLogo from '@theme/Navbar/Logo';
function CloseButton() {
const mobileSidebar = useNavbarMobileSidebar();
return (
<button
type="button"
aria-label={translate({
id: 'theme.docs.sidebar.closeSidebarButtonAriaLabel',
message: 'Close navigation bar',
description: 'The ARIA label for close button of mobile sidebar',
})}
className="clean-btn navbar-sidebar__close"
onClick={() => mobileSidebar.toggle()}>
<IconClose color="var(--ifm-color-emphasis-600)" />
</button>
);
}
export default function NavbarMobileSidebarHeader() {
return (
<div className="navbar-sidebar__brand">
<NavbarLogo />
<NavbarColorModeToggle className="margin-right--md" />
<CloseButton />
</div>
);
}
22 changes: 22 additions & 0 deletions src/theme/Navbar/MobileSidebar/Layout/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import clsx from 'clsx';
import {useNavbarSecondaryMenu} from '@docusaurus/theme-common/internal';
export default function NavbarMobileSidebarLayout({
header,
primaryMenu,
secondaryMenu,
}) {
const {shown: secondaryMenuShown} = useNavbarSecondaryMenu();
return (
<div className="navbar-sidebar">
{header}
<div
className={clsx('navbar-sidebar__items', {
'navbar-sidebar__items--show-secondary': secondaryMenuShown,
})}>
<div className="navbar-sidebar__item menu">{primaryMenu}</div>
<div className="navbar-sidebar__item menu">{secondaryMenu}</div>
</div>
</div>
);
}
27 changes: 27 additions & 0 deletions src/theme/Navbar/MobileSidebar/PrimaryMenu/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import {useThemeConfig} from '@docusaurus/theme-common';
import {useNavbarMobileSidebar} from '@docusaurus/theme-common/internal';
import NavbarItem from '@theme/NavbarItem';
function useNavbarItems() {
// TODO temporary casting until ThemeConfig type is improved
return useThemeConfig().navbar.items;
}
// The primary menu displays the navbar items
export default function NavbarMobilePrimaryMenu() {
const mobileSidebar = useNavbarMobileSidebar();
// TODO how can the order be defined for mobile?
// Should we allow providing a different list of items?
const items = useNavbarItems();
return (
<ul className="menu__list">
{items.map((item, i) => (
<NavbarItem
mobile
{...item}
onClick={() => mobileSidebar.toggle()}
key={i}
/>
))}
</ul>
);
}
Loading

0 comments on commit d3c17a5

Please sign in to comment.