diff --git a/docs/_app.js b/docs/_app.js deleted file mode 100644 index e6aca89..0000000 --- a/docs/_app.js +++ /dev/null @@ -1,58 +0,0 @@ -import React from 'react' -import { - Provider, - Flex, - Box, - Container, - Text, - Caps, - BlockLink, -} from 'rebass' -import { Link } from 'react-router-dom' -import { Logo } from '@compositor/logo' -import theme from './theme' - -export default ({ render }) => - - - - - - - Compositor - - - - - - - x0 - - - - - GitHub - - - - {render()} - - - - - GitHub - - - - - Compositor - - - - - © 2018 Compositor, Inc. All rights reserved - - - - diff --git a/docs/index.js b/docs/index.js deleted file mode 100644 index 52d8dc5..0000000 --- a/docs/index.js +++ /dev/null @@ -1,70 +0,0 @@ -import React from 'react' -import { Link } from 'react-router-dom' -import styled from 'styled-components' -import { - Container, - Box, - Flex, - Caps, - Heading, - Text, - Button, - Pre, -} from 'rebass' -import { Logo } from '@compositor/logo' - -const Video = styled.video([], { - display: 'block', - maxWidth: '100%', - height: 'auto', - borderRadius: '16px', -}) - -export default class extends React.Component { - render () { - return ( - - - - x0: Zero-config React development environment & static site generator - - - -
npm i -g @compositor/x0
- - - - - -
-
- ) - } -} diff --git a/docs/webpack.config.js b/docs/webpack.config.js deleted file mode 100644 index 9718488..0000000 --- a/docs/webpack.config.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - module: { - rules: [ - { - test: /\.md$/, - use: [ - // 'raw-loader' - { - loader: 'babel-loader', - options: { - presets: [ - 'env', - 'stage-0', - 'react' - ] - } - }, - '@compositor/md-loader' - ] - } - ] - } -} diff --git a/lib/config.js b/lib/config.js index 04dafb0..f642bd3 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,5 +1,12 @@ const path = require('path') +const remark = { + images: require('remark-images'), + emoji: require('remark-emoji'), + slug: require('remark-slug'), + autolinkHeadings: require('remark-autolink-headings'), +} + const babel = { presets: [ 'babel-preset-env', @@ -27,20 +34,24 @@ const rules = [ options: babel }, { - test: /\.jsx$/, - loader: require.resolve('@compositor/jsx-loader'), - options: {} - }, - { - test: /\.mdx$/, + test: /\.(md|mdx|jsx)$/, use: [ { loader: require.resolve('babel-loader'), options: babel }, { - loader: require.resolve('@mdx-js/loader') - } + loader: require.resolve('@mdx-js/loader'), + options: { + mdPlugins: [ + remark.slug, + remark.autolinkHeadings, + remark.images, + remark.emoji, + ] + } + }, + path.join(__dirname, './mdx-fm-loader'), ] } ] diff --git a/lib/entry.js b/lib/entry.js index 41eb723..8ab4f23 100644 --- a/lib/entry.js +++ b/lib/entry.js @@ -11,7 +11,7 @@ import { } from 'react-router-dom' const IS_CLIENT = typeof document !== 'undefined' -const req = require.context(DIRNAME, false, /\.(js|mdx|jsx)$/) +const req = require.context(DIRNAME, false, /\.(js|md|mdx|jsx)$/) const { filename, basename = '', disableScroll } = OPTIONS const index = filename ? path.basename(filename, path.extname(filename)) : 'index' diff --git a/lib/mdx-fm-loader.js b/lib/mdx-fm-loader.js new file mode 100644 index 0000000..28a04c6 --- /dev/null +++ b/lib/mdx-fm-loader.js @@ -0,0 +1,13 @@ +// front-matter loader for mdx +const matter = require('gray-matter') +const stringifyObject = require('stringify-object') + +module.exports = async function (src) { + const callback = this.async() + const { content, data } = matter(src) + + const code = `export const frontMatter = ${stringifyObject(data)} +${content} + ` + return callback(null, code) +} diff --git a/package.json b/package.json index e37f89e..d215d6c 100644 --- a/package.json +++ b/package.json @@ -27,13 +27,12 @@ "author": "Brent Jackson", "license": "MIT", "dependencies": { - "@compositor/jsx-loader": "^1.0.0-4", "@compositor/log": "^1.0.0-0", - "@mdx-js/loader": "^0.9.0", - "@mdx-js/mdx": "^0.9.0", + "@mdx-js/loader": "^0.11.0", + "@mdx-js/mdx": "^0.10.1", "babel-core": "^6.26.3", "babel-loader": "^7.1.4", - "babel-plugin-macros": "^2.2.1", + "babel-plugin-macros": "^2.2.2", "babel-plugin-transform-runtime": "^6.23.0", "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", @@ -42,8 +41,8 @@ "chalk": "^2.4.1", "clipboardy": "^1.2.3", "connect-history-api-fallback": "^1.5.0", - "emotion": "^9.1.3", - "emotion-server": "^9.1.3", + "emotion": "^9.2.3", + "emotion-server": "^9.2.3", "find-up": "^2.1.0", "fs-extra": "^6.0.1", "glamor": "^2.20.40", @@ -52,31 +51,35 @@ "meow": "^5.0.0", "mini-html-webpack-plugin": "^0.2.3", "pkg-conf": "^2.1.0", - "react": "^16.4.0", + "react": "^16.4.1", "react-dev-utils": "^5.0.1", - "react-dom": "^16.4.0", - "react-router": "^4.2.0", - "react-router-dom": "^4.2.2", + "react-dom": "^16.4.1", + "react-router": "^4.3.1", + "react-router-dom": "^4.3.1", "read-pkg-up": "^3.0.0", + "remark-autolink-headings": "^5.0.0", + "remark-emoji": "^2.0.1", + "remark-images": "^0.8.1", + "remark-slug": "^5.0.0", "semver": "^5.5.0", "update-notifier": "^2.5.0", "webpack": "^4.10.2", - "webpack-merge": "^4.1.2", - "webpack-serve": "^1.0.2" + "webpack-merge": "^4.1.3", + "webpack-serve": "^1.0.4" }, "devDependencies": { - "@compositor/logo": "^1.3.5", + "@compositor/logo": "^1.4.0", "@compositor/md-loader": "^1.0.34", "ava": "^0.25.0", "isomorphic-fetch": "^2.2.1", "nano-style": "^1.0.0", "nyc": "^12.0.1", "raw-loader": "^0.5.1", - "rebass": "^2.0.0-2", + "rebass": "^2.0.0-7", "refunk": "^3.0.1", "rimraf": "^2.6.2", - "styled-components": "^3.3.0", - "styled-system": "^2.2.5" + "styled-components": "^3.3.2", + "styled-system": "^2.3.1" }, "x0": { "title": "Compositor x0", diff --git a/src/LiveEditor.js b/src/LiveEditor.js new file mode 100644 index 0000000..6ac3ac6 --- /dev/null +++ b/src/LiveEditor.js @@ -0,0 +1,73 @@ +import React from 'react' +import { + LiveProvider, + LivePreview, + LiveEditor, + LiveError +} from 'react-live' +import { ScopeConsumer } from 'react-scope-provider' +import { Box } from 'rebass' +import { color, borderColor } from 'styled-system' +import styled from 'styled-components' + +const transformCode = src => `${src}` + +const Preview = styled(LivePreview)([], { + padding: '16px', + border: '1px solid', + borderRadius: '2px 2px 0 0', +}, borderColor) +Preview.defaultProps = { + borderColor: 'gray' +} + +const Editor = styled(LiveEditor)([], { + fontFamily: 'Menlo, monospace', + fontSize: '13px', + margin: 0, + padding: '16px', + borderRadius: '0 0 2px 2px', + '&:focus': { + outline: 'none', + boxShadow: 'inset 0 0 0 1px #6cf', + } +}, color) +Editor.defaultProps = { + bg: 'gray' +} + +const Err = styled(LiveError)([], { + fontFamily: 'Menlo, monospace', + fontSize: '13px', + padding: '8px', + color: 'white', + backgroundColor: 'red' +}) + +export default ({ + code, + scope, + render +}) => ( + + + {scope => ( + + {typeof render === 'function' ? ( + render({ code, scope }) + ) : ( + + + + + + )} + + )} + + +) diff --git a/src/ScopeProvider.js b/src/ScopeProvider.js new file mode 100644 index 0000000..d302900 --- /dev/null +++ b/src/ScopeProvider.js @@ -0,0 +1,20 @@ +import React from 'react' +import { MDXProvider } from '@mdx-js/tag' +import { ScopeProvider } from 'react-scope-provider' +import defaultScope from './scope' + +export default props => { + const scope = { + ...defaultScope, + ...props.scope + } + return ( + + + + {props.children} + + + + ) +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..d59e3fc --- /dev/null +++ b/src/index.js @@ -0,0 +1,3 @@ +export { default as ScopeProvider } from './ScopeProvider' +export { default as LiveEditor } from './LiveEditor' +export { default as scope } from './scope' diff --git a/src/scope.js b/src/scope.js new file mode 100644 index 0000000..2257fb2 --- /dev/null +++ b/src/scope.js @@ -0,0 +1,80 @@ +import React from 'react' +import { withRouter, Link } from 'react-router-dom' +import rebassMarkdown from '@rebass/markdown' +import { Pre } from 'rebass' + +import LiveEditor from './LiveEditor' +import LivePreview from './LivePreview' + +const cleanHREF = href => href + .replace(/\.mdx?$/, '') + .replace(/\.jsx?$/, '') + +export const link = withRouter(({ + href, + match, + location, + children, + className, + ...props +}) => { + if (/^https?:\/\//.test(href) || /^#/.test(href)) { + return ( + + ) + } + const to = cleanHREF(href, location.pathname) + return ( + + ) +}) + +export const code = ({ + children, + className, + scope, + ...props +}) => { + const lang = className.replace(/^language\-/, '') + const type = lang.charAt(0) + const code = React.Children.toArray(children).join('\n') + + switch (type) { + case '.': + return + case '!': + return + default: + return ( +
+      )
+  }
+}
+
+const pre = props => props.children
+
+const scope = rebassMarkdown({
+  a: {
+    is: link
+  },
+  code: {
+    is: code
+  },
+  pre: {
+    is: pre,
+  }
+})
+
+export default scope