From 0a1592db73bbbc4a49caf1d5fde3529314ba3031 Mon Sep 17 00:00:00 2001 From: Neshura Date: Mon, 19 Dec 2022 21:03:08 +0100 Subject: [PATCH] Addresses #29, #28, #26, #20, #19 --- components/footer.tsx | 2 +- components/navbar.tsx | 48 ++-- components/styles/content.tsx | 2 +- components/styles/generic.tsx | 5 +- components/styles/navbar.tsx | 148 ----------- components/styles/navbar/desktop.tsx | 54 ++++ components/styles/navbar/mobile.tsx | 247 ++++++++++++++++++ .../desktop.tsx} | 0 components/styles/themedropdown/mobile.tsx | 49 ++++ components/themeselector.tsx | 53 ++-- 10 files changed, 416 insertions(+), 192 deletions(-) delete mode 100644 components/styles/navbar.tsx create mode 100644 components/styles/navbar/desktop.tsx create mode 100644 components/styles/navbar/mobile.tsx rename components/styles/{themedropdown.tsx => themedropdown/desktop.tsx} (100%) create mode 100644 components/styles/themedropdown/mobile.tsx diff --git a/components/footer.tsx b/components/footer.tsx index 9af8993..c5824b5 100644 --- a/components/footer.tsx +++ b/components/footer.tsx @@ -8,7 +8,7 @@ const PageFooter = () => { ); } -const NavMenuFooter = () => { +export const NavMenuFooter = () => { return ( Built using Next.js diff --git a/components/navbar.tsx b/components/navbar.tsx index 6d3dbe7..83a84c5 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -1,9 +1,10 @@ import { usePathname } from 'next/navigation' -import { NavBar, NavBarMobile, NavIndicator, NavIndicators, NavLink, NavSideMenu, NavSideMenuButton, NavSideMenuPanel, NavSideMenuButtonPlaceholder, NavWrap, NavWrapMobile, NavWrapMobileGhost, NavSideMenuGhost } from './styles/navbar'; +import { NavBarMobile, NavIndicator, NavIndicators , NavSideMenu, NavSideMenuButton, NavSideMenuPanel, NavLinkMobile, NavWrapMobile, NavWrapMobileGhost, NavSideMenuGhost } from './styles/navbar/mobile'; +import { NavBar, NavLink, NavWrap } from './styles/navbar/desktop'; import { StyleSelector, StyleSelectorPlaceholder } from './themeselector'; import Links from '../public/data/navbar.json'; import { useState } from 'react'; -import NavMenuFooter from './footer'; +import { NavMenuFooter } from './footer'; const PageNavbar = ({ mobile }: { mobile: number }) => { const path = usePathname(); @@ -12,48 +13,47 @@ const PageNavbar = ({ mobile }: { mobile: number }) => { function handleSidebar(event: any) { if (!event.currentTarget.contains(event.relatedTarget)) { setSideBarActive(false); - console.log(event.relatedTarget); // DEBUG } - else { console.log("nah") } // DEBUG } let navbar: JSX.Element; if (mobile) { navbar = ( <> - handleSidebar(event)} active={+sideBarActive}> - - {Links.links.map((item) => ( - - {item.name} - - ))} - - Mastodon - - - - - - + handleSidebar(event)} active={+sideBarActive}> + setSideBarActive(sideBarActive => !sideBarActive)} active={+sideBarActive}>Menu + + + {Links.links.map((item) => ( + + {item.name} + + ))} + + Mastodon + + + + + + + - setSideBarActive(!sideBarActive)} active={+sideBarActive}>Menu {Links.links.map((item) => ( ))} - - + ); } else { navbar = ( - + {Links.links.map((item) => ( @@ -64,7 +64,7 @@ const PageNavbar = ({ mobile }: { mobile: number }) => { Mastodon - + ); } diff --git a/components/styles/content.tsx b/components/styles/content.tsx index 31c35d8..376cc94 100644 --- a/components/styles/content.tsx +++ b/components/styles/content.tsx @@ -24,7 +24,7 @@ export const PageTitle = styled.h1` export const PageDescription = styled.p` background-color: ${({ theme }) => theme.colors.background ? theme.colors.background : ""}; padding: 0.25rem 0.5rem; - margin: 4rem 0; + margin: 4rem 2rem; line-height: 1.5; font-size: 1.5rem; text-align: center; diff --git a/components/styles/generic.tsx b/components/styles/generic.tsx index 3aa4db4..dbc3c45 100644 --- a/components/styles/generic.tsx +++ b/components/styles/generic.tsx @@ -45,6 +45,7 @@ export const Footer = styled.footer` ` export const MobileFooter = styled(Footer)` - position: absolute; - bottom: 100%; + white-space: nowrap; + flex: 0.5; + width: 100%; ` diff --git a/components/styles/navbar.tsx b/components/styles/navbar.tsx deleted file mode 100644 index 4eade9d..0000000 --- a/components/styles/navbar.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import styled from 'styled-components' -import Link from 'next/link'; - -interface ActivePropType { - active?: number; -} - -export const NavWrap = styled.div` - display: flex; - flex-wrap: nowrap; - justify-content: center; - align-items: center; - border-bottom: 1px solid ${({ theme }) => theme.colors.primary}; -` - - -export const NavWrapMobile = styled(NavWrap)` - width: 100%; - flex-direction: row; - position: fixed; - z-index: 100; -` - -export const NavWrapMobileGhost = styled.div` - position: relative; - width: 100%; - height: 57px; -` - -export const NavSideMenu = styled.div ` - position: fixed; - top: 0%; left: 0%; right: 0%; bottom: 0%; - max-width: ${ props => props.active ? "60%" : "0%"}; - display: flex; - justify-content: space-between; - flex-direction: column; - align-items: center; - height: 100%; - z-index: 100; - - background-color: ${({ theme }) => theme.colors.background}; - visibility: ${ props => props.active ? "visible" : "hidden"}; - width: ${ props => props.active ? "360px" : "0%"}; - transition-delay: ${ props => props.active ? "0s, 0s" : "0s, 0.3s"}; -` - -export const NavSideMenuPanel = styled.div ` - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - -` - -export const NavSideMenuButton = styled.button ` - z-index: 100; - margin: 16px; - color: ${ props => props.active ? ({ theme }) => theme.colors.background : ({ theme }) => theme.colors.primary }; - background-color: ${ props => props.active ? ({ theme }) => theme.colors.secondary : ({ theme }) => theme.colors.background }; -` - -export const NavSideMenuButtonPlaceholder = styled.div` - width: 48px; - margin: 16px; -` - -export const NavSideMenuGhost = styled.div` - -` - -export const NavBar = styled.nav` - margin-right: 1%; - display: flex; - flex: 1; - padding: 1rem 0; - flex-wrap: nowrap; - justify-content: center; - align-items: center; -` - -export const NavBarMobile = styled(NavBar)` - flex-direction: column; -` - -export const NavLink = styled(Link) ` - color: ${props => props.active ? - ({ theme }) => theme.invertButtons ? - theme.colors.text ? theme.colors.text : theme.colors.secondary : theme.colors.secondary : - ({ theme }) => theme.colors.primary}; - - background-color: ${props => props.active ? - ({ theme }) => theme.invertButtons ? - theme.colors.secondary : theme.colors.background : - ({ theme }) => theme.colors.background}; - - padding: 2px 6px; - border: 2px solid; - - margin: 0.2rem; - border-radius: 5px; - display: flex; - justify-content: center; - align-items: center; - transition: all 0.1s ease; - - &:hover { - color: ${({ theme }) => theme.invertButtons ? - theme.colors.text ? theme.colors.text : theme.colors.primary : - theme.colors.secondary}; - - background-color: ${({ theme }) => theme.invertButtons ? - theme.colors.secondary : - theme.colors.background}; - } -` - -export const NavIndicators = styled.nav` - width: 100%; - display: flex; - flex: 1; - padding: 1rem 0; - flex-wrap: nowrap; - justify-content: center; - align-items: center; -` - -export const NavIndicator = styled(Link) ` - margin: 0.2rem; - border-radius: 50%; - aspect-ratio: 1; - width: 10px; - border: 1px solid ${({ theme }) => theme.colors.primary}; - - background-color: ${props => props.active ? - ({ theme }) => theme.invertButtons ? - theme.colors.secondary : theme.colors.background : - ({ theme }) => theme.colors.background}; - - &:hover { - color: ${({ theme }) => theme.invertButtons ? - theme.colors.text ? theme.colors.text : theme.colors.primary : - theme.colors.secondary}; - - background-color: ${({ theme }) => theme.invertButtons ? - theme.colors.secondary : - theme.colors.background}; - } -` \ No newline at end of file diff --git a/components/styles/navbar/desktop.tsx b/components/styles/navbar/desktop.tsx new file mode 100644 index 0000000..b77b140 --- /dev/null +++ b/components/styles/navbar/desktop.tsx @@ -0,0 +1,54 @@ +import styled from 'styled-components' +import Link from 'next/link'; + +interface ActivePropType { + active?: number; +} + +export const NavWrap = styled.div` + display: flex; + flex-wrap: nowrap; + justify-content: center; + align-items: center; + border-bottom: 1px solid ${({ theme }) => theme.colors.primary}; +` + +export const NavBar = styled.nav` + margin-right: 1%; + display: flex; + flex: 1; + padding: 1rem 0; + flex-wrap: nowrap; + justify-content: center; + align-items: center; +` + +export const NavLink = styled(Link) ` + color: ${props => props.active ? + ({ theme }) => theme.invertButtons ? + theme.colors.text ? theme.colors.text : theme.colors.secondary : theme.colors.secondary : + ({ theme }) => theme.colors.primary}; + + background-color: ${props => props.active ? + ({ theme }) => theme.invertButtons ? + theme.colors.secondary : theme.colors.background : + ({ theme }) => theme.colors.background}; + + padding: 2px 6px; + border: 2px solid; + + margin: 0.2rem; + border-radius: 5px; + display: flex; + transition: all 0.1s ease; + + &:hover { + color: ${({ theme }) => theme.invertButtons ? + theme.colors.text ? theme.colors.text : theme.colors.primary : + theme.colors.secondary}; + + background-color: ${({ theme }) => theme.invertButtons ? + theme.colors.secondary : + theme.colors.background}; + } +` \ No newline at end of file diff --git a/components/styles/navbar/mobile.tsx b/components/styles/navbar/mobile.tsx new file mode 100644 index 0000000..19567e7 --- /dev/null +++ b/components/styles/navbar/mobile.tsx @@ -0,0 +1,247 @@ +import styled from 'styled-components' +import Link from 'next/link'; +import { NavBar, NavLink, NavWrap } from './desktop'; + +interface ActivePropType { + active?: number; +} + +interface MultipliesPropType { + num?: number; +} + +export const NavWrapMobile = styled(NavWrap)` + width: 100%; + flex-direction: row; + position: fixed; + z-index: 50; +` + +export const NavWrapMobileGhost = styled.div` + position: relative; + width: 100%; + height: 50px; +` + +export const NavSideMenu = styled.div ` + position: fixed; + top: 0%; left: 0%; right: 0%; bottom: 0%; + max-width: ${props => props.active ? "240px" : "0px"}; + max-height: ${props => props.active ? "100%" : "50px"}; + display: flex; + justify-content: space-between; + flex-direction: column; + height: 100%; + z-index: 100; + border-right: ${ props => ({ theme }) => { + let ret: string; + if(props.active) { + ret = "1px solid " + theme.colors.primary; + } + else { + ret = "0px solid"; + } + return ret; + }}; + + background-color: ${ props => ({ theme }) => { + let ret: string; + if (props.active) { + ret = theme.colors.background; + } + else { + ret = ""; + } + return ret; + }}; + + overflow-x: hidden; + transition-property: max-width, max-height, border-right, background-color; + transition-timing-function: ease-in-out; + transition-duration: 0.15s, 0s, 0s, 0s; + transition-delay: ${props => props.active ? "0s, 0s, 0s, 0s" : "0s, 0.15s, 0.15s, 0.15s"}; +` + +export const NavSideMenuPanel = styled.div ` + height: 100%; + width: 240px; + overflow: hidden; + display: flex; + flex-direction: column; + align-items: left; +` + +export const NavSideMenuButton = styled.button ` + position: ${ props => props.active ? "absolute" : "fixed"}; + z-index: 200; + left: ${ props => props.active ? "165px" : "0px"}; + + transition-property: left, color, background-color, border-color; + transition-timing-function: ease-in-out; + transition-duration: 0.135s, 0.15s; + transition-delay: ${props => props.active ? "0.03s, 0s" : "0s, 0s"}; + + align-self: flex-end; + cursor: pointer; + margin: 12px; + color: ${props => ({ theme }) => { + let ret: string; + if (props.active) { + if (theme.invertButtons) { + ret = theme.colors.text ? theme.colors.text : theme.colors.secondary; + } + else { + ret = theme.colors.secondary; + } + } + else { + ret = theme.colors.primary; + } + return ret; + }}; + background-color: ${props => ({ theme }) => { + let ret: string; + if (props.active) { + if (theme.invertButtons) { + ret = theme.colors.secondary; + } + else { + ret = theme.colors.background; + } + } + else { + ret = theme.colors.background; + } + return ret; + }}; + + border: 2px solid; + border-radius: 5px; + border-color: ${props => ({ theme }) => { + let ret: string; + if (props.active) { + if (theme.invertButtons) { + ret = theme.colors.text ? theme.colors.text : theme.colors.secondary; + } + else { + ret = theme.colors.secondary; + } + } + else { + ret = theme.colors.primary; + } + return ret; + }}; + + &:hover { + color: ${({ theme }) => { + let ret: string; + if (theme.invertButtons) { + ret = theme.colors.text ? theme.colors.text : theme.colors.primary; + } + else { + ret = theme.colors.secondary; + } + return ret; + }}; + + background-color: ${({ theme }) => { + let ret: string; + if (theme.invertButtons) { + ret = theme.colors.secondary; + } + else { + ret = theme.colors.background; + } + return ret; + }}; + + border-color: ${({ theme }) => { + let ret: string; + if (theme.invertButtons) { + ret = theme.colors.text ? theme.colors.text : theme.colors.secondary; + } + else { + ret = theme.colors.secondary; + } + return ret; + }}; + } +` + +export const NavSideMenuGhost = styled.div ` + flex: ${ props => props.num ? props.num * 2 : 2 }; +` + +export const NavBarMobile = styled(NavBar)` + margin-top: 56px; + flex-direction: column; + align-items: flex-start; +` + +export const NavLinkMobile = styled(NavLink)` + display: block; + margin-left: 1rem; + margin-top: 1rem; + padding: 0.5rem; + border: none; + border-top: 2px solid; + width: 80%; + text-align: center; + + color: ${props => ({ theme }) => props.active ? theme.colors.secondary : theme.colors.primary}; + background-color: ${({ theme }) => theme.colors.backgroundAlt ? theme.colors.backgroundAlt : theme.colors.background}; + + &:hover { + color: ${({ theme }) => theme.colors.secondary }; + background-color: ${({ theme }) => theme.colors.backgroundAlt ? theme.colors.backgroundAlt : theme.colors.background}; + } +` + +export const NavIndicators = styled.nav` + background-color: ${({ theme }) => theme.colors.background}; + background-image: ${({ theme }) => theme.backgroundImage ? "url(" + theme.backgroundImage + ")" : ""}; + background-repeat: no-repeat; + background-attachment: fixed; + background-size: cover; + width: 100%; + display: flex; + flex: 1; + padding: 1rem 0; + flex-wrap: nowrap; + justify-content: center; + align-items: center; +` + +export const NavIndicator = styled(Link) ` + margin: 0.2rem; + border-radius: 50%; + aspect-ratio: 1; + width: 10px; + border: 1px solid; + border-color: ${ props => ({ theme }) => props.active ? + theme.invertButtons ? theme.colors.secondary : theme.colors.primary : + theme.colors.primary + }; + + background-color: ${props => ({ theme }) => props.active ? + theme.invertButtons ? theme.colors.secondary : theme.colors.primary : + theme.colors.background + }; + + &:hover { + border-color: ${ props => ({ theme }) => + theme.invertButtons ? theme.colors.secondary : theme.colors.primary + }; + + color: ${({ theme }) => theme.invertButtons ? + theme.invertButtons ? theme.colors.secondary : theme.colors.primary : + theme.colors.primary + }; + + background-color: ${({ theme }) => theme.invertButtons ? + theme.colors.secondary : + theme.colors.primary + }; + } +` \ No newline at end of file diff --git a/components/styles/themedropdown.tsx b/components/styles/themedropdown/desktop.tsx similarity index 100% rename from components/styles/themedropdown.tsx rename to components/styles/themedropdown/desktop.tsx diff --git a/components/styles/themedropdown/mobile.tsx b/components/styles/themedropdown/mobile.tsx new file mode 100644 index 0000000..f5acd3c --- /dev/null +++ b/components/styles/themedropdown/mobile.tsx @@ -0,0 +1,49 @@ +import styled from 'styled-components'; +import { ThemeDropDown, ThemeDropDownButton, ThemeDropDownOption, ThemeDropDownOptions } from './desktop'; + +export const ThemeDropDownMobile = styled(ThemeDropDown)` + width: 80%; + margin-left: 1rem; +`; + +export const ThemeDropDownButtonMobile = styled(ThemeDropDownButton)` + width: 100%; + padding: 0.5rem; + border: none; + border-top: 2px solid; + border-left: ${ props => props.show ? "2px solid" : "0px solid"}; + border-right: ${ props => props.show ? "2px solid" : "0px solid"}; + + color: ${props => ({ theme }) => props.focus ? theme.colors.secondary : theme.colors.primary}; + background-color: ${({ theme }) => theme.colors.backgroundAlt ? theme.colors.backgroundAlt : theme.colors.background}; + + &:focus,:hover { + color: ${({ theme }) => theme.colors.secondary}; + + background-color: ${({ theme }) => theme.colors.backgroundAlt ? theme.colors.backgroundAlt : theme.colors.background}; + } + + transition-property: color, border-bottom-left-radius, border-bottom-right-radius, background-color, border-left, border-right; + transition-timing-function: ease; + transition-duration: 0.15s; + transition-delay: 0s, ${ props => props.show ? "0s" : "0.6s, 0.6s, 0s, 0.6s, 0.6s" }; +`; + +export const ThemeDropDownOptionsMobile = styled(ThemeDropDownOptions)` + background-image: unset; + background-color: ${({ theme }) => theme.colors.background}; + border: 2px solid ${props => ({ theme }) => props.focus ? theme.colors.secondary : theme.colors.primary}; + border-top: 0; + max-height: ${ props => props.show ? "100%" : "0%"}; + position: relative; + width: 100%; +`; + +export const ThemeDropDownOptionMobile = styled(ThemeDropDownOption)` + text-align: left; + margin: 0.5rem; + padding: 0rem 0.5rem; + width: 80%; + border-left: 2px solid; + border-radius: 5px; +`; \ No newline at end of file diff --git a/components/themeselector.tsx b/components/themeselector.tsx index eb4fee9..55be165 100644 --- a/components/themeselector.tsx +++ b/components/themeselector.tsx @@ -2,10 +2,11 @@ import { useUpdateTheme } from "../pages/_app"; import { useContext, useState } from 'react'; import { ThemeContext, DefaultTheme } from "styled-components"; import { darkTheme, lightTheme } from './themes'; -import { ThemeDropDown, ThemeDropDownButton, ThemeDropDownOption, ThemeDropDownOptions } from "./styles/themedropdown"; +import { ThemeDropDown, ThemeDropDownButton, ThemeDropDownOption, ThemeDropDownOptions } from "./styles/themedropdown/desktop"; +import { ThemeDropDownMobile, ThemeDropDownButtonMobile, ThemeDropDownOptionMobile, ThemeDropDownOptionsMobile } from "./styles/themedropdown/mobile"; import Themes from '../public/data/themes.json'; -export const StyleSelector = () => { +export const StyleSelector = ({ mobile }: { mobile: number }) => { const themes: DefaultTheme[] = Themes.themes; const updateTheme = useUpdateTheme(); const currentTheme = useContext(ThemeContext); @@ -34,7 +35,7 @@ export const StyleSelector = () => { } } - const [visible, setVisible] = useState(false); + const [visible, setVisible] = useState(true); //DEBUG set to false const [buttonFocus, setButtonFocus] = useState(visible); function handleBlur(event:any) { @@ -44,19 +45,39 @@ export const StyleSelector = () => { } } - return ( - handleBlur(event)}> - setButtonFocus(true)} onClick={() => setVisible(visible => !visible)}>{selectedTheme.themeName} - - - {themes.map((theme) => ( - updateThemeWithStorage(theme)}> - {theme.themeName} - - ))} - - - ); + let themeselector: JSX.Element; + if(mobile) { + themeselector = ( + handleBlur(event)}> + setButtonFocus(true)} onClick={() => setVisible(visible => !visible)}> + {selectedTheme.themeName} + + + {themes.map((theme) => ( + updateThemeWithStorage(theme)}> + {theme.themeName} + + ))} + + + ); + } + else { + themeselector = ( + handleBlur(event)}> + setButtonFocus(true)} onClick={() => setVisible(visible => !visible)}>{selectedTheme.themeName} + + + {themes.map((theme) => ( + updateThemeWithStorage(theme)}> + {theme.themeName} + + ))} + + + ); + } + return themeselector; } export const StyleSelectorPlaceholder = () => {