1
1
mirror of https://github.com/jxnblk/mdx-deck.git synced 2024-09-20 11:27:14 +03:00

Merge branch 'master' into v2-prototype

This commit is contained in:
Brent Jackson 2019-02-18 17:10:46 -05:00
commit 4ce6202476
15 changed files with 164 additions and 118 deletions

View File

@ -13,6 +13,16 @@
- Removed `notes` language attribute for fenced code blocks
- Refactored dev server
## v1.9.0 2019-02-18
- Fix for font size in nested lists #204
- Add `--hot-port` option to CLI #206
- Add support for `.jsx` file extensions #239
- Fix typos in syntax highlighting component #250
- Add context to grid view #187
- Add `--no-sandbox` option to CLI #200
- Surface compilation errors from webpack #252
## v1.8.2 2018-12-04
- Bugfix for window check

View File

@ -33,17 +33,23 @@ Create an [MDX][] file and separate each slide with `---`.
````mdx
# This is the title of my deck
---
# About Me
---
```jsx
<CodeSnippet />
```
---
import Demo from './components/Demo'
<Demo />
---
## <Demo />
# The end
````
@ -71,14 +77,14 @@ npm start
- [Build a Custom Provider Component for MDX-Deck](ks-egghead) by [Kyle Shevlin][]
[egghead]: https://egghead.io/lessons/react-build-a-slide-deck-with-mdx-deck-using-markdown-react
[Kent C. Dodds]: https://mobile.twitter.com/kentcdodds
[kent c. dodds]: https://mobile.twitter.com/kentcdodds
[kcd-video]: http://youtu.be/d2sQiI5NFAM?a
[kcd-medium]: https://blog.kentcdodds.com/mdx-deck-slide-decks-powered-by-markdown-and-react-bfc6d6af20da
[hw-video]: https://www.youtube.com/watch?v=LvP2EqCiQMg&feature=youtu.be
[hw-demo]: https://github.com/hswolff/mdx-deck-demo
[Harry Wolff]: https://mobile.twitter.com/hswolff
[harry wolff]: https://mobile.twitter.com/hswolff
[ks-egghead]: https://egghead.io/lessons/javascript-build-a-custom-provider-component-for-mdx-deck
[Kyle Shevlin]: https://twitter.com/kyleshevlin
[kyle shevlin]: https://twitter.com/kyleshevlin
## Quick Start
@ -99,12 +105,10 @@ To import components, use ES import syntax separated with empty lines from any m
```mdx
import { Box } from 'grid-styled'
<Box color='tomato'>
Hello
</Box>
<Box color="tomato">Hello</Box>
```
Read more about MDX syntax in the [MDX Docs][MDX].
Read more about MDX syntax in the [MDX Docs][mdx].
## Theming
@ -157,7 +161,7 @@ export default {
text: '#f0f',
background: 'black',
link: '#0ff',
}
},
}
```
@ -195,7 +199,7 @@ export default ({ children }) => (
style={{
width: '100vw',
height: '100vw',
backgroundColor: 'tomato'
backgroundColor: 'tomato',
}}>
{children}
</div>
@ -208,6 +212,7 @@ import Layout from './Layout'
# No Layout
---
export default Layout
# Custom Layout
@ -229,7 +234,7 @@ mdx-deck includes a built-in presenter mode, with a preview of the next slide an
To use presenter mode:
- Open two windows in the same browser, with the same URL on two different screens. (this should work in both development and exported presentations)
- In your window, press the `Option/Alt + P` keys to enter presenter mode.
- In your window, press the `Option/Alt + P` keys (or add `?mode=presenter` to the URL) to enter presenter mode.
- Display the other window on the screen for the audience to see.
- Control the presentation from your window by using the left and right arrow keys; the other window should stay in sync
@ -255,32 +260,30 @@ import { Notes } from 'mdx-deck'
# Slide Content
<Notes>
Only visible in presenter mode
</Notes>
<Notes>Only visible in presenter mode</Notes>
```
## Overview Mode
![Overview Mode](docs/images/overview-mode.png)
When editing a slide deck, toggle overview mode with `Option + O`.
When editing a slide deck, toggle overview mode with `Option + O` or add `?mode=overview` to the URL.
This shows a list of all slides on the left and a preview of the current slide on the right.
## Keyboard Shortcuts
Key | Description
----------- | -----------
Left Arrow | Go to previous slide (or step in [Appear][])
Right Arrow | Go to next slide (or step in [Appear][])
Space | Go to next slide (or step in [Appear][])
Up Arrow | Hide current step in [Appear][] component without navigating slides
Down Arrow | Show next step in [Appear][] component without navigating slides
Option + P | Toggle [Presenter Mode](#presenter-mode)
Option + O | Toggle [Overview Mode](#overview-mode)
Option + G | Toggle grid view mode
| Key | Description |
| ----------- | ------------------------------------------------------------------- |
| Left Arrow | Go to previous slide (or step in [Appear][]) |
| Right Arrow | Go to next slide (or step in [Appear][]) |
| Space | Go to next slide (or step in [Appear][]) |
| Up Arrow | Hide current step in [Appear][] component without navigating slides |
| Down Arrow | Show next step in [Appear][] component without navigating slides |
| Option + P | Toggle [Presenter Mode](#presenter-mode) |
| Option + O | Toggle [Overview Mode](#overview-mode) |
| Option + G | Toggle grid view mode |
[Appear]: docs/components.md#appear
[appear]: docs/components.md#appear
## Exporting
@ -298,6 +301,7 @@ See more exporting options in the [Exporting Documentation](docs/exporting.md)
```
-p --port Dev server port
--hot-port Dev server hot reload port
-h --host Host the dev server listens to
--no-open Prevent from opening in default browser
-d --out-dir Output directory for exporting
@ -340,12 +344,12 @@ See more exporting options in the [Exporting Documentation](docs/exporting.md)
[MIT License](LICENSE.md)
[MDX]: https://github.com/mdx-js/mdx
[mdx]: https://github.com/mdx-js/mdx
[ok-mdx]: https://github.com/jxnblk/ok-mdx
[Compositor x0]: https://github.com/c8r/x0
[compositor x0]: https://github.com/c8r/x0
[styled-system]: https://github.com/jxnblk/styled-system
[styled-components]: https://github.com/styled-components/styled-components
[Spectacle]: https://github.com/FormidableLabs/spectacle
[spectacle]: https://github.com/FormidableLabs/spectacle
[mdx-go]: https://github.com/jxnblk/mdx-go
<!-- examples -->

1
cli.js
View File

@ -29,6 +29,7 @@ const cli = meow(
-h --host Dev server host
-p --port Dev server port
--hot-port Dev server hot reload port
--no-open Prevent from opening in default browser
${chalk.gray('Build options')}

View File

@ -21,6 +21,12 @@ const build = async (opts = {}) => {
reject(err)
return
}
if (stats.compilation.errors && stats.compilation.errors.length) {
reject(stats.compilation.errors)
return
}
resolve(stats)
})
})

View File

@ -22,7 +22,7 @@ const babel = {
const rules = [
{
test: /\.js$/,
test: /\.jsx?$/,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
options: babel,
@ -59,6 +59,7 @@ const baseConfig = {
rules,
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'mdx-deck': path.resolve(__dirname, '..'),
'webpack-hot-middleware/client': path.resolve(
@ -100,14 +101,6 @@ const createConfig = (opts = {}) => {
new HTMLPlugin({ context: opts })
)
// if (config.resolve.alias) {
// const hotAlias = config.resolve.alias['webpack-hot-client/client']
// if (!fs.existsSync(hotAlias)) {
// const hotPath = path.dirname(require.resolve('webpack-hot-client/client'))
// config.resolve.alias['webpack-hot-client/client'] = hotPath
// }
// }
return config
}

66
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "mdx-deck",
"version": "1.8.2",
"version": "1.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -874,10 +874,37 @@
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000938.tgz",
"integrity": "sha512-ekW8NQ3/FvokviDxhdKLZZAx7PptXNwxKgXtnR5y+PR3hckwuP3yJ1Ir+4/c97dsHNqtAyfKUGdw8P4EYzBNgw=="
},
"electron-to-chromium": {
"version": "1.3.113",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz",
"integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g=="
"globals": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz",
"integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw=="
},
"is-extglob": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
"integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"optional": true
},
"is-glob": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
"integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"requires": {
"is-extglob": "^1.0.0"
}
},
"kind-of": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
}
}
},
@ -900,14 +927,6 @@
"dev": true,
"requires": {
"regenerator-runtime": "^0.12.0"
},
"dependencies": {
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==",
"dev": true
}
}
},
"@babel/template": {
@ -944,11 +963,6 @@
"ms": "^2.1.1"
}
},
"globals": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz",
"integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw=="
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
@ -3435,6 +3449,11 @@
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"electron-to-chromium": {
"version": "1.3.113",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.113.tgz",
"integrity": "sha512-De+lPAxEcpxvqPTyZAXELNpRZXABRxf+uL/rSykstQhzj/B0l1150G/ExIIxKc16lI89Hgz81J0BHAcbTqK49g=="
},
"elegant-spinner": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
@ -4752,6 +4771,11 @@
"which": "^1.3.1"
}
},
"globals": {
"version": "11.11.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz",
"integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw=="
},
"globby": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
@ -8605,6 +8629,12 @@
"regenerate": "^1.4.0"
}
},
"regenerator-runtime": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
"integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==",
"dev": true
},
"regex-not": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "mdx-deck",
"version": "1.8.2",
"version": "1.9.0",
"description": "MDX-based presentation decks",
"main": "src/index.js",
"bin": {

View File

@ -10,7 +10,7 @@ const Button = styled.button(
fontSize: '12px',
fontWeight: 'bold',
borderRadius: '4px',
border: 'none'
border: 'none',
},
space,
color
@ -18,7 +18,7 @@ const Button = styled.button(
Button.propTypes = {
...space.propTypes,
...color.propTypes
...color.propTypes,
}
Button.defaultProps = {
@ -26,7 +26,7 @@ Button.defaultProps = {
px: 2,
py: 1,
color: 'white',
bg: '#333'
bg: '#333',
}
export default Button

View File

@ -31,14 +31,14 @@ export const Presenter = ({
bg="black"
css={{
flexDirection: 'column',
height: '100vh'
height: '100vh',
}}>
<Flex my="auto">
<Box
mx="auto"
width={5 / 8}
css={{
border: '1px solid rgba(128, 128, 128, 0.25)'
border: '1px solid rgba(128, 128, 128, 0.25)',
}}>
<Zoom zoom={5 / 8}>
<Root {...props}>{props.children}</Root>
@ -49,12 +49,12 @@ export const Presenter = ({
mx="auto"
css={{
flex: 'none',
flexDirection: 'column'
flexDirection: 'column',
}}>
<Box
mx="auto"
css={{
border: '1px solid rgba(128, 128, 128, 0.25)'
border: '1px solid rgba(128, 128, 128, 0.25)',
}}>
<Zoom zoom={1 / 4}>
<Root {...props}>
@ -69,7 +69,7 @@ export const Presenter = ({
<Box
py={3}
css={{
flex: 'auto'
flex: 'auto',
}}>
{notes}
</Box>
@ -100,7 +100,7 @@ Presenter.propTypes = {
step: PropTypes.number.isRequired,
slides: PropTypes.array,
mode: PropTypes.string,
metadata: PropTypes.object
metadata: PropTypes.object,
}
export default Presenter

View File

@ -27,12 +27,7 @@ import {
incrementStep,
toggleMode,
} from './updaters'
import {
modes,
keys,
MDX_SLIDE_INDEX,
MDX_SLIDE_STEP,
} from './constants'
import { modes, keys, MDX_SLIDE_INDEX, MDX_SLIDE_STEP } from './constants'
export class SlideDeck extends React.Component {
static propTypes = {
@ -49,7 +44,7 @@ export class SlideDeck extends React.Component {
static defaultProps = {
slides: [],
theme: defaultTheme,
components: {} ,
components: {},
Provider: DefaultProvider,
width: '100vw',
height: '100vh',
@ -63,14 +58,16 @@ export class SlideDeck extends React.Component {
mode: modes.normal,
// contextual metadata for slides
metadata: {},
step: 0
step: 0,
}
update = fn => this.setState(fn)
handleKeyDown = e => {
if (document.activeElement.tagName !== 'BODY'
|| this.props.ignoreKeyEvents) {
if (
document.activeElement.tagName !== 'BODY' ||
this.props.ignoreKeyEvents
) {
return
}
@ -142,9 +139,11 @@ export class SlideDeck extends React.Component {
}
getMode = () => {
const { mode } = querystring.parse(window.location.search.replace(/^\?/, ''))
const { mode } = querystring.parse(
window.location.search.replace(/^\?/, '')
)
this.setState({
mode: modes[mode] || modes.normal
mode: modes[mode] || modes.normal,
})
}
@ -160,7 +159,7 @@ export class SlideDeck extends React.Component {
}
}
componentDidMount () {
componentDidMount() {
document.body.addEventListener('keydown', this.handleKeyDown)
window.addEventListener('hashchange', this.handleHashChange)
window.addEventListener('storage', this.handleStorageChange)
@ -168,13 +167,13 @@ export class SlideDeck extends React.Component {
this.getMode()
}
componentWillUnmount () {
componentWillUnmount() {
document.body.removeEventListener('keydown', this.handleKeyDown)
window.removeEventListener('hashchange', this.handleHashChange)
window.removeEventListener('storage', this.handleStorageChange)
}
componentDidUpdate () {
componentDidUpdate() {
if (this.isHashChange) {
this.isHashChange = false
return
@ -186,19 +185,21 @@ export class SlideDeck extends React.Component {
const { index, mode, step } = this.state
let query = ''
if (mode && mode !== modes.normal) {
query += '?' + querystring.stringify({
mode: (mode || '').toLowerCase()
})
query +=
'?' +
querystring.stringify({
mode: (mode || '').toLowerCase(),
})
} else if (mode === modes.normal) {
query += window.location.pathname
}
const step_ = step !== 0 ? ('.' + step) : ''
const step_ = step !== 0 ? '.' + step : ''
history.pushState(null, null, query + '#' + index + step_)
localStorage.setItem(MDX_SLIDE_INDEX, index)
localStorage.setItem(MDX_SLIDE_STEP, step)
}
render () {
render() {
const {
slides,
theme,
@ -206,18 +207,11 @@ export class SlideDeck extends React.Component {
Provider: PropsProvider,
width,
height,
headTags
headTags,
} = this.props
const {
index,
mode,
metadata,
} = this.state
const { index, mode, metadata } = this.state
const {
components = propsComponents,
Provider = PropsProvider
} = theme
const { components = propsComponents, Provider = PropsProvider } = theme
let Wrapper = Root
if (mode === modes.presenter) {
@ -229,7 +223,7 @@ export class SlideDeck extends React.Component {
const context = {
...this.state,
slides,
update: this.update
update: this.update,
}
return (
@ -238,14 +232,11 @@ export class SlideDeck extends React.Component {
<MDXProvider
components={{
...defaultComponents,
...components
...components,
}}>
<Provider {...this.state} update={this.update}>
{mode === modes.grid ? (
<Grid
slides={slides}
update={this.update}
/>
<Grid {...context} slides={slides} update={this.update} />
) : (
<Swipeable
onSwipedLeft={() => this.update(next)}
@ -264,7 +255,7 @@ export class SlideDeck extends React.Component {
id={'slide-' + i}
{...context}
index={i}
className='Slide'
className="Slide"
active={i === index}
metadata={metadata[i]}>
<Component />

View File

@ -8,7 +8,7 @@ class Timer extends React.Component {
state = {
on: false,
time: new Date().toLocaleTimeString(),
seconds: 0
seconds: 0,
}
toggle = () => {
@ -23,7 +23,7 @@ class Timer extends React.Component {
const now = new Date()
this.setState(state => ({
time: now.toLocaleTimeString(),
seconds: state.on ? state.seconds + 1 : state.seconds
seconds: state.on ? state.seconds + 1 : state.seconds,
}))
}
@ -42,12 +42,11 @@ class Timer extends React.Component {
return (
<Flex css={{ alignItems: 'center' }}>
{!on &&
seconds > 0 && (
<Button mr={1} onClick={this.reset}>
reset
</Button>
)}
{!on && seconds > 0 && (
<Button mr={1} onClick={this.reset}>
reset
</Button>
)}
<Button bg={on ? '#600' : '#060'} onClick={this.toggle}>
{on ? 'stop' : 'start'}
</Button>

View File

@ -11,7 +11,7 @@ const FullCode = styled.div([], {
width: '100vw',
height: '100vh',
overflow: 'auto',
}
},
})
export default FullCode

View File

@ -16,6 +16,13 @@ export default {
'@media screen and (min-width:64em)': {
fontSize: '3em',
},
'li > ul, li > ol': {
fontSize: 'inherit',
},
'li > p': {
fontSize: 'inherit',
margin: 0,
},
},
ol: {
textAlign: 'left',

View File

@ -1,7 +1,5 @@
{
"private": true,
"version": "1.0.0",
"description": "Deck created with mdx-deck",
"scripts": {
"start": "mdx-deck deck.mdx",
"build": "mdx-deck build deck.mdx",
@ -9,9 +7,6 @@
"image": "mdx-deck screenshot deck.mdx",
"help": "mdx-deck"
},
"keywords": [],
"author": "Brent Jackson",
"license": "MIT",
"devDependencies": {
"mdx-deck": "^1.6.7"
}

View File

@ -335,6 +335,16 @@ Array [
background-color: white;
}
.c0 li > ul,
.c0 li > ol {
font-size: inherit;
}
.c0 li > p {
font-size: inherit;
margin: 0;
}
@media print {
.c1 {
height: auto;