-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a29c3cc
commit 3aab2d9
Showing
7 changed files
with
216 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,4 +22,4 @@ | |
<redoc id="example"></redoc> | ||
</body> | ||
|
||
</html> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import * as React from 'react'; | ||
|
||
import styled from '../../styled-components'; | ||
|
||
export const AnimatedChevronButton = ({ open }: { open: boolean }) => { | ||
const iconOffset = open ? 8 : -4; | ||
|
||
return ( | ||
<ChevronContainer> | ||
<ChevronSvg | ||
size={15} | ||
style={{ | ||
transform: `translate(2px, ${iconOffset}px) rotate(180deg)`, | ||
transition: 'transform 0.2s ease', | ||
}} | ||
/> | ||
<ChevronSvg | ||
size={15} | ||
style={{ | ||
transform: `translate(2px, ${0 - iconOffset}px)`, | ||
transition: 'transform 0.2s ease', | ||
}} | ||
/> | ||
</ChevronContainer> | ||
); | ||
}; | ||
|
||
// adapted from reactjs.org | ||
const ChevronSvg = ({ size = 10, className = '', style = {} }) => ( | ||
<svg | ||
className={className} | ||
style={style} | ||
viewBox="0 0 926.23699 573.74994" | ||
version="1.1" | ||
x="0px" | ||
y="0px" | ||
width={size} | ||
height={size} | ||
> | ||
<g transform="translate(904.92214,-879.1482)"> | ||
<path | ||
d={` | ||
m -673.67664,1221.6502 -231.2455,-231.24803 55.6165, | ||
-55.627 c 30.5891,-30.59485 56.1806,-55.627 56.8701,-55.627 0.6894, | ||
0 79.8637,78.60862 175.9427,174.68583 l 174.6892,174.6858 174.6892, | ||
-174.6858 c 96.079,-96.07721 175.253196,-174.68583 175.942696, | ||
-174.68583 0.6895,0 26.281,25.03215 56.8701, | ||
55.627 l 55.6165,55.627 -231.245496,231.24803 c -127.185,127.1864 | ||
-231.5279,231.248 -231.873,231.248 -0.3451,0 -104.688, | ||
-104.0616 -231.873,-231.248 z | ||
`} | ||
fill="currentColor" | ||
/> | ||
</g> | ||
</svg> | ||
); | ||
|
||
const ChevronContainer = styled.div` | ||
user-select: none; | ||
width: 20px; | ||
height: 20px; | ||
align-self: center; | ||
display: flex; | ||
flex-direction: column; | ||
color: ${props => props.theme.colors.main}; | ||
`; |
127 changes: 127 additions & 0 deletions
127
src/components/StickySidebar/StickyResponsiveSidebar.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { observer } from 'mobx-react'; | ||
import * as React from 'react'; | ||
|
||
import { MenuStore } from '../../services/MenuStore'; | ||
import { RedocNormalizedOptions, RedocRawOptions } from '../../services/RedocNormalizedOptions'; | ||
import styled, { media, withProps } from '../../styled-components'; | ||
import { ComponentWithOptions } from '../OptionsProvider'; | ||
import { AnimatedChevronButton } from './ChevronSvg'; | ||
|
||
let Stickyfill; | ||
if (typeof window !== 'undefined') { | ||
Stickyfill = require('stickyfill').default; | ||
} | ||
|
||
export interface StickySidebarProps { | ||
className?: string; | ||
scrollYOffset?: RedocRawOptions['scrollYOffset']; // passed directly or via context | ||
menu: MenuStore; | ||
} | ||
|
||
const stickyfill = Stickyfill && Stickyfill(); | ||
|
||
const StyledStickySidebar = withProps<{ open?: boolean }>(styled.div)` | ||
width: ${props => props.theme.menu.width}; | ||
background-color: ${props => props.theme.menu.backgroundColor}; | ||
overflow: hidden; | ||
display: flex; | ||
flex-direction: column; | ||
transform: translateZ(0); | ||
height: 100vh; | ||
position: sticky; | ||
position: -webkit-sticky; | ||
top: 0; | ||
${media.lessThan('small')` | ||
position: fixed; | ||
z-index: 20; | ||
width: 100%; | ||
background: #ffffff; | ||
display: ${props => (props.open ? 'flex' : 'none')}; | ||
`}; | ||
`; | ||
|
||
const FloatingButton = styled.div` | ||
outline: none; | ||
user-select: none; | ||
background-color: #f2f2f2; | ||
color: ${props => props.theme.colors.main}; | ||
display: none; | ||
cursor: pointer; | ||
position: fixed; | ||
right: 20px; | ||
z-index: 100; | ||
border-radius: 50%; | ||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); | ||
${media.lessThan('small')` | ||
display: flex; | ||
`}; | ||
bottom: 44px; | ||
width: 60px; | ||
height: 60px; | ||
padding: 0 20px; | ||
`; | ||
|
||
@observer | ||
export class StickyResponsiveSidebar extends ComponentWithOptions<StickySidebarProps> { | ||
stickyElement: Element; | ||
|
||
componentDidMount() { | ||
if (stickyfill) { | ||
stickyfill.add(this.stickyElement); | ||
} | ||
} | ||
|
||
componentWillUnmount() { | ||
if (stickyfill) { | ||
stickyfill.remove(this.stickyElement); | ||
} | ||
} | ||
|
||
get scrollYOffset() { | ||
let top; | ||
if (this.props.scrollYOffset !== undefined) { | ||
top = RedocNormalizedOptions.normalizeScrollYOffset(this.props.scrollYOffset)(); | ||
} else { | ||
top = this.options.scrollYOffset(); | ||
} | ||
return top + 'px'; | ||
} | ||
|
||
render() { | ||
const top = this.scrollYOffset; | ||
const open = this.props.menu.sideBarOpened; | ||
|
||
const height = `calc(100vh - ${top})`; | ||
|
||
return ( | ||
<> | ||
<StyledStickySidebar | ||
open={open} | ||
className={this.props.className} | ||
style={{ top, height }} | ||
// tslint:disable-next-line | ||
innerRef={el => { | ||
this.stickyElement = el; | ||
}} | ||
> | ||
{this.props.children} | ||
</StyledStickySidebar> | ||
<FloatingButton onClick={this.toggleNavMenu}> | ||
<AnimatedChevronButton open={open} /> | ||
</FloatingButton> | ||
</> | ||
); | ||
} | ||
|
||
private toggleNavMenu = () => { | ||
this.props.menu.toggleSidebar(); | ||
}; | ||
|
||
// private closeNavMenu = () => { | ||
// this.setState({ open: false }); | ||
// }; | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters