1
1
mirror of https://github.com/jxnblk/mdx-deck.git synced 2024-09-17 18:07:43 +03:00

Add swipe support

This commit is contained in:
Brent Jackson 2019-07-09 12:39:58 -04:00
parent 3f4b64814a
commit 68cbdbbb70
10 changed files with 138 additions and 51 deletions

View File

@ -21,30 +21,38 @@ Prototype for MDX Deck v3
- [x] Print
- [x] add legacy theme transformer
- [x] export theme/themes API
- [-] slide styles
- [-] theme-ui
- [x] theme-ui
- [x] react helmet
- [x] custom Head component
- [x] remove Head in slides parser
- [x] Use deck title in default head
- [x] single deck mode
- [x] Index page
- [x] swipe handlers
- [-] slide styles
- [ ] default theme
- [ ] Embed component
- [ ] Print styles
CLI
- [ ] mdx-deck CLI
- [ ] develop
- [ ] build
- [ ] eject
- [ ] single or multiple decks
- [ ] swipe handlers
- [ ] Embed component
- [x] Index page
Other Packages
- [ ] port default themes over
- [ ] update layouts for theme-ui
- [ ] update create-deck
- [ ] shim for @mdx-deck/components
- [ ] export PDF (general Gatsby usage?)
Additional
Additional things for consideration
- [ ] Aspect Ratio/scale mode
- [ ] custom remark plugins
- [ ] Slide/route transitions
- [ ] Open issue for static slide rendering (mdxs)

View File

@ -27,6 +27,7 @@
"lodash.merge": "^4.6.1",
"mkdirp": "^0.5.1",
"react-helmet": "^6.0.0-beta",
"react-swipeable": "^5.3.0",
"theme-ui": "^0.2.10"
}
}

View File

@ -93,7 +93,14 @@ export default ({
</Helmet>
<Context.Provider value={context}>
<ThemeProvider {...legacyTheme}>
<Global styles={{ body: { margin: 0 } }} />
<Global
styles={{
body: {
margin: 0,
overflow: context.mode === modes.normal ? 'hidden' : null,
},
}}
/>
<Keyboard />
<Storage />
<Wrapper>

View File

@ -2,17 +2,21 @@
import { jsx } from 'theme-ui'
import Context from '../context'
import useDeck from '../hooks/use-deck'
import useSwipe from '../hooks/use-swipe'
export const Slide = ({ slide, index, preview, ...props }) => {
const outer = useDeck()
const swipeProps = useSwipe()
const context = {
...outer,
index,
preview,
}
return (
<Context.Provider value={context}>
<div
{...(!preview ? swipeProps : {})}
sx={{
width: '100%',
height: '100%',

View File

@ -1,16 +1,42 @@
/** @jsx jsx */
import { jsx } from 'theme-ui'
import { useState, useEffect } from 'react'
import useDeck from '../hooks/use-deck'
import { modes } from '../constants'
export default props => (
<div
{...props}
sx={{
width: '100vw',
height: '100vh',
variant: 'styles.root',
'*': {
boxSizing: 'border-box',
},
}}
/>
)
export default props => {
const [height, setHeight] = useState('100vh')
const { mode } = useDeck()
useEffect(() => {
// handle mobile safari height
setHeight(window.innerHeight)
const handleResize = e => {
setHeight(window.innerHeight)
}
const stopTouch = e => {
if (mode !== modes.normal) return
e.preventDefault()
}
window.addEventListener('resize', handleResize)
document.body.addEventListener('touchstart', stopTouch)
return () => {
window.removeEventListener('resize', handleResize)
document.body.removeEventListener('touchstart', stopTouch)
}
}, [mode])
return (
<div
{...props}
sx={{
width: '100vw',
height,
variant: 'styles.root',
'*': {
boxSizing: 'border-box',
},
}}
/>
)
}

View File

@ -11,7 +11,7 @@ export default {
body: 'system-ui, sans-serif',
heading: 'system-ui, sans-serif',
monospace: '"Roboto Mono", Menlo, monospace',
ui: 'serif, system-ui, sans-serif',
ui: 'system-ui, sans-serif',
},
lineHeights: {
body: 1.5,

View File

@ -3,6 +3,7 @@ import { useEffect } from 'react'
import { navigate } from '@reach/router'
import useDeck from './use-deck'
import { modes } from '../constants'
import { previous, next } from '../navigate'
const keys = {
right: 39,
@ -16,35 +17,6 @@ const keys = {
pageDown: 34,
}
const nextSlide = ({ slug, length, index, setState }) => {
const n = index + 1
if (n >= length) return
navigate([slug, n].join('/'))
setState({ step: 0 })
}
const next = context => {
const { steps, step, setState } = context
if (!steps || step >= steps) return nextSlide(context)
setState({ step: step + 1 })
}
const previousSlide = ({ slug, index, metadata, setState }) => {
const n = index - 1
if (n < 0) return
navigate([slug, n].join('/'))
const { steps = 0 } = metadata[n] || {}
setState({ step: steps })
}
const previous = context => {
const { steps, step, setState } = context
if (steps && step > 0) {
return setState({ step: step - 1 })
}
previousSlide(context)
}
const toggleMode = next => state =>
state.mode === next
? {

View File

@ -0,0 +1,38 @@
import { useSwipeable } from 'react-swipeable'
import useDeck from './use-deck'
import { previous, next } from '../navigate'
import { modes } from '../constants'
const toggleMode = next => state =>
state.mode === next ? { mode: modes.normal } : { mode: next }
export const useSwipe = () => {
const context = useDeck()
const onSwipedLeft = e => {
next(context)
}
const onSwipedRight = e => {
previous(context)
}
const onSwipedUp = e => {
context.setState({ mode: modes.presenter })
}
const onSwipedDown = e => {
context.setState({ mode: modes.normal })
}
const props = useSwipeable({
onSwipedLeft,
onSwipedRight,
onSwipedUp,
onSwipedDown,
})
return props
}
export default useSwipe

View File

@ -0,0 +1,31 @@
// utilities for navigation
import { navigate } from '@reach/router'
const nextSlide = ({ slug, length, index, setState }) => {
const n = index + 1
if (n >= length) return
navigate([slug, n].join('/'))
setState({ step: 0 })
}
export const next = context => {
const { steps, step, setState } = context
if (!steps || step >= steps) return nextSlide(context)
setState({ step: step + 1 })
}
const previousSlide = ({ slug, index, metadata, setState }) => {
const n = index - 1
if (n < 0) return
navigate([slug, n].join('/'))
const { steps = 0 } = metadata[n] || {}
setState({ step: steps })
}
export const previous = context => {
const { steps, step, setState } = context
if (steps && step > 0) {
return setState({ step: step - 1 })
}
previousSlide(context)
}

View File

@ -12548,7 +12548,7 @@ react-side-effect@^1.1.0:
exenv "^1.2.1"
shallowequal "^1.0.1"
react-swipeable@^5.0.1:
react-swipeable@^5.0.1, react-swipeable@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/react-swipeable/-/react-swipeable-5.3.0.tgz#861bcecab2d5ff462e5737b1a20da2bfe35d8b21"
integrity sha512-mOfRfPxbcfl0jC/3DHSYWRkTElr8aU+ZVc4qv+VOhOQfw8+UM7Mhlky+1YhpRQ/5F9NRR36NZHhHP0kC1yEjGQ==