mirror of
https://github.com/jxnblk/mdx-deck.git
synced 2024-10-26 07:37:23 +03:00
Add components
This commit is contained in:
parent
6c112d0e78
commit
cfe5ff19e9
@ -1,17 +1,6 @@
|
||||
|
||||
# @mdx-deck/gatsby-plugin
|
||||
|
||||
Lightweight alternative to core mdx-deck
|
||||
Plugin used internally by mdx-deck core package -- **not intended for standalone usage**
|
||||
|
||||
- ~~No steps~~
|
||||
- No print mode
|
||||
- No export
|
||||
- No layouts
|
||||
|
||||
---
|
||||
|
||||
- [x] presenter styles
|
||||
- [x] overview styles
|
||||
- [x] timer
|
||||
- [x] clock
|
||||
- [ ] local images
|
||||
See [`gatsby-theme-mdx-deck`](https://github.com/jxnblk/mdx-deck/tree/master/packages/gatsby-theme) for custom usage with Gatsby
|
||||
|
@ -3,11 +3,10 @@ const path = require('path')
|
||||
const { createPath, validatePath } = require('gatsby-page-utils')
|
||||
const remarkPlugins = [
|
||||
require('remark-images'),
|
||||
require('remark-unwrap-images'),
|
||||
require('remark-emoji'),
|
||||
]
|
||||
|
||||
const isDir = p => fs.statSync(p).isDirectory()
|
||||
|
||||
exports.onCreateWebpackConfig = ({
|
||||
stage,
|
||||
rules,
|
||||
|
@ -22,6 +22,7 @@
|
||||
"react-helmet": "^5.2.1",
|
||||
"remark-emoji": "^2.0.2",
|
||||
"remark-images": "^1.0.0",
|
||||
"remark-unwrap-images": "^1.0.0",
|
||||
"theme-ui": "^0.3.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -58,8 +58,7 @@ 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>
|
||||
|
||||
// ensure this works
|
||||
const items = React.Children.toArray(list && list.props.children)
|
||||
|
||||
const step = useSteps(items.length)
|
||||
@ -90,3 +89,102 @@ export const Appear = ({
|
||||
)
|
||||
return <React.Fragment>{styled}</React.Fragment>
|
||||
}
|
||||
|
||||
export const Image = ({
|
||||
src,
|
||||
width = '100%',
|
||||
height = '100%',
|
||||
size = 'cover',
|
||||
...props
|
||||
}) =>
|
||||
<div
|
||||
{...props}
|
||||
sx={{
|
||||
width,
|
||||
height,
|
||||
backgroundSize: size,
|
||||
backgroundImage: `url(${src})`,
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
}}
|
||||
/>
|
||||
|
||||
export const Horizontal = ({
|
||||
...props
|
||||
}) => {
|
||||
const children = React.Children.toArray(props.children)
|
||||
console.log(children.length)
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
textAlign: 'center',
|
||||
}}>
|
||||
{children.map((child, i) => (
|
||||
<div
|
||||
key={child.key}
|
||||
sx={{
|
||||
width: 100 / children.length + '%',
|
||||
img: {
|
||||
height: 'auto',
|
||||
}
|
||||
}}>
|
||||
{child}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Half = props => <div {...props} sx={{
|
||||
width: '50%',
|
||||
img: {
|
||||
height: 'auto',
|
||||
}
|
||||
}} />
|
||||
|
||||
export const Split = ({ reverse, ...props }) => {
|
||||
const [first, ...rest] = React.Children.toArray(props.children)
|
||||
const children = reverse
|
||||
? [ <Half key='rest'>{rest}</Half>, <Half key='first'>{first}</Half> ]
|
||||
: [ <Half key='first'>{first}</Half>, <Half key='rest'>{rest}</Half> ]
|
||||
|
||||
return (
|
||||
<div
|
||||
{...props}
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
textAlign: 'center',
|
||||
}}>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const SplitRight = props =>
|
||||
<Split
|
||||
{...props}
|
||||
reverse={true}
|
||||
/>
|
||||
|
||||
export const FullScreenCode = ({ ...props }) => (
|
||||
<div
|
||||
{...props}
|
||||
sx={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
pre: {
|
||||
// hack for prism styles
|
||||
margin: '0 !important',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
overflow: 'auto',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
@ -115,7 +115,6 @@ const Presenter = props => {
|
||||
}
|
||||
|
||||
const Overview = props => {
|
||||
const context = useDeck()
|
||||
const ref = React.useRef(null)
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -145,9 +144,9 @@ const Overview = props => {
|
||||
role='button'
|
||||
title={`Go to slide ${i}`}
|
||||
onClick={e => {
|
||||
context.setIndex(i)
|
||||
context.setStep(0)
|
||||
context.setSteps(0)
|
||||
props.setIndex(i)
|
||||
props.setStep(0)
|
||||
props.setSteps(0)
|
||||
}}
|
||||
sx={{
|
||||
p: 2,
|
||||
@ -183,6 +182,72 @@ const Overview = props => {
|
||||
)
|
||||
}
|
||||
|
||||
const Grid = props => {
|
||||
const ref = React.useRef(null)
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!ref.current) return
|
||||
if (typeof ref.current.scrollIntoViewIfNeeded !== 'function') return
|
||||
ref.current.scrollIntoViewIfNeeded()
|
||||
}, [ref.current])
|
||||
|
||||
return (
|
||||
<div
|
||||
sx={{
|
||||
minHeight: '100vh',
|
||||
bg: 'backdrop',
|
||||
}}>
|
||||
<div
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
flexWrap: 'wrap',
|
||||
}}>
|
||||
{props.slides.map((slide, i) => (
|
||||
<div
|
||||
key={i}
|
||||
ref={i === props.index ? ref : null}
|
||||
role='button'
|
||||
title={`Go to slide ${i}`}
|
||||
onClick={e => {
|
||||
props.setIndex(i)
|
||||
props.setStep(0)
|
||||
props.setSteps(0)
|
||||
props.setMode(modes.default)
|
||||
}}
|
||||
sx={{
|
||||
p: 2,
|
||||
width: '25%',
|
||||
height: '23vh',
|
||||
}}>
|
||||
<Slide
|
||||
sx={{
|
||||
outline: props.index === i ? '2px solid cyan' : null,
|
||||
}}
|
||||
zoom={1/4}>
|
||||
{slide}
|
||||
</Slide>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const Print = props => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{props.slides.map((slide, i) => (
|
||||
<Main key={i} preview>
|
||||
<Slide>
|
||||
{slide}
|
||||
</Slide>
|
||||
</Main>
|
||||
))}
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
|
||||
export default props => {
|
||||
const context = useDeck()
|
||||
|
||||
@ -191,6 +256,10 @@ export default props => {
|
||||
return <Presenter {...props} {...context} />
|
||||
case modes.overview:
|
||||
return <Overview {...props} {...context} />
|
||||
case modes.grid:
|
||||
return <Grid {...props} {...context} />
|
||||
case modes.print:
|
||||
return <Print {...props} {...context} />
|
||||
case modes.default:
|
||||
default:
|
||||
return <Main {...props} {...context} />
|
||||
|
@ -50,6 +50,8 @@ export default props => {
|
||||
setMode,
|
||||
toggleMode,
|
||||
notes: slide.notes,
|
||||
header: slides.header,
|
||||
footer: slides.footer,
|
||||
step,
|
||||
setStep,
|
||||
steps,
|
||||
@ -77,11 +79,18 @@ export default props => {
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
if (props.location.pathname === '/print') return
|
||||
props.navigate('/' + index, {
|
||||
replace: true,
|
||||
})
|
||||
}, [index])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (props.location.pathname === '/print') {
|
||||
setMode(modes.print)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const theme = merge(baseTheme, props.theme || {})
|
||||
|
||||
return (
|
||||
|
@ -6,6 +6,7 @@ export default props =>
|
||||
{...props}
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
zIndex: 1,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
|
@ -6,6 +6,7 @@ export default props =>
|
||||
{...props}
|
||||
sx={{
|
||||
position: 'absolute',
|
||||
zIndex: 1,
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
|
@ -18,8 +18,4 @@ export const wrapPageElement = ({ element, props }) =>
|
||||
{element}
|
||||
</Page>
|
||||
|
||||
export {
|
||||
Notes,
|
||||
Head,
|
||||
} from './components'
|
||||
export { useDeck } from './context'
|
||||
|
@ -14,12 +14,20 @@ export const useKeyboard = () => {
|
||||
switch (e.key) {
|
||||
case 'P':
|
||||
case 'p':
|
||||
context.toggleMode(modes.presenter)
|
||||
if (e.shiftKey) {
|
||||
context.toggleMode(modes.print)
|
||||
} else {
|
||||
context.toggleMode(modes.presenter)
|
||||
}
|
||||
break
|
||||
case 'O':
|
||||
case 'o':
|
||||
context.toggleMode(modes.overview)
|
||||
break
|
||||
case 'G':
|
||||
case 'g':
|
||||
context.toggleMode(modes.grid)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -2,4 +2,6 @@ export default {
|
||||
default: 'default',
|
||||
presenter: 'presenter',
|
||||
overview: 'overview',
|
||||
grid: 'grid',
|
||||
print: 'print',
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import { useDeck } from './context'
|
||||
|
||||
const keys = {
|
||||
slide: 'mdx-deck-slide',
|
||||
step: 'mdx-deck-step',
|
||||
}
|
||||
|
||||
export const useStorage = () => {
|
||||
@ -15,8 +16,14 @@ export const useStorage = () => {
|
||||
const handleStorageChange = e => {
|
||||
const n = parseInt(e.newValue, 10)
|
||||
if (isNaN(n)) return
|
||||
if (e.key !== keys.slide) return
|
||||
context.setIndex(n)
|
||||
switch (e.key) {
|
||||
case keys.slide:
|
||||
context.setIndex(n)
|
||||
break
|
||||
case keys.step:
|
||||
context.setStep(n)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
|
@ -11,11 +11,18 @@ export default {
|
||||
},
|
||||
img: {
|
||||
width: '100vw',
|
||||
maxWidth: '100%',
|
||||
height: '100vh',
|
||||
objectFit: 'contain',
|
||||
},
|
||||
Slide: {
|
||||
fontSize: '2em',
|
||||
},
|
||||
Header: {
|
||||
px: 3,
|
||||
},
|
||||
Footer: {
|
||||
px: 3,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ export const useSteps = length => {
|
||||
if (!context.main) return
|
||||
context.setSteps(length)
|
||||
if (context.direction < 0) context.setStep(length)
|
||||
}, [length])
|
||||
}, [length, context])
|
||||
|
||||
if (!context.main) return length
|
||||
return context.step
|
||||
|
@ -3,11 +3,30 @@
|
||||
<title>Hello</title>
|
||||
</Head>
|
||||
|
||||
<Header>
|
||||
|
||||
MDX Deck v4
|
||||
|
||||
</Header>
|
||||
|
||||
# Hello
|
||||
|
||||
<Notes>
|
||||
|
||||
## To do
|
||||
|
||||
- [x] Print mode
|
||||
- [x] Grid mode
|
||||
- [ ] Deprecate layouts/docs??
|
||||
- [ ] Clean up docs/readme
|
||||
- [ ] Clean up demo
|
||||
- [ ] Changelog
|
||||
|
||||
</Notes>
|
||||
|
||||
---
|
||||
|
||||
## This is MDX Deck v3
|
||||
## This is MDX Deck v4
|
||||
|
||||
MDX-based presentation decks
|
||||
|
||||
@ -19,20 +38,16 @@ These are top-secret speaker notes. Shhhh!
|
||||
|
||||
---
|
||||
|
||||
## Nice to meet you
|
||||
|
||||
---
|
||||
|
||||
### What's New
|
||||
|
||||
<ul>
|
||||
<li>Built with Gatsby</li>
|
||||
<Appear>
|
||||
<li>Gatsby Theme</li>
|
||||
<li>Component Shadowing</li>
|
||||
<li>Theme UI</li>
|
||||
</Appear>
|
||||
</ul>
|
||||
<StepList>
|
||||
|
||||
- Persistent headers and footers
|
||||
- Simplified implementation
|
||||
- Simplified API
|
||||
- Refactored internals & bug fixes
|
||||
|
||||
</StepList>
|
||||
|
||||
---
|
||||
|
||||
@ -82,20 +97,6 @@ This one is inverted
|
||||
|
||||
---
|
||||
|
||||
<FullScreenCode>
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
|
||||
export default props =>
|
||||
<div>
|
||||
This is a full-screen code block
|
||||
</div>
|
||||
```
|
||||
|
||||
</FullScreenCode>
|
||||
|
||||
---
|
||||
|
||||
<Split>
|
||||
|
||||
@ -132,3 +133,27 @@ This one is split the other way around
|
||||
## Get Started :sunglasses:
|
||||
|
||||
[GitHub](https://github.com/jxnblk/mdx-deck)
|
||||
|
||||
---
|
||||
|
||||
What
|
||||
|
||||
---
|
||||
|
||||
Happens
|
||||
|
||||
---
|
||||
|
||||
When
|
||||
|
||||
---
|
||||
|
||||
You
|
||||
|
||||
---
|
||||
|
||||
Add
|
||||
|
||||
---
|
||||
|
||||
A whole bunch more slides?
|
||||
|
Loading…
Reference in New Issue
Block a user