Skip to content
This repository has been archived by the owner on Jul 16, 2023. It is now read-only.

Commit

Permalink
feat: ✨ added configurable full screen mode
Browse files Browse the repository at this point in the history
  • Loading branch information
filipowm committed Aug 3, 2020
1 parent 909ab00 commit b2c954f
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 54 deletions.
6 changes: 5 additions & 1 deletion config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,8 @@ features:
toc:
show: true
depth: 4

fullScreenMode:
enabled: true
hideHeader: true
hideToc: true
hideSidebar: true
8 changes: 7 additions & 1 deletion config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ module.exports = {
enabled: true,
default: false,
},
publishDraft: false
publishDraft: false,
fullScreenMode: {
enabled: false,
hideHeader: true,
hideToc: true,
hideSidebar: true
}
},
};
19 changes: 18 additions & 1 deletion content/configuration/setting-up/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,21 @@ features:
Even if table of contents is globally turned off or on, it can be altered
per page by setting up `showToc` property in [frontmatter](/editingcontent/page_config#frontmatter).
Also on page you can alter depth of table of contents by setting up
`tocDepth` in frontmatter. Both settings have precedence over global configuration.
`tocDepth` in frontmatter. Both settings have precedence over global configuration.

## Full screen mode

Full screen mode can be used to hide any disruptive page elements
and focus only on content. You can configure which elements should
be hidden while in full screen mode.

**Important:** Full screen mode is disabled by default.

```yaml
features:
fullScreenMode:
enabled: false # set to true to enable full screen mode
hideHeader: true # set to true to hide header while in full screen mode
hideSidebar: true # set to true to hide sidebar while in full screen mode
hideToc: true # set to true to hide Table of Contents while in full screen mode
```
4 changes: 2 additions & 2 deletions content/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ you treat your documentation in the same way as your code.
- responsive, optimized for mobile devices
- integration with Google Analytics
- Search Engine Optimization (_SEO_) friendliness
- full screen mode
- RSS feed
- easy way to edit content on Gitlab, Github or Bitbucket
- custom CLI helping to initialize and develop BooGi apps
Expand All @@ -55,7 +56,7 @@ you treat your documentation in the same way as your code.
<Info>Features listed here will arrive in Q2/Q3 2020!</Info>

- local search capabilities without need to integrate with an external system
- full screen mode
- embed files to download
- sharing on social media
- syntax highlighting improvements (more languages, copy code snippets, show language used)
- new components: tabs, math formulas
Expand All @@ -67,7 +68,6 @@ What we will be working on next?

- documentation versions
- API documentation with OpenAPI support
- embed files to download
- authentication (OAuth2, LDAP) when using Docker / Kubernetes deployment
- improved and even faster site navigation
- support for multiple languages
Expand Down
96 changes: 56 additions & 40 deletions src/components/Header/Header.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useState, useEffect } from 'react';
import { StaticQuery, graphql } from 'gatsby';
import styled from '@emotion/styled';
import 'css';
import config from 'config';
import Logo from './logo';
import Navigation from './navigation';
Expand All @@ -13,6 +12,7 @@ import { Rss } from '../Buttons';
import { globalHistory } from '@reach/router';
import { hiddenMobile, visibleMobile, visibleTablet, hiddenTablet } from '../../styles';
import { onMobile, onTablet, isMobile } from '../../styles/responsive';
import { FullScreenClose, FullScreenEnter, FullScreenHeader } from './fullscreen';

const isSearchEnabled = config.features.search && config.features.search.enabled;

Expand All @@ -39,7 +39,7 @@ const HeaderWrapper = styled.header`
border-radius: 0;
margin-bottom: 0;
border: 0;
display: flex;
display: ${(props) => (props.show ? 'flex' : 'none')};
align-items: center;
box-shadow: 0 3px 8px 0 ${(props) => props.theme.header.shadow};
border-bottom: 1px solid ${(props) => props.theme.header.border};
Expand Down Expand Up @@ -200,7 +200,7 @@ const SocialButtonsWrapper = styled.div`
}
`;

const Header = ({ setShowSearch, location, themeProvider }) => (
const Header = ({ setShowSearch, location, themeProvider, show, toggleFullscreenMode }) => (
<StaticQuery
query={graphql`
query headerTitleQuery {
Expand Down Expand Up @@ -248,7 +248,6 @@ const Header = ({ setShowSearch, location, themeProvider }) => (
const DarkModeButton = config.features.darkMode.enabled ? (
<DarkModeSwitch
{...iconBaseProps}
style={{ marginLeft: '10px' }}
hoverFill={theme.header.icons.hover}
fill={theme.header.icons.fill}
isDarkThemeActive={darkMode}
Expand All @@ -265,45 +264,62 @@ const Header = ({ setShowSearch, location, themeProvider }) => (
setShowSearch(false);
});
return (
<HeaderWrapper>
<Logo link={logoLink} img={logoImg} title={headerTitle} />
<TopNavigation css={hiddenMobile}>
<Navigation links={headerLinks} />
</TopNavigation>
<ButtonsWrapper>
{isSearchEnabled ? (
<>
<SearchOpener open={open} forcedComponent={'icon'} css={visibleTablet} />
<SearchOpener open={open} css={hiddenTablet} />
</>
) : null}
{helpUrl && helpUrl.length > 0 ? (
<HelpButton css={hiddenMobile} helpUrl={helpUrl} />
) : (
''
)}
<SocialButtonsWrapper css={hiddenMobile}>
{SocialButtons(iconBaseProps, config.social)}
</SocialButtonsWrapper>
<RssIcon {...iconBaseProps} />
{DarkModeButton}
<MobileMenuToggle toggle={toggleMenuOpen} open={menuOpen} />
</ButtonsWrapper>

{isMobile() ? (
<MobileNavigation css={visibleMobile} show={menuOpen}>
<Sidebar location={location} />

<Navigation links={headerLinks} />

<SocialButtonsWrapper css={visibleMobile}>
{SocialButtons(iconBaseProps, config.social)}
</SocialButtonsWrapper>
</MobileNavigation>
<>
{config.features.fullScreenMode.enabled &&
config.features.fullScreenMode.enabled === true ? (
<FullScreenHeader show={!show} css={hiddenMobile}>
<FullScreenClose toggle={toggleFullscreenMode} />
{DarkModeButton}
</FullScreenHeader>
) : (
''
)}
</HeaderWrapper>
<HeaderWrapper show={show}>
<Logo link={logoLink} img={logoImg} title={headerTitle} />
<TopNavigation css={hiddenMobile}>
<Navigation links={headerLinks} />
</TopNavigation>
<ButtonsWrapper>
{isSearchEnabled ? (
<>
<SearchOpener open={open} forcedComponent={'icon'} css={visibleTablet} />
<SearchOpener open={open} css={hiddenTablet} />
</>
) : null}
{helpUrl && helpUrl.length > 0 ? (
<HelpButton css={hiddenMobile} helpUrl={helpUrl} />
) : (
''
)}
<SocialButtonsWrapper css={hiddenMobile}>
{SocialButtons(iconBaseProps, config.social)}
</SocialButtonsWrapper>
<RssIcon {...iconBaseProps} />
{config.features.fullScreenMode.enabled &&
config.features.fullScreenMode.enabled === true ? (
<FullScreenEnter toggle={toggleFullscreenMode} css={hiddenMobile} />
) : (
''
)}
{DarkModeButton}
<MobileMenuToggle toggle={toggleMenuOpen} open={menuOpen} />
</ButtonsWrapper>

{isMobile() ? (
<MobileNavigation css={visibleMobile} show={menuOpen}>
<Sidebar location={location} show={true} />

<Navigation links={headerLinks} />

<SocialButtonsWrapper css={visibleMobile}>
{SocialButtons(iconBaseProps, config.social)}
</SocialButtonsWrapper>
</MobileNavigation>
) : (
''
)}
</HeaderWrapper>
</>
);
}}
/>
Expand Down
62 changes: 62 additions & 0 deletions src/components/Header/fullscreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import styled from '@emotion/styled';
import { Maximize, Minimize } from 'react-feather';
import { useTheme } from 'emotion-theming';
import { ButtonIcon } from '../';

export const FullScreenEnter = styled(({ toggle, ...props }) => {
const theme = useTheme();
return (
<ButtonIcon
title={'Enter fullscreen mode'}
background={theme.header.icons.background}
hoverStroke={theme.header.icons.hover}
fill={'transparent'}
stroke={theme.header.icons.stroke}
icon={Maximize}
onClick={toggle}
{...props}
/>
);
})``;

export const FullScreenHeader = styled.div`
display: ${(props) => (props.show ? 'flex' : 'none')};
position: fixed;
justify-content: flex-end;
align-items: center;
height: 32px;
padding: 6px;
width: 100%;
z-index: 10;
top: 0;
background-color: ${(props) => props.theme.header.background};
`;

export const FullScreenClose = styled(({ className, toggle }) => {
const theme = useTheme();
return (
<div className={className} onClick={toggle}>
<span css={{marginRight: '6px'}}>Close full mode</span>
<ButtonIcon
title={'Close fullscreen mode'}
background={theme.header.icons.background}
hoverStroke={theme.header.icons.hover}
fill={'transparent'}
stroke={theme.header.icons.stroke}
icon={Minimize}
/>
</div>
);
})`
display: flex;
transition: ${(props) => props.theme.transitions.hover};
cursor: pointer;
align-items: center;
font-size: 10pt;
margin-right: 10px;
&:hover{
color: ${(props) => props.theme.colors.hover};
}
`;

8 changes: 6 additions & 2 deletions src/components/Layout/Layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import React, { useRef, useEffect, useState } from 'react';
import { Slide } from 'react-reveal';
import { hiddenMobile, hiddenTablet } from '../../styles';
import { onMobile, onTablet } from '../../styles/responsive';
import 'css';

const Wrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -77,6 +78,7 @@ function actOnClose(ref, onClose) {
const Layout = ({ children, location }) => {
const [showSearch, setShowSearch] = useState(false);
const [searchVisible, setSearchVisible] = useState(false);
const [fullscreenMode, setFullScreenMode] = useState(false);
const themeProviderRef = React.createRef();
const searchSidebarRef = useRef(null);
const closeSearch = () => setShowSearch(false);
Expand All @@ -98,9 +100,11 @@ const Layout = ({ children, location }) => {
</Slide>
</div>
<Header
show={! (config.features.fullScreenMode.hideHeader && fullscreenMode)}
location={location}
setShowSearch={setShowSearch}
themeProvider={themeProviderRef}
toggleFullscreenMode={() => setFullScreenMode(!fullscreenMode)}
/>
</>
) : (
Expand All @@ -110,12 +114,12 @@ const Layout = ({ children, location }) => {
{config.features.scrollTop === true ? <ScrollTop /> : ''}
<Wrapper>
{config.sidebar.enabled === true ? (
<Sidebar location={location} css={hiddenMobile} />
<Sidebar show={! (config.features.fullScreenMode.hideSidebar && fullscreenMode)} location={location} css={hiddenMobile} />
) : (
''
)}
<Content id="main-content">{children}</Content>
<TableOfContents location={location} css={hiddenTablet} />
<TableOfContents show={! (config.features.fullScreenMode.hideToc && fullscreenMode)} location={location} css={hiddenTablet} />
</Wrapper>
</MDXProvider>
</ThemeProvider>
Expand Down
9 changes: 5 additions & 4 deletions src/components/Sidebar/Sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ const PoweredByWrapper = styled.div`
box-shadow: 0 -7px 10px -5px ${(props) => props.theme.navigationSidebar.backgroundPrimary};
`;

const NavigationWrapper = styled(({ className, children, ...props }) => {
const NavigationWrapper = styled(({ className, children }) => {
return (
<aside className={className} {...props}>
<aside className={className}>
<Sidebar>{children}</Sidebar>
</aside>
);
})`
display: ${(props) => props.show ? 'block' : 'none'};
height: 100vh;
top: 0;
flex: 0 0 ${(props) => props.theme.layout.leftWidth};
Expand Down Expand Up @@ -118,10 +119,10 @@ const Divider = styled((props) => (
border-bottom: 1px solid ${(props) => props.theme.navigationSidebar.border};
}
`;
const ContentNavigation = ({ className, location }) => {
const ContentNavigation = ({ show, className, location }) => {
const edges = getNavigationData();
return (
<NavigationWrapper className={className}>
<NavigationWrapper className={className} show={show}>
<SidebarMain css={scrollbar}>
<ContentTree edges={edges} location={location} />
{config.sidebar.links && config.sidebar.links.length > 0 ? (
Expand Down
6 changes: 3 additions & 3 deletions src/components/TableOfContents/TableOfContents.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import emoji from '../../utils/emoji';

const Sidebar = styled.aside`
background-color: ${(props) => props.theme.tableOfContents.background};
display: ${(props) => props.show ? 'block' : 'none'};
min-width: 260px;
height: 100vh;
overflow: auto;
Expand Down Expand Up @@ -160,7 +160,7 @@ const tocItemsEqual = (items, targetItems) => {
return true;
};

const TableOfContents = ({ className, location }) => (
const TableOfContents = ({ show, className, location }) => (
<StaticQuery
query={graphql`
query {
Expand Down Expand Up @@ -207,7 +207,7 @@ const TableOfContents = ({ className, location }) => (
}
};
return (
<Sidebar className={className} css={scrollbar}>
<Sidebar show={show} className={className} css={scrollbar}>
<TocTitle>Contents</TocTitle>
<Scrollspy
ref={scrollspyRef}
Expand Down

0 comments on commit b2c954f

Please sign in to comment.