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

Commit

Permalink
add custom overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
nalesnichok committed Jul 6, 2022
1 parent 3d1253b commit f84a200
Show file tree
Hide file tree
Showing 8 changed files with 498 additions and 18 deletions.
13 changes: 13 additions & 0 deletions _override/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import type { Location } from 'history';

export function App({ children, location }: React.PropsWithChildren<{ location: Location }>) {
return (
<>
<header style={{background: 'yellow', textAlign: 'center', padding: '20px 0', fontSize: '24px'}}>
Header
</header>
{children}
</>
);
}
54 changes: 54 additions & 0 deletions _override/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import * as React from 'react';
import styled from 'styled-components';

import { Flex, Link } from '@redocly/developer-portal/ui';


export default function Footer(props) {
const { columns, copyrightText } = props.footer;
console.log(columns)
return (
<FooterWrapper>
<Flex py="60px" px="60px">
<FooterItems>
{
columns.map((col, index) => {
return <li key={index}>
{col.group}
<FooterItems>
{
col.items.map((item, index) => {
return <li key={index}>
<Link to={item.link}>{item.label}</Link>
</li>
})
}
</FooterItems>
</li>
})
}
</FooterItems>
</Flex>
</FooterWrapper>
)
}

const FooterWrapper = styled.div`
background: rgba(34,122,136,0.9);
`;

const FooterItems = styled.ul`
margin: 0;
padding: 0;
display: flex;
align-items: center;
color: #ffffff;
justify-content: start;
& li {
list-style: none;
margin-right: 20px;
& a {
color: #ffffff;
}
}
`;
139 changes: 139 additions & 0 deletions _override/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import * as React from 'react';
import styled from 'styled-components';
import { lighten } from 'polished';

import { MenuItemProps, Link, Arrow, OperationBadge } from '@redocly/developer-portal/ui';
import { theme } from '../theme';

export default function MenuItem(props: MenuItemProps) {
const {
item: { active, expanded, items, link, label, type, httpVerb, external, target },
depth,
isExpanded,
isAlwaysExpanded,
} = props;

const hasChildren = items && items.length > 0;
const ItemTitleComponent = depth === 0 ? HeaderItem : NestedItem;
const arrowDirection = isExpanded ? 'down' : 'right';

const element =
type === 'separator' ? (
<Separator depth={depth}>{label}</Separator>
) : (
<ItemTitleComponent
expanded={!!expanded && hasChildren}
active={active}
depth={depth}
onClick={props.onClick}
isAlwaysExpanded={!!isAlwaysExpanded}
data-cy={`sidebar-item-${label}`}
>
{hasChildren && (
<ArrowWrapper>
{(props.item.menuStyle === 'drilldown' || !isAlwaysExpanded) && (
<Arrow
width="10px"
height="10px"
color={theme.colors.text.primary}
direction={arrowDirection}
data-cy="arrow"
/>
)}
</ArrowWrapper>
)}
{httpVerb && (
<div>
<OperationBadge type={httpVerb}>{httpVerb}</OperationBadge>
</div>
)}
<MenuLabel>{label}</MenuLabel>

</ItemTitleComponent>
);

return link ? (
<Link to={link} target={target || undefined}>
{element}
</Link>
) : (
element
);
}

const MenuItemTitle = styled.div<{
expanded: boolean;
active: boolean;
isAlwaysExpanded: boolean;
}>`
position: relative;
display: flex;
justify-content: space-between;
font-family: ${({ theme }) => theme.typography.headings.fontFamily};
border-left: ${({active}) => active ? '4px solid #DC1928' : '4px solid transparent'};
color: ${props => (props.active ? props.theme.sidebar.activeTextColor : 'inherit')};
background-color: ${props => (props.active ? props.theme.sidebar.activeBgColor : 'inherit')};
cursor: ${({ isAlwaysExpanded }) => (isAlwaysExpanded ? 'default' : 'pointer')};
opacity: 1;
font-size: 0.929em;
padding: 12.5px 20px;
transition: background-color 0.3s, color 0.3s;
:hover {
color: ${({ isAlwaysExpanded, theme }) =>
isAlwaysExpanded ? 'inherit' : theme.sidebar.activeTextColor};
background-color: ${({ isAlwaysExpanded, theme }) =>
isAlwaysExpanded ? 'inherit' : lighten(0.04, theme.sidebar.activeBgColor)};
}
:empty {
padding: 0;
}
`;

const NestedItem = styled(MenuItemTitle)<{ depth: number }>`
color: inherit;
padding-left: ${({ depth }) => `${(depth + 1) * 20}px`};
:hover {
color: inherit;
}
`;

const HeaderItem = styled(MenuItemTitle)<{ depth: number }>`
position: relative;
`;

const Separator = styled.span<{ depth?: number }>`
display: block;
padding: 12.5px 20px;
padding-left: ${({ depth = 0 }) => `${(depth + 1) * 20}px`};
padding-bottom: 2px;
position: relative;
cursor: default;
font-family: ${({ theme }) => theme.typography.headings.fontFamily};
font-size: 0.8em;
text-transform: uppercase;
opacity: 0.8;
&:before {
content: '';
border-left: 3px solid ${({ theme }) => theme.colors.border.light};
position: absolute;
top: -50%;
bottom: -50%;
left: -12px;
z-index: 1;
}
&:empty {
padding: 0.1em 0;
}
&:empty:before {
top: -1.5em;
bottom: -1.5em;
}
`;

const MenuLabel = styled.span`
width: 100%;
`;

const ArrowWrapper = styled.div`
margin-right: 5px;
`;
162 changes: 162 additions & 0 deletions _override/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import * as React from 'react';
import styled from 'styled-components';

import { Flex, Link, SearchBox } from '@redocly/developer-portal/ui';

export default function NavBar(props) {
const { items, logo } = props;

const [isMobileMenuOpened, setMobileMenuOpened] = React.useState(false);
const [pageIsScrolled, setPageIsScrolled] = React.useState(false);
const toggleMobileMenu = () => setMobileMenuOpened(!isMobileMenuOpened);
const hideMobileMenu = () => setMobileMenuOpened(false);

React.useEffect(() => {
const handleScroll = () => setPageIsScrolled(window.scrollY > 10);

document.addEventListener('scroll', handleScroll);

return () => document.removeEventListener('scroll', handleScroll);
}, []);

const navItems = items
.filter(item => item.type !== 'search')
.map((item, index) => {
return (
<NavItem key={index} onClick={hideMobileMenu}>
<Link to={item.link}>{item.label}</Link>
</NavItem>
);
});

return (
<NavWrapper scrolled={pageIsScrolled ? 1 : 0}>
<Flex
maxWidth={{ xs: '100%', large: '1400px' }}
alignItems='center'
justifyContent='space-between'
width='100%'
mx='auto'>
<img src={logo} alt='' height='50' />
<NavItems>
{navItems}
<SearchBox pathPrefix={props.pathPrefix} />
</NavItems>
</Flex>
<NavControls>
<MobileMenuIcon onClick={toggleMobileMenu} />
</NavControls>
<MobileMenu isShown={isMobileMenuOpened}>
<CloseIcon onClick={hideMobileMenu} />
{navItems}
<SearchBox />
</MobileMenu>
</NavWrapper>
);
}

const NavItem = styled.li`
padding: 10px 0;
`;

const NavWrapper = styled.nav<{ scrolled: boolean }>`
padding: 15px 20px;
display: flex;
position: sticky;
z-index: 50;
transition: all 0.25s ease;
background-color: #227a88;
@media only screen and (min-width: ${({ theme }) => theme.breakpoints.large}) {
padding: 10px 15px;
box-shadow: ${({ scrolled }) => (scrolled ? '0px 1px 0px 0px rgba(225,225,225,0.2)' : 'none')};
top: 0;
left: 0;
right: 0;
}
`;

const NavItems = styled.ul`
display: none;
margin: 0 0 0 40px;
padding: 0;
align-items: center;
justify-content: start;
& li {
list-style: none;
margin-right: 20px;
& a {
color: #ffffff;
text-decoration: none;
}
}
@media only screen and (min-width: ${({ theme }) => theme.breakpoints.medium}) {
display: flex;
}
`;

export const MobileMenu = styled.ul<{ isShown: boolean }>`
background: ${props => props.theme.colors.primary.main};
list-style: none;
padding: 50px 40px;
margin: 0;
position: absolute;
border-top: 1px solid transparent;
z-index: 100;
color: ${props => props.theme.colors.primary.contrastText};
top: 0;
right: 0;
left: 0;
bottom: 0;
font-size: 1.1875rem;
box-shadow: 0px 10px 100px 0px rgba(35, 35, 35, 0.1);
text-align: left;
display: none;
@media only screen and (max-width: ${({ theme }) => theme.breakpoints.medium}) {
position: fixed;
display: ${props => (props.isShown ? 'flex' : 'none')};
flex-direction: column;
overflow-y: auto;
}
& li {
list-style: none;
margin-right: 20px;
& a {
color: #ffffff;
text-decoration: none;
}
}
`;

export const NavControls = styled.div`
padding: 10px;
display: flex;
align-items: center;
flex: 1;
justify-content: flex-end;
@media only screen and (min-width: ${({ theme }) => theme.breakpoints.medium}) {
display: none;
}
`;

export const MobileMenuIcon = styled.span`
width: 1.25em;
height: 1.25em;
display: inline-block;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' x='0' y='0' viewBox='0 0 396.7 396.7' xml:space='preserve'%3E%3Cpath fill='white' d='M17 87.8h362.7c9.4 0 17-7.6 17-17s-7.6-17-17-17H17c-9.3 0-17 7.7-17 17C0 80.2 7.7 87.8 17 87.8zM17 215.3h362.7c9.4 0 17-7.6 17-17s-7.6-17-17-17H17c-9.3 0-17 7.7-17 17S7.7 215.3 17 215.3zM17 342.8h362.7c9.4 0 17-7.6 17-17s-7.6-17-17-17H17c-9.3 0-17 7.7-17 17S7.7 342.8 17 342.8z'/%3E%3C/svg%3E");
cursor: pointer;
@media only screen and (min-width: ${({ theme }) => theme.breakpoints.medium}) {
display: none;
}
`;

export const CloseIcon = styled.i`
cursor: pointer;
position: absolute;
right: 20px;
top: 25px;
width: 15px;
height: 15px;
background-repeat: no-repeat;
background-size: 15px 15px;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='0 0 15.6 15.6' enable-background='new 0 0 15.642 15.642'%3E%3Cpath fill-rule='evenodd' fill='white' d='M8.9 7.8l6.5-6.5c0.3-0.3 0.3-0.8 0-1.1 -0.3-0.3-0.8-0.3-1.1 0L7.8 6.8 1.3 0.2c-0.3-0.3-0.8-0.3-1.1 0 -0.3 0.3-0.3 0.8 0 1.1l6.5 6.5L0.2 14.4c-0.3 0.3-0.3 0.8 0 1.1 0.1 0.1 0.3 0.2 0.5 0.2s0.4-0.1 0.5-0.2l6.5-6.5 6.5 6.5c0.1 0.1 0.3 0.2 0.5 0.2 0.2 0 0.4-0.1 0.5-0.2 0.3-0.3 0.3-0.8 0-1.1L8.9 7.8z'/%3E%3C/svg%3E");
`;
Loading

0 comments on commit f84a200

Please sign in to comment.