mirror of
https://github.com/jxnblk/mdx-deck.git
synced 2024-10-26 15:49:50 +03:00
Adjust steps implementation and presenter mode
This commit is contained in:
parent
12ac79128a
commit
e87f63c01a
@ -9,7 +9,7 @@
|
||||
"scripts": {
|
||||
"__start": "yarn workspace @mdx-deck/docs start",
|
||||
"start": "yarn workspace @mdx-deck/lite start",
|
||||
"build": "yarn workspace @mdx-deck/docs build",
|
||||
"build": "yarn workspace @mdx-deck/lite build",
|
||||
"export": "./packages/export/cli.js http://localhost:8000/print -o docs/public/deck.pdf",
|
||||
"cypress:open": "cypress open",
|
||||
"cypress:run": "cypress run",
|
||||
|
@ -3,7 +3,15 @@
|
||||
|
||||
Lightweight alternative to core mdx-deck
|
||||
|
||||
- No steps
|
||||
- ~~No steps~~
|
||||
- No print mode
|
||||
- No export
|
||||
- No layouts
|
||||
|
||||
---
|
||||
|
||||
- [ ] presenter styles
|
||||
- [ ] overview styles
|
||||
- [ ] timer
|
||||
- [ ] clock
|
||||
- [ ] local images
|
||||
|
@ -18,6 +18,7 @@
|
||||
"@mdx-js/mdx": "^1.5.3",
|
||||
"gatsby-page-utils": "^0.0.37",
|
||||
"gatsby-plugin-react-helmet": "^3.1.18",
|
||||
"hhmmss": "^1.0.0",
|
||||
"react-helmet": "^5.2.1",
|
||||
"remark-emoji": "^2.0.2",
|
||||
"remark-images": "^1.0.0",
|
||||
|
17
packages/gatsby-plugin/src/clock.js
Normal file
17
packages/gatsby-plugin/src/clock.js
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
|
||||
export default props => {
|
||||
const [time, setTime] = React.useState(new Date().toLocaleTimeString())
|
||||
|
||||
React.useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
const now = new Date()
|
||||
setTime(now.toLocaleTimeString())
|
||||
}, 1000)
|
||||
return () => {
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return time
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
import { jsx } from 'theme-ui'
|
||||
import React from 'react'
|
||||
import useSteps from './use-steps'
|
||||
|
||||
const createComponent = key => {
|
||||
const Component = () => false
|
||||
@ -41,3 +43,50 @@ export const Invert = props =>
|
||||
color='background'
|
||||
bg='text'
|
||||
/>
|
||||
|
||||
export const Counter = ({ length = 4 }) => {
|
||||
const step = useSteps(length)
|
||||
|
||||
return (
|
||||
<pre>
|
||||
{step} / {length}
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
|
||||
export const StepList = props => {
|
||||
const list = React.Children.toArray(props.children)
|
||||
.find(child => /^(ul|ol)$/.test(child.props.originalType))
|
||||
|
||||
// if (!list) return <div>{props.children}</div>
|
||||
|
||||
const items = React.Children.toArray(list && list.props.children)
|
||||
|
||||
const step = useSteps(items.length)
|
||||
|
||||
if (!list) return false
|
||||
|
||||
const children = items.map((item, i) => React.cloneElement(item, {
|
||||
style: {
|
||||
visibility: i < step ? 'visible' : 'hidden'
|
||||
}
|
||||
}))
|
||||
|
||||
return React.cloneElement(list, { children })
|
||||
}
|
||||
|
||||
export const Appear = ({
|
||||
target,
|
||||
...props
|
||||
}) => {
|
||||
const children = React.Children.toArray(props.children)
|
||||
const step = useSteps(children.length)
|
||||
const styled = children.map((child, i) =>
|
||||
React.cloneElement(child, {
|
||||
style: {
|
||||
visibility: i < step ? 'visible' : 'hidden',
|
||||
}
|
||||
})
|
||||
)
|
||||
return <React.Fragment>{styled}</React.Fragment>
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
/** @jsx jsx */
|
||||
import { jsx } from 'theme-ui'
|
||||
import { jsx, Box, Flex } from 'theme-ui'
|
||||
import React from 'react'
|
||||
import { Context, useDeck } from './context'
|
||||
import modes from './modes'
|
||||
import Header from './header'
|
||||
import Footer from './footer'
|
||||
import Slide from './slide'
|
||||
import Clock from './clock'
|
||||
import Timer from './timer'
|
||||
|
||||
const Main = ({
|
||||
width = '100vw',
|
||||
@ -16,7 +18,7 @@ const Main = ({
|
||||
const outer = useDeck()
|
||||
const context = {
|
||||
...outer,
|
||||
isMain: !preview,
|
||||
main: !preview,
|
||||
}
|
||||
|
||||
return (
|
||||
@ -52,42 +54,62 @@ const Presenter = props => {
|
||||
sx={{
|
||||
display: 'flex',
|
||||
height: '100vh',
|
||||
bg: 'backdrop',
|
||||
}}>
|
||||
<div
|
||||
sx={{
|
||||
width: '60%',
|
||||
height: '100vh',
|
||||
padding: 3,
|
||||
}}>
|
||||
<Main
|
||||
{...props}
|
||||
width='100%'
|
||||
height='100vh'>
|
||||
height='100%'>
|
||||
<Slide>
|
||||
{props.slide}
|
||||
</Slide>
|
||||
</Main>
|
||||
</div>
|
||||
<div
|
||||
<Flex
|
||||
sx={{
|
||||
flexDirection: 'column',
|
||||
width: '40%',
|
||||
height: '100vh',
|
||||
padding: 3,
|
||||
py: 3,
|
||||
pr: 3,
|
||||
overflowY: 'auto',
|
||||
outline: '1px solid cyan',
|
||||
}}>
|
||||
<Slide
|
||||
width='100%'
|
||||
height='100vh'
|
||||
zoom={1/2}
|
||||
sx={{
|
||||
outline: '1px solid tomato',
|
||||
}}>
|
||||
{next}
|
||||
</Slide>
|
||||
<div>
|
||||
<div
|
||||
sx={{
|
||||
py: 3,
|
||||
flex: '1 1 auto',
|
||||
}}>
|
||||
{props.notes}
|
||||
</div>
|
||||
</div>
|
||||
<Flex
|
||||
sx={{
|
||||
fontFamily: '"Roboto Mono", Menlo, monospace',
|
||||
}}>
|
||||
<Box>
|
||||
{props.index} / {props.slides.length - 1}
|
||||
</Box>
|
||||
<Box mx='auto' />
|
||||
<Box>
|
||||
<Timer />
|
||||
{' '}
|
||||
<Clock />
|
||||
</Box>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -10,16 +10,6 @@ import Container from './container'
|
||||
import Slide from './slide'
|
||||
import baseTheme from './theme'
|
||||
|
||||
/**
|
||||
* - [ ] presenter styles
|
||||
* - [ ] overview styles
|
||||
* - [ ] timer/clock
|
||||
* - [ ] Ditch layouts?
|
||||
* - [ ] themes
|
||||
* - [ ] base theme
|
||||
* - [ ] test local images
|
||||
*/
|
||||
|
||||
const getIndex = props => {
|
||||
if (!props.location) return 0
|
||||
const paths = props.location.pathname.split('/')
|
||||
@ -29,7 +19,8 @@ const getIndex = props => {
|
||||
|
||||
export default props => {
|
||||
const slides = split(props)
|
||||
const index = getIndex(props)
|
||||
// const index = getIndex(props)
|
||||
const [index, setIndex] = React.useState(getIndex(props))
|
||||
const { slug } = props.pageContext || {}
|
||||
const slide = slides[index]
|
||||
|
||||
@ -45,6 +36,10 @@ export default props => {
|
||||
lastIndex.current = index
|
||||
}, [index])
|
||||
|
||||
// steps
|
||||
const [step, setStep] = React.useState(0)
|
||||
const [steps, setSteps] = React.useState(0)
|
||||
|
||||
const context = {
|
||||
slides,
|
||||
slug,
|
||||
@ -56,23 +51,46 @@ export default props => {
|
||||
setMode,
|
||||
toggleMode,
|
||||
notes: slide.notes,
|
||||
step,
|
||||
setStep,
|
||||
steps,
|
||||
setSteps,
|
||||
}
|
||||
|
||||
/*
|
||||
context.setIndex = fn => {
|
||||
const n = typeof fn === 'function' ? fn(index) : fn
|
||||
props.navigate('/' + n)
|
||||
}
|
||||
*/
|
||||
|
||||
context.previous = () => {
|
||||
context.setIndex(n => n > 0 ? n - 1 : n)
|
||||
if (steps && step > 0) {
|
||||
setStep(n => n - 1)
|
||||
} else {
|
||||
setIndex(n => n > 0 ? n - 1 : n)
|
||||
setStep(0)
|
||||
setSteps(0)
|
||||
}
|
||||
}
|
||||
|
||||
context.next = () => {
|
||||
context.setIndex(n => n < slides.length - 1 ? n + 1 : n)
|
||||
if (step < steps) {
|
||||
setStep(n => n + 1)
|
||||
} else {
|
||||
setIndex(n => n < slides.length - 1 ? n + 1 : n)
|
||||
setStep(0)
|
||||
setSteps(0)
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
props.navigate('/' + index, {
|
||||
replace: true,
|
||||
})
|
||||
}, [index])
|
||||
|
||||
const theme = merge(baseTheme, props.theme || {})
|
||||
console.log(context)
|
||||
// console.log(context)
|
||||
|
||||
return (
|
||||
<Context.Provider value={context}>
|
||||
|
@ -18,6 +18,8 @@ export default ({
|
||||
justifyContent: 'center',
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
color: 'text',
|
||||
bg: 'background',
|
||||
variant: 'styles.Slide',
|
||||
width,
|
||||
height,
|
||||
|
@ -3,6 +3,7 @@ export default {
|
||||
colors: {
|
||||
text: '#fff',
|
||||
background: '#000',
|
||||
backdrop: '#111',
|
||||
},
|
||||
styles: {
|
||||
root: {
|
||||
|
39
packages/gatsby-plugin/src/timer.js
Normal file
39
packages/gatsby-plugin/src/timer.js
Normal file
@ -0,0 +1,39 @@
|
||||
/** @jsx jsx */
|
||||
import { jsx } from 'theme-ui'
|
||||
import React from 'react'
|
||||
import hhmmss from 'hhmmss'
|
||||
|
||||
export default props => {
|
||||
const [seconds, setSeconds] = React.useState(0)
|
||||
const [active, setActive] = React.useState(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
if (!active) return
|
||||
setSeconds(n => n + 1)
|
||||
}, 1000)
|
||||
return () => {
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, [active])
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={e => {
|
||||
setActive(!active)
|
||||
if (active) setSeconds(0)
|
||||
}}
|
||||
title={active ? 'Stop Timer' : 'Start Timer'}
|
||||
sx={{
|
||||
appearance: 'none',
|
||||
fontFamily: '"Roboto Mono", Menlo, monospace',
|
||||
fontSize: 'inherit',
|
||||
color: 'white',
|
||||
bg: 'black',
|
||||
border: 0,
|
||||
padding: 2,
|
||||
}}>
|
||||
{hhmmss(seconds)}
|
||||
</button>
|
||||
)
|
||||
}
|
17
packages/gatsby-plugin/src/use-steps.js
Normal file
17
packages/gatsby-plugin/src/use-steps.js
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
import { useDeck } from './context'
|
||||
|
||||
export const useSteps = length => {
|
||||
const context = useDeck()
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!context.main) return
|
||||
context.setSteps(length)
|
||||
if (context.direction < 0) context.setStep(length)
|
||||
}, [length])
|
||||
|
||||
if (!context.main) return length
|
||||
return context.step
|
||||
}
|
||||
|
||||
export default useSteps
|
@ -21,8 +21,12 @@ These are top-secret speaker notes. Shhhh!
|
||||
|
||||
### What's New
|
||||
|
||||
<StepList>
|
||||
|
||||
- Simplified API
|
||||
- No steps
|
||||
- Refactored internals
|
||||
|
||||
</StepList>
|
||||
|
||||
---
|
||||
|
||||
@ -36,6 +40,10 @@ Stand clear of the closing doors
|
||||
|
||||
---
|
||||
|
||||
<Counter />
|
||||
|
||||
---
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user