mirror of
https://github.com/jxnblk/mdx-deck.git
synced 2024-09-20 11:27:14 +03:00
commit
320f366e23
78
packages/components/src/Grid.js
Normal file
78
packages/components/src/Grid.js
Normal file
@ -0,0 +1,78 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { Location, navigate } from '@reach/router'
|
||||
import Zoom from './Zoom'
|
||||
import Slide from './Slide'
|
||||
|
||||
const getIndex = ({ pathname }) => {
|
||||
return Number(pathname.split('/')[1] || 0)
|
||||
}
|
||||
|
||||
const withLocation = Component => props => (
|
||||
<Location
|
||||
children={({ location }) => (
|
||||
<Component {...props} location={location} index={getIndex(location)} />
|
||||
)}
|
||||
/>
|
||||
)
|
||||
|
||||
export const Grid = withLocation(props => {
|
||||
const { index, slides, modes, update } = props
|
||||
const activeThumb = React.createRef()
|
||||
|
||||
useEffect(() => {
|
||||
const el = activeThumb.current
|
||||
if (!el) return
|
||||
if (typeof el.scrollIntoViewIfNeeded === 'function') {
|
||||
el.scrollIntoViewIfNeeded()
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
height: '100vh',
|
||||
overflowY: 'auto',
|
||||
color: 'white',
|
||||
backgroundColor: 'black',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-start',
|
||||
flexWrap: 'wrap',
|
||||
}}
|
||||
>
|
||||
{slides.map((Component, i) => (
|
||||
<div
|
||||
ref={i === index ? activeThumb : null}
|
||||
key={i}
|
||||
role="link"
|
||||
onClick={e => {
|
||||
navigate('/' + i)
|
||||
update({ mode: modes.NORMAL })
|
||||
}}
|
||||
style={{
|
||||
display: 'block',
|
||||
width: '25vw',
|
||||
height: '25vh',
|
||||
padding: '2px',
|
||||
overflow: 'hidden',
|
||||
color: 'inherit',
|
||||
textDecoration: 'none',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
<Zoom zoom={1 / 4}>
|
||||
<Slide>
|
||||
<Component />
|
||||
</Slide>
|
||||
</Zoom>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
export default Grid
|
@ -7,6 +7,7 @@ import Provider from './Provider'
|
||||
import Slide from './Slide'
|
||||
import Presenter from './Presenter'
|
||||
import Overview from './Overview'
|
||||
import Grid from './Grid'
|
||||
import Print from './Print'
|
||||
import GoogleFonts from './GoogleFonts'
|
||||
import Catch from './Catch'
|
||||
@ -14,7 +15,15 @@ import Catch from './Catch'
|
||||
const NORMAL = 'normal'
|
||||
const PRESENTER = 'presenter'
|
||||
const OVERVIEW = 'overview'
|
||||
const GRID = 'grid'
|
||||
const PRINT = 'print'
|
||||
const modes = {
|
||||
NORMAL,
|
||||
PRESENTER,
|
||||
OVERVIEW,
|
||||
GRID,
|
||||
PRINT,
|
||||
}
|
||||
|
||||
const STORAGE_INDEX = 'mdx-slide'
|
||||
const STORAGE_STEP = 'mdx-step'
|
||||
@ -25,6 +34,7 @@ const keys = {
|
||||
space: 32,
|
||||
p: 80,
|
||||
o: 79,
|
||||
g: 71,
|
||||
}
|
||||
|
||||
const toggleMode = key => state => ({
|
||||
@ -43,6 +53,7 @@ export class MDXDeck extends React.Component {
|
||||
slides: props.slides,
|
||||
step: 0,
|
||||
mode: NORMAL,
|
||||
update: fn => this.setState(fn),
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,6 +82,9 @@ export class MDXDeck extends React.Component {
|
||||
case keys.o:
|
||||
this.setState(toggleMode(OVERVIEW))
|
||||
break
|
||||
case keys.g:
|
||||
this.setState(toggleMode(GRID))
|
||||
break
|
||||
}
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
@ -217,13 +231,16 @@ export class MDXDeck extends React.Component {
|
||||
case OVERVIEW:
|
||||
Wrapper = Overview
|
||||
break
|
||||
case GRID:
|
||||
Wrapper = Grid
|
||||
break
|
||||
}
|
||||
|
||||
return (
|
||||
<Provider {...this.props} {...this.state} mode={mode} index={index}>
|
||||
<Catch>
|
||||
<GoogleFonts />
|
||||
<Wrapper {...this.state} index={index}>
|
||||
<Wrapper {...this.state} modes={modes} index={index}>
|
||||
<Swipeable onSwipedRight={this.previous} onSwipedLeft={this.next}>
|
||||
<Router>
|
||||
<Slide path="/" index={0} {...context}>
|
||||
|
@ -52,6 +52,7 @@ export const Overview = withLocation(props => {
|
||||
<div
|
||||
ref={i === index ? activeThumb : null}
|
||||
key={i}
|
||||
role="link"
|
||||
onClick={e => {
|
||||
navigate('/' + i)
|
||||
}}
|
||||
|
@ -3,8 +3,8 @@ import styled from '@emotion/styled'
|
||||
|
||||
const ZoomRoot = styled.div(props => ({
|
||||
backgroundColor: props.theme.colors.background,
|
||||
width: 100 * props.zoom + 'vw',
|
||||
height: 100 * props.zoom + 'vh',
|
||||
width: `calc(${100 * props.zoom}vw)`,
|
||||
height: `calc(${100 * props.zoom}vh)`,
|
||||
}))
|
||||
|
||||
const ZoomInner = styled.div([], props => ({
|
||||
|
Loading…
Reference in New Issue
Block a user