From 3a977caebf0394a34c20e9addc4a1784c853a415 Mon Sep 17 00:00:00 2001 From: Brent Jackson Date: Thu, 2 Aug 2018 20:54:21 -0400 Subject: [PATCH 1/7] Add basic context setup --- docs/index.mdx | 7 ++++- src/Notes.js | 17 ++++++++++++ src/Slide.js | 29 +++++++++++++++++++- src/context.js | 16 +++++++++++ src/index.js | 74 +++++++++++++++++++++++++++++--------------------- 5 files changed, 110 insertions(+), 33 deletions(-) create mode 100644 src/Notes.js create mode 100644 src/context.js diff --git a/docs/index.mdx b/docs/index.mdx index 643fa53..1a6b841 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -1,5 +1,5 @@ export { future as theme } from '../src/themes' -import { Image } from '../src' +import { Image, Notes } from '../src' import Layout from './Layout' # mdx-deck @@ -36,6 +36,11 @@ import Box from 'superbox' ``` ``` + + + Hi this is some notes + + --- > “Blockquotes are essential to any good presentation” diff --git a/src/Notes.js b/src/Notes.js new file mode 100644 index 0000000..044f044 --- /dev/null +++ b/src/Notes.js @@ -0,0 +1,17 @@ +import React from 'react' +import { withDeck } from './context' +import { withSlide } from './Slide' + +export default withDeck(withSlide(class extends React.Component { + componentDidUpdate () { + console.log( + this.props.children, + this.props.slide, + this.props.deck + ) + } + + render () { + return false + } +})) diff --git a/src/Slide.js b/src/Slide.js index ce12ab2..12470ba 100644 --- a/src/Slide.js +++ b/src/Slide.js @@ -1,7 +1,20 @@ +import React from 'react' import styled from 'styled-components' import { space, color } from 'styled-system' -export const Slide = styled.div([], { +const Context = React.createContext(null) + +export const withSlide = Component => props => + + {slide => ( + + )} + + +const Root = styled.div([], { flex: 'none', display: 'flex', alignItems: 'center', @@ -19,6 +32,20 @@ export const Slide = styled.div([], { } }, space, color) +class Slide extends React.Component { + render () { + const { + index, + ...props + } = this.props + return ( + + + + ) + } +} + Slide.defaultProps = { px: [ 4, 5, 6 ] } diff --git a/src/context.js b/src/context.js new file mode 100644 index 0000000..1e14f9e --- /dev/null +++ b/src/context.js @@ -0,0 +1,16 @@ +import React from 'react' + +export const Context = React.createContext(null) +export const { Provider, Consumer } = Context + +export const withDeck = Component => props => + + {deck => ( + + )} + + +export default Context diff --git a/src/index.js b/src/index.js index 6277a9c..e547b4a 100644 --- a/src/index.js +++ b/src/index.js @@ -4,6 +4,7 @@ import { MDXProvider } from '@mdx-js/tag' import { ThemeProvider } from 'styled-components' import debounce from 'lodash.debounce' +import { Provider } from './context' import Carousel from './Carousel' import Slide from './Slide' import Dots from './Dots' @@ -15,6 +16,7 @@ import defaultTheme from './themes' import defaultComponents from './components' export { default as Image } from './Image' +export { default as Notes } from './Notes' export { default as components } from './components' // themes @@ -142,38 +144,48 @@ export class SlideDeck extends React.Component { ? Presenter : Root + const context = { + ...this.state, + slides, + } + return ( - - - - - - {slides.map((Component, i) => ( - - - - ))} - - { - this.setState({ index }) - }} - /> - - - + + + + + + + {slides.map((Component, i) => ( + + + + ))} + + { + this.setState({ index }) + }} + /> + + + + ) } } From 36a5af82b73356476ed06ff5069c6019e9369435 Mon Sep 17 00:00:00 2001 From: Brent Jackson Date: Thu, 2 Aug 2018 21:21:16 -0400 Subject: [PATCH 2/7] Show speaker notes in presenter mode --- docs/index.mdx | 10 +++++++++- src/Flex.js | 8 ++++++-- src/Notes.js | 27 +++++++++++++++++++++------ src/Presenter.js | 45 ++++++++++++++++++++++++++++++--------------- src/index.js | 13 ++++++++++++- 5 files changed, 78 insertions(+), 25 deletions(-) diff --git a/docs/index.mdx b/docs/index.mdx index 1a6b841..d1ae302 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -33,12 +33,20 @@ import Box from 'superbox' 3. Present --- + ``` ``` - Hi this is some notes +
    +
  • + Hi these are notes +
  • +
  • + And it's React! +
  • +
--- diff --git a/src/Flex.js b/src/Flex.js index 99eb4c3..4979421 100644 --- a/src/Flex.js +++ b/src/Flex.js @@ -1,5 +1,5 @@ import styled from 'styled-components' -import { space, color } from 'styled-system' +import { space, width, color } from 'styled-system' const Flex = styled.div([], { display: 'flex', @@ -7,6 +7,10 @@ const Flex = styled.div([], { '@media print': { display: 'none' } -}, props => props.css, space, color) +}, props => props.css, + space, + width, + color +) export default Flex diff --git a/src/Notes.js b/src/Notes.js index 044f044..fa80c65 100644 --- a/src/Notes.js +++ b/src/Notes.js @@ -3,14 +3,29 @@ import { withDeck } from './context' import { withSlide } from './Slide' export default withDeck(withSlide(class extends React.Component { - componentDidUpdate () { - console.log( - this.props.children, - this.props.slide, - this.props.deck - ) + setNotes = (props) => { + const { slide, deck, children } = props + if (!slide.index) return + deck.addNotes({ + index: slide.index, + children + }) } + componentWillMount () { + this.setNotes(this.props) + } + + /* todo + componentWillUpdate (next) { + this.setNotes(next) + } + + shouldComponentUpdate (next) { + return next.children !== this.props.children + } + */ + render () { return false } diff --git a/src/Presenter.js b/src/Presenter.js index 10a516b..91284d2 100644 --- a/src/Presenter.js +++ b/src/Presenter.js @@ -12,6 +12,7 @@ export const Presenter = ({ length, slides = [], mode, + notes = {}, ...props }) => { const Next = slides[index + 1] @@ -24,11 +25,10 @@ export const Presenter = ({ height: '100vh' }} > - + @@ -38,21 +38,36 @@ export const Presenter = ({ - - - - {Next && ( - - - - )} - - - + + + + {Next && ( + + + + )} + + + + + {notes[index]} + + Slide {index} of {length} diff --git a/src/index.js b/src/index.js index e547b4a..2d2b678 100644 --- a/src/index.js +++ b/src/index.js @@ -51,7 +51,8 @@ export class SlideDeck extends React.Component { state = { length: this.props.slides.length, index: 0, - mode: modes.normal + mode: modes.normal, + notes: {} } update = fn => this.setState(fn) @@ -106,6 +107,15 @@ export class SlideDeck extends React.Component { this.setState({ index }) } + addNotes = ({ index, children }) => { + this.setState(state => ({ + notes: { + ...state.notes, + [index]: children + } + })) + } + componentDidMount () { document.body.addEventListener('keydown', this.handleKeyDown) window.addEventListener('hashchange', this.handleHashChange) @@ -147,6 +157,7 @@ export class SlideDeck extends React.Component { const context = { ...this.state, slides, + addNotes: this.addNotes } return ( From 4ee0ef190b7954e5c2cf1d1433d6425da73e5fed Mon Sep 17 00:00:00 2001 From: Brent Jackson Date: Thu, 2 Aug 2018 21:54:49 -0400 Subject: [PATCH 3/7] Store presenter mode in querystring --- package.json | 1 + src/Notes.js | 10 ---------- src/index.js | 7 +++++-- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index dc9ec7b..36e8d07 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "pkg-conf": "^2.1.0", "prop-types": "^15.6.2", "puppeteer": "^1.6.1", + "querystring": "^0.2.0", "react": "^16.4.1", "react-dev-utils": "^5.0.1", "remark-emoji": "^2.0.1", diff --git a/src/Notes.js b/src/Notes.js index fa80c65..1fc57de 100644 --- a/src/Notes.js +++ b/src/Notes.js @@ -16,16 +16,6 @@ export default withDeck(withSlide(class extends React.Component { this.setNotes(this.props) } - /* todo - componentWillUpdate (next) { - this.setNotes(next) - } - - shouldComponentUpdate (next) { - return next.children !== this.props.children - } - */ - render () { return false } diff --git a/src/index.js b/src/index.js index 2d2b678..5e95975 100644 --- a/src/index.js +++ b/src/index.js @@ -135,8 +135,11 @@ export class SlideDeck extends React.Component { this.isHashChange = false return } - const { index } = this.state - history.pushState(null, null, '#' + index) + const { index, mode } = this.state + let query = '' + if (mode === modes.presenter) query += 'presenter' + query = query ? '?' + query : '' + history.pushState(null, null, query + '#' + index) localStorage.setItem('mdx-slide', index) } From df92e5e651e38ac07275054ad32ef15986d30364 Mon Sep 17 00:00:00 2001 From: Brent Jackson Date: Thu, 2 Aug 2018 21:58:21 -0400 Subject: [PATCH 4/7] Adjust query params --- src/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 5e95975..a9d9e4c 100644 --- a/src/index.js +++ b/src/index.js @@ -136,9 +136,8 @@ export class SlideDeck extends React.Component { return } const { index, mode } = this.state - let query = '' + let query = '?' if (mode === modes.presenter) query += 'presenter' - query = query ? '?' + query : '' history.pushState(null, null, query + '#' + index) localStorage.setItem('mdx-slide', index) } From 7797aaaa9b369dbc53c40508314a25283e3faa4b Mon Sep 17 00:00:00 2001 From: Brent Jackson Date: Thu, 2 Aug 2018 22:15:33 -0400 Subject: [PATCH 5/7] Add docs for speaker notes --- README.md | 27 +++++++++++++++++++++++++++ docs/index.mdx | 21 +++++++++++---------- src/Mono.js | 3 ++- src/components.js | 28 ++++++++++++++++++++++------ 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 4003841..6751f37 100644 --- a/README.md +++ b/README.md @@ -262,6 +262,33 @@ To use 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 +### Speaker Notes + +Notes that only show in presenter mode can be added to any slide. +Speaker notes can be added in one of the following two ways: + +**Markdown:** Use the `notes` language attribute in a fenced code block to add speaker notes. + +````mdx +# Slide Content + +```notes +These are only visible in presenter mode +``` +```` + +**Notes Component:** Use the `Notes` component to create more complex speaker notes. + +````mdx +import { Notes } from 'mdx-deck' + +# Slide Content + + + Only visible in presenter mode + +```` + ## Exporting Add a `build` script to your `package.json` to export a presentation as HTML with a JS bundle. diff --git a/docs/index.mdx b/docs/index.mdx index d1ae302..54ee1a9 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -38,22 +38,23 @@ import Box from 'superbox' ``` - -
    -
  • - Hi these are notes -
  • -
  • - And it's React! -
  • -
-
+```notes +- These are speaker notes +- And they won't rendered in your slide +``` --- > “Blockquotes are essential to any good presentation” – Anonymous + +
    +
  • Speaker notes can also be
  • +
  • Written in JSX
  • +
+
+ --- diff --git a/src/Mono.js b/src/Mono.js index adea194..8664181 100644 --- a/src/Mono.js +++ b/src/Mono.js @@ -5,6 +5,7 @@ export default props => diff --git a/src/components.js b/src/components.js index 64b58ec..4add096 100644 --- a/src/components.js +++ b/src/components.js @@ -5,6 +5,8 @@ import { space, color } from 'styled-system' +import Notes from './Notes' +import Mono from './Mono' const css = key => props => props.theme[key] @@ -89,15 +91,16 @@ blockquote.defaultProps = { color: 'quote' } -const pre = styled.pre([], props => ({ - fontFamily: props.theme.monospace +const Pre = styled.pre([], props => ({ + fontFamily: props.theme.monospace, + whiteSpace: 'pre-wrap' }), fontSize, space, color, css('pre') ) -pre.defaultProps = { +Pre.defaultProps = { fontSize: 1, m: 0, p: 2, @@ -105,7 +108,20 @@ pre.defaultProps = { bg: 'preBackground' } -const code = styled.code([], props => ({ +const code = props => { + switch (props.className) { + case 'language-notes': + return ( + + + + ) + default: + return
+  }
+}
+
+const inlineCode = styled.code([], props => ({
   fontFamily: props.theme.monospace
 }), fontSize, space, color, css('code'))
 code.defaultProps = {
@@ -132,7 +148,7 @@ export default {
   ol,
   li,
   pre: props => props.children,
-  code: pre,
-  inlineCode: code,
+  code,
+  inlineCode,
   img
 }

From 56ff67b93b38bdd4a802f4325727b0beef918dc2 Mon Sep 17 00:00:00 2001
From: Brent Jackson 
Date: Thu, 2 Aug 2018 22:17:08 -0400
Subject: [PATCH 6/7] Remove unused dep

---
 package.json | 1 -
 1 file changed, 1 deletion(-)

diff --git a/package.json b/package.json
index 36e8d07..dc9ec7b 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,6 @@
     "pkg-conf": "^2.1.0",
     "prop-types": "^15.6.2",
     "puppeteer": "^1.6.1",
-    "querystring": "^0.2.0",
     "react": "^16.4.1",
     "react-dev-utils": "^5.0.1",
     "remark-emoji": "^2.0.1",

From 50424c7bef7f9c960da48ebe11606fb9e7c0bfb0 Mon Sep 17 00:00:00 2001
From: Brent Jackson 
Date: Thu, 2 Aug 2018 22:21:32 -0400
Subject: [PATCH 7/7] Update snapshots

---
 src/components.js                     | 2 +-
 test/__snapshots__/components.js.snap | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/components.js b/src/components.js
index 4add096..903fa45 100644
--- a/src/components.js
+++ b/src/components.js
@@ -124,7 +124,7 @@ const code = props => {
 const inlineCode = styled.code([], props => ({
   fontFamily: props.theme.monospace
 }), fontSize, space, color, css('code'))
-code.defaultProps = {
+inlineCode.defaultProps = {
   color: 'code',
   bg: 'codeBackground'
 }
diff --git a/test/__snapshots__/components.js.snap b/test/__snapshots__/components.js.snap
index e204e5d..c5db60e 100644
--- a/test/__snapshots__/components.js.snap
+++ b/test/__snapshots__/components.js.snap
@@ -33,6 +33,7 @@ exports[`renders blockquote 1`] = `
 
 exports[`renders code 1`] = `
 .c0 {
+  white-space: pre-wrap;
   font-size: 14px;
   margin: 0px;
   padding: 8px;