Skip to content

Instantly share code, notes, and snippets.

@pomber
Last active October 10, 2018 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pomber/6f09c617d2031d00dae08f608329625d to your computer and use it in GitHub Desktop.
Save pomber/6f09c617d2031d00dae08f608329625d to your computer and use it in GitHub Desktop.
deck-run
{
"presets": ["@babel/preset-react", "@babel/preset-env"]
}
{
"templateName": "mdx-deck",
"templateColor": "#222",
"sandpack": {
"defaultExtensions": ["js", "jsx", "ts", "tsx", "json"],
"aliases": {},
"preInstalledDependencies": [],
"transpilers": {
"\\.mdx$": ["./transpilers/mdx-deck-transpiler", "codesandbox:babel"],
"\\.jsx?$": ["codesandbox:babel"],
"\\.json$": ["codesandbox:json"],
".*": ["codesandbox:raw"]
}
}
}
import normalizeNewline from "normalize-newline";
import mdx from "@mdx-js/mdx";
import matter from "gray-matter";
import stringifyObject from "stringify-object";
const SLIDEREG = /\n---\n/;
export async function transpile(code, loaderContext) {
const { data, content } = matter(code);
const modules = [];
const slides = normalizeNewline(content)
.split(SLIDEREG)
.map(str => {
const code = mdx.sync(str, { skipExport: true });
const lines = code.split("\n");
const tagIndex = lines.findIndex(str => /^</.test(str));
modules.push(...lines.slice(0, tagIndex).filter(Boolean));
const jsx = lines.slice(tagIndex).join("\n");
return `({ components, ...props }) => ${jsx}`;
})
.map(str => str.trim());
return {
transpiledCode: `
import React from 'react'
import { MDXTag } from '@mdx-js/tag'
${modules.join("\n")}
export const meta = ${stringifyObject(data)}
export default [
${slides.join(",\n\n")}
]`
};
}
import React from "react";
import { render } from "react-dom";
import { SlideDeck } from "mdx-deck";
import { injectGlobal } from "styled-components";
injectGlobal`
*{box-sizing:border-box}
body{font-family:system-ui,sans-serif;margin:0}
html,body{overflow:hidden}
/* TODO use showOpenInCodeSandbox: false */
iframe {display: none}
`;
const mod = require("./deck.mdx");
const slides = mod.default;
const { theme, components, Provider } = mod;
export default class App extends React.Component {
render() {
return (
<SlideDeck
{...this.props}
slides={slides}
theme={theme}
components={components}
Provider={Provider}
/>
);
}
}
if (typeof document !== "undefined") {
render(<App />, document.getElementById("root"));
}
if (module.hot) module.hot.accept();
import React from "react";
import styled from "styled-components";
const IMG = styled.img`
width: 100vw;
position: absolute;
left: 0;
z-index: -1;
top: 50%;
transform: translateY(-50%);
`;
const BGImage = ({ src }) => <IMG src={src} />;
export default BGImage;
import BGImage from "./bg-image";
import LayoutNoFooter from "./layout-no-footer";
import Layout from "./layout";
import Split from "./Split";
import Theme from "./theme";
export { BGImage, LayoutNoFooter, Layout, Split };
export default Theme;
import React, { Fragment } from "react";
import styled from "styled-components";
const Wrapper = styled.main`
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
flex-direction: row;
justify-content: center;
position: relative;
`;
const Footer = styled.footer`
font-size: 14px;
color: white;
padding: 30px 100px;
text-align: right;
width: 100vw;
border-top: 1px solid #dc5f53;
display: flex;
justify-content: space-between;
`;
const Layout = ({ children }) => (
<Fragment>
<Wrapper>{children}</Wrapper>
<Footer>
<span>Vue London 🇬🇧</span>
<span>@NIkkitaFTW</span>
</Footer>
</Fragment>
);
export default Layout;
import styled from "styled-components";
const H2 = styled.h2`
transform: rotate(-90deg);
`;
export default H2;
import React from "react";
import styled from "styled-components";
import Flex from "mdx-deck/dist/Flex";
import Box from "mdx-deck/dist/Box";
const Footer = styled.footer`
font-size: 14px;
color: white;
padding: 30px 100px;
text-align: right;
width: 100vw;
border-top: 1px solid #dc5f53;
display: flex;
justify-content: space-between;
position: absolute;
bottom: 0;
`;
const Root = styled.div([], {
width: "100vw",
height: "100vh"
});
const Half = styled(Box)`
> * {
max-width: 100%;
}
`;
const Split = ({ children }) => {
const kids = React.Children.toArray(children.props.children);
const times = kids.length;
return (
<Root>
<Flex
css={{
alignItems: "center",
height: "100%"
}}
>
{kids.map(k => (
<Half key={k} width={1 / times}>
{k}
</Half>
))}
</Flex>
<Footer>
<span>Vue London 🇬🇧</span>
<span>@NIkkitaFTW</span>
</Footer>
</Root>
);
};
export default Split;
import theme from "mdx-deck/themes";
import atomDark from "react-syntax-highlighter/styles/prism/atom-dark";
export default {
...theme,
font: "Futura, sans-serif",
h1: {
textTransform: "uppercase",
fontWeight: 600
},
monospace: '"Dank Mono", monospace',
prism: {
style: atomDark
},
img: {
maxWidth: "100%"
},
weights: 400,
li: {
paddingBottom: "20px",
fontFamily: '"Dank Mono", monospace'
},
ul: {
listStyle: "none",
paddingLeft: "20px",
display: "inline-block"
},
colors: {
text: "#6AD798",
background: "rgb(1, 22, 39)",
link: "#fff",
pre: "#fff",
preBackground: "#051626",
code: "#fff"
}
};

import { Head, Image } from "mdx-deck" import nightOwl from "prism-react-renderer/themes/nightOwl" import { CodeSurfer } from "mdx-deck-code-surfer" import { LayoutNoFooter, Layout, Split, BGImage } from "./components/index" import { default as foo } from "./components/index"

export { components } from "mdx-deck-code-surfer" export const theme = { ...foo, codeSurfer: { ...nightOwl, showNumbers: false } }

export default Layout

<title>GraphQL + Apollo + Vue = Magic</title>

GraphQL + Apollo + Vue = Magic


export default LayoutNoFooter


export default Layout

I really love GraphQL


export default Split

GraphQL is Bae


export default Layout

My name is Sara


export default Split

  • Developer Advocate at YLD
  • Really into shitty movies
  • Really into football

export default Layout

I Adore Vue


export default Layout

I feel like Vue is like the Harry Potter of JS Libraries


export default Layout

Have you ever met anyone that hates Harry Potter ?


export default LayoutNoFooter


export default Layout

Point Proven


export default Layout

🦄🎉🏳️‍🌈🎉🦄


export default LayoutNoFooter


export default LayoutNoFooter


export default Layout

How?


npm i vue-apollo apollo-boost graphql

# yarn add vue-apollo apollo-boost graphql

import Vue from "vue"
import App from "./App"
import ApolloClient from "apollo-boost"
import VueApollo from "vue-apollo"

const apolloProvider = new VueApollo({
  defaultClient: new ApolloClient({
    uri: "https://api.graphcms.com/simple/v1/awesomeTalksClone"
  })
})

Vue.use(VueApollo)
new Vue({
  el: "#app",
  provide: apolloProvider.provide(),
  render: h => h(App)
})
----
*
3 > Import the Apollo Client
4 > Import Vue Apollo for using Apollo with vue
6:10 > Create the provider and give it the URL
13:17 > Mount Vue

export default Layout

Done


export default Layout

Let's Query Some Things!


export default LayoutNoFooter


import { gql } from "apollo-boost"
export default gql`
  query allSpeakers {
    allSpeakers {
      id
      name
      photo {
        url
      }
    }
  }
`

export default Layout

Query Component


<template>
  <ApolloQuery :query="require('../queries/SPEAKERS.gql').default">
    <template slot-scope="{ result: { loading, error, data } }">
      <h3 v-if="loading"> Loading </h3>
      <h3 v-if="error"> Oh No :( </h3>
      <ul v-if="data.allSpeakers.length">
        <li v-for="s in data.allSpeakers" :key="s.id">
          <img :src="s.photo.url" :alt="s.name" />
          {{s.name}}
        </li>
      </ul>
      <section v-else class="empty">
        No Speakers
      </section>
    </template>
  </ApolloQuery>
</template>
----
*
2, 16 > Import the query

Variables ?


export default Layout

<CodeSurfer theme={nightOwl} lang="javascript" code={ import { gql } from "apollo-boost" \n export default gql\ query allSpeakers($name: String) { allSpeakers(filter: { name_contains: $name }) { id name photo { url } } } ` `} />


<CodeSurfer theme={nightOwl} lang="markup" steps={[ { lines: [4], notes: "Add an input with a v-model" }, { lines: [6], notes: "Import Query" }, { lines: [7], notes: "Set the variables" } ]} code={<template> <main> <input type="text" placeholder="Search them names" v-model="search" /> <ApolloQuery :query="require('../queries/SPEAKERS.gql').default" :variables="{ name: search }"> <template slot-scope="{ result: { loading, error, data } }"> <h3 v-if="loading"> Loading </h3> <h3 v-if="error"> Oh No :( </h3> <ul v-if="data.allSpeakers.length"> <li v-for="s in data.allSpeakers" :key="s.id"> <img :src="s.photo.url" :alt="s.name" /> {{s.name}} </li> </ul> <section v-else class="empty"> No Speakers match your search </section> </template> </ApolloQuery> </main> </template>} />


export default Layout

Mutations?


export default Layout

Mutation component!!


<CodeSurfer theme={nightOwl} lang="javascript" code={ import { gql } from "apollo-boost" \n export default gql\ mutation createSpeaker($name: String!) { createSpeakers(name: $name) { id name } } ` `} />


<CodeSurfer theme={nightOwl} lang="markup" steps={[ { lines: [4], notes: "Import Mutation" }, { lines: [5, 10], notes: "Set the variables" }, { lines: [9], notes: "Run the mutation function on submit" } ]} code={<template> <ApolloMutation :mutation=“require('../queries/ADD_SPEAKER.gql').default" :variables="{ name }” :update=“onUpdate" > <template slot-scope="{ mutate, loading, error }"> <form @submit.prevent="mutate"> <input type="text" placeholder=“Name" v-model="name" /> <button type="submit">Add Speaker</button> <h3 v-if="error">Failed</h3> <h3 v-if="loading">Loading</h3> </form> </template> </ApolloMutation> </template>} />


export default Layout

The Update Function


<CodeSurfer theme={nightOwl} lang="javascript" code={methods: { onUpdate(cache, { data: { createSpeaker }}) { const { allSpeakers } = cache.readQuery({ query: SPEAKERS }) cache.writeQuery({ query: SPEAKERS, data: { allSpeakers: allSpeakers.concat({ ... createSpeaker, photo: { url: 'http://placekitten.com/100/100', __typename: 'Assets', }, }), }, }) }, }} />


Demo


Demo with Local State


export default LayoutNoFooter

export default LayoutNoFooter

Thank You 🇬🇧󠁢󠁥󠁮󠁧󠁿

{
"name": "run",
"main": "/.entry.js",
"dependencies": {
"@mdx-js/mdx": "latest",
"@mdx-js/tag": "latest",
"mdx-deck": "latest",
"mdx-deck-code-surfer": "latest",
"normalize-newline": "latest",
"gray-matter": "latest",
"react": "latest",
"react-dom": "latest",
"stringify-object": "latest"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment