diff options
| author | Oliver <oliver@mohlin.dev> | 2025-01-08 20:30:07 +0100 |
|---|---|---|
| committer | Markus Pettersson <markus.pettersson@mullvad.net> | 2025-01-13 15:02:51 +0100 |
| commit | ed2b55346ce702285703bf4e93bd6d938cb783c7 (patch) | |
| tree | 3919f58e204d0c040c0d1dadec5a8cbf5ec0b73d | |
| parent | db47f912430b49f1d638843f986e2851e0696c0c (diff) | |
| download | mullvadvpn-ed2b55346ce702285703bf4e93bd6d938cb783c7.tar.xz mullvadvpn-ed2b55346ce702285703bf4e93bd6d938cb783c7.zip | |
Add NavigationHeader component
8 files changed, 118 insertions, 0 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/index.ts index 677ca79d47..ff83ea947f 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/index.ts +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/index.ts @@ -1 +1,2 @@ export * from './header'; +export * from './navigation-header'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/NavigationHeader.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/NavigationHeader.tsx new file mode 100644 index 0000000000..9b73e18f85 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/NavigationHeader.tsx @@ -0,0 +1,53 @@ +import styled from 'styled-components'; + +import { Colors, Spacings } from '../../../foundations'; +import { TransientProps } from '../../../types'; +import { Flex } from '../../layout'; +import { + NavigationHeaderButtonGroup, + NavigationHeaderIconButton, + NavigationHeaderTitle, +} from './components'; +import { NavigationHeaderProvider } from './NavigationHeaderContext'; + +export type NavigationHeaderProps = React.PropsWithChildren<{ + titleVisible?: boolean; +}>; + +const StyledHeader = styled.nav<TransientProps<NavigationHeaderProps>>({ + backgroundColor: Colors.darkBlue, +}); + +export const StyledContent = styled.div({ + display: 'grid', + gridTemplateColumns: '1fr auto 1fr', + placeContent: 'center', + minHeight: '32px', + height: '32px', +}); + +const NavigationHeader = ({ titleVisible, children, ...props }: NavigationHeaderProps) => { + return ( + <NavigationHeaderProvider titleVisible={!!titleVisible}> + <StyledHeader {...props}> + <Flex + $flexDirection="column" + $justifyContent="center" + $padding={{ + horizontal: Spacings.spacing5, + vertical: Spacings.spacing3, + }}> + <StyledContent>{children}</StyledContent> + </Flex> + </StyledHeader> + </NavigationHeaderProvider> + ); +}; + +const NavigationHeaderNamespace = Object.assign(NavigationHeader, { + ButtonGroup: NavigationHeaderButtonGroup, + IconButton: NavigationHeaderIconButton, + Title: NavigationHeaderTitle, +}); + +export { NavigationHeaderNamespace as NavigationHeader }; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/NavigationHeaderContext.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/NavigationHeaderContext.tsx new file mode 100644 index 0000000000..d0111b50bd --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/NavigationHeaderContext.tsx @@ -0,0 +1,24 @@ +import { createContext, useContext } from 'react'; + +interface NavigationHeaderContextProps { + titleVisible: boolean; +} + +const NavigationHeaderContext = createContext<NavigationHeaderContextProps | undefined>(undefined); + +export const NavigationHeaderProvider = ({ + titleVisible, + children, +}: React.PropsWithChildren<NavigationHeaderContextProps>) => ( + <NavigationHeaderContext.Provider value={{ titleVisible }}> + {children} + </NavigationHeaderContext.Provider> +); + +export const useNavigationHeader = (): NavigationHeaderContextProps => { + const context = useContext(NavigationHeaderContext); + if (context === undefined) { + throw new Error('useNavigationHeader must be used within a NavigationHeaderProvider'); + } + return context; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderButtonGroup.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderButtonGroup.tsx new file mode 100644 index 0000000000..b6fc317554 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderButtonGroup.tsx @@ -0,0 +1,9 @@ +import styled from 'styled-components'; + +import { Spacings } from '../../../../foundations'; +import { Flex } from '../../../layout'; + +export const NavigationHeaderButtonGroup = styled(Flex).attrs({ + $gap: Spacings.spacing6, + $alignItems: 'center', +})({}); diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderIconButton.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderIconButton.tsx new file mode 100644 index 0000000000..531e97eafd --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderIconButton.tsx @@ -0,0 +1,5 @@ +import { IconButton, IconButtonProps } from '../../../molecules'; + +export const NavigationHeaderIconButton = (props: IconButtonProps) => { + return <IconButton variant="secondary" {...props} />; +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderTitle.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderTitle.tsx new file mode 100644 index 0000000000..31164ffdea --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/NavigationHeaderTitle.tsx @@ -0,0 +1,22 @@ +import styled from 'styled-components'; + +import { TitleMedium } from '../../../typography'; +import { useNavigationHeader } from '../NavigationHeaderContext'; + +export interface NavigationHeaderTitleProps { + children: React.ReactNode; +} + +export const StyledText = styled(TitleMedium)<{ $visible?: boolean }>(({ $visible = true }) => ({ + opacity: $visible ? 1 : 0, + transition: 'opacity 250ms ease-in-out', +})); + +export const NavigationHeaderTitle = ({ children }: NavigationHeaderTitleProps) => { + const { titleVisible } = useNavigationHeader(); + return ( + <StyledText tag="h1" $visible={titleVisible}> + {children} + </StyledText> + ); +}; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/index.ts new file mode 100644 index 0000000000..1869233158 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/components/index.ts @@ -0,0 +1,3 @@ +export * from './NavigationHeaderButtonGroup'; +export * from './NavigationHeaderTitle'; +export * from './NavigationHeaderIconButton'; diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/index.ts new file mode 100644 index 0000000000..e5022e8bf9 --- /dev/null +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/components/organisms/navigation-header/index.ts @@ -0,0 +1 @@ +export * from './NavigationHeader'; |
