From 74818b7066aab7926d972b7d960e8616d7f37b14 Mon Sep 17 00:00:00 2001 From: Brent Jackson Date: Tue, 19 Jun 2018 11:41:18 -0400 Subject: [PATCH] Add scope and matching --- README.md | 14 ++-- cli.js | 4 ++ docs/_app.js | 36 ++++++++++ docs/components.md | 2 +- docs/examples/Button.md | 6 ++ docs/examples/index.md | 2 + lib/build.js | 3 +- lib/dev.js | 1 + package.json | 7 +- src/Catch.js | 40 +++++++++++ src/FileList.js | 17 +++++ src/LivePreview.js | 30 ++++++++ src/ScrollTop.js | 22 ++++++ src/entry.js | 155 ++++++++++++++++------------------------ 14 files changed, 235 insertions(+), 104 deletions(-) create mode 100644 docs/_app.js create mode 100644 docs/examples/Button.md create mode 100644 docs/examples/index.md create mode 100644 src/Catch.js create mode 100644 src/FileList.js create mode 100644 src/LivePreview.js create mode 100644 src/ScrollTop.js diff --git a/README.md b/README.md index 6efa0c8..4d17554 100644 --- a/README.md +++ b/README.md @@ -367,9 +367,13 @@ See the [example](https://github.com/c8r/x0/tree/master/examples/webpack-config) **REMOVE BEFORE MERGING** -- [ ] deep require context -- [ ] minimatch -- [ ] default route sorting - [ ] markdown scope -- [ ] move client modules to src -- [ ] adjust resolve +- [ ] default route sorting +- [x] deep require context +- [ ] route dirname/full path +- [ ] minimatch +- [ ] pass front-matter as props +- [ ] props.Component in custom apps +- [x] move client modules to src +- [x] adjust resolve + diff --git a/cli.js b/cli.js index ed53b71..08a57de 100755 --- a/cli.js +++ b/cli.js @@ -28,6 +28,7 @@ const cli = meow(` ${chalk.gray('Options')} --webpack Path to webpack config file + --match String to match routes against using minimatch ${chalk.gray('Dev Server')} @@ -68,6 +69,9 @@ const cli = meow(` type: 'string', alias: 'c' }, + match: { + type: 'string' + }, scope: { type: 'string', }, diff --git a/docs/_app.js b/docs/_app.js new file mode 100644 index 0000000..bbe351d --- /dev/null +++ b/docs/_app.js @@ -0,0 +1,36 @@ +import React from 'react' +import * as scope from 'rebass' +import { ScopeProvider } from '../src' +import { + Flex, + Box, + Container, +} from 'rebass' + +export default class App extends React.Component { + static defaultProps = { + title: 'Hello' + } + + render () { + const { render } = this.props + console.log('custom app', this.props.routes) + + return ( + + + {false && ( + + custom app + + )} + + + {render()} + + + + + ) + } +} diff --git a/docs/components.md b/docs/components.md index 07b9030..0cbc221 100644 --- a/docs/components.md +++ b/docs/components.md @@ -9,5 +9,5 @@ This is a standard markdown file. This is a live/editable code block: ```.jsx -

Hello

+Hello ``` diff --git a/docs/examples/Button.md b/docs/examples/Button.md new file mode 100644 index 0000000..1a19a8f --- /dev/null +++ b/docs/examples/Button.md @@ -0,0 +1,6 @@ + +# Button + +```.jsx + +``` diff --git a/docs/examples/index.md b/docs/examples/index.md new file mode 100644 index 0000000..b0fe5b7 --- /dev/null +++ b/docs/examples/index.md @@ -0,0 +1,2 @@ + +# Examples diff --git a/lib/build.js b/lib/build.js index 4971fbf..c39a4e6 100644 --- a/lib/build.js +++ b/lib/build.js @@ -165,7 +165,8 @@ module.exports = async (opts) => { DEV: JSON.stringify(false), OPTIONS: JSON.stringify(opts), DIRNAME: JSON.stringify(opts.dirname), - APP: JSON.stringify(opts.app) + APP: JSON.stringify(opts.app), + MATCH: JSON.stringify(opts.match) }) ) diff --git a/lib/dev.js b/lib/dev.js index c454811..517a017 100644 --- a/lib/dev.js +++ b/lib/dev.js @@ -50,6 +50,7 @@ module.exports = async (opts) => { OPTIONS: JSON.stringify(opts), DIRNAME: JSON.stringify(opts.dirname), APP: JSON.stringify(opts.app), + MATCH: JSON.stringify(opts.match) }) ) diff --git a/package.json b/package.json index d215d6c..1249c85 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,8 @@ "@compositor/log": "^1.0.0-0", "@mdx-js/loader": "^0.11.0", "@mdx-js/mdx": "^0.10.1", + "@mdx-js/tag": "^0.11.0", + "@rebass/markdown": "^1.0.0-1", "babel-core": "^6.26.3", "babel-loader": "^7.1.4", "babel-plugin-macros": "^2.2.2", @@ -50,12 +52,14 @@ "koa-connect": "^2.0.1", "meow": "^5.0.0", "mini-html-webpack-plugin": "^0.2.3", + "minimatch": "^3.0.4", "pkg-conf": "^2.1.0", "react": "^16.4.1", "react-dev-utils": "^5.0.1", "react-dom": "^16.4.1", "react-router": "^4.3.1", "react-router-dom": "^4.3.1", + "react-scope-provider": "^1.0.0-1", "read-pkg-up": "^3.0.0", "remark-autolink-headings": "^5.0.0", "remark-emoji": "^2.0.1", @@ -69,13 +73,12 @@ }, "devDependencies": { "@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-7", + "rebass": "^2.0.0-6", "refunk": "^3.0.1", "rimraf": "^2.6.2", "styled-components": "^3.3.2", diff --git a/src/Catch.js b/src/Catch.js new file mode 100644 index 0000000..61091f0 --- /dev/null +++ b/src/Catch.js @@ -0,0 +1,40 @@ +import React from 'react' + +export default class Catch extends React.Component { + static getDerivedStateFromProps (props, state) { + if (!state.err) return null + return { err: null } + } + + state = { + err: null + } + + componentDidCatch (err) { + this.setState({ err }) + } + + render () { + const { err } = this.state + + if (err) { + return ( +
+      )
+    }
+
+    return this.props.children
+  }
+}
diff --git a/src/FileList.js b/src/FileList.js
new file mode 100644
index 0000000..5a58375
--- /dev/null
+++ b/src/FileList.js
@@ -0,0 +1,17 @@
+import React from 'react'
+import { Link } from 'react-router-dom'
+
+export default ({ routes = [] }) => (
+  
+    
{DIRNAME}
+
    + {routes.map(route => ( +
  • + + {route.name} + +
  • + ))} +
+
+) diff --git a/src/LivePreview.js b/src/LivePreview.js new file mode 100644 index 0000000..989b18f --- /dev/null +++ b/src/LivePreview.js @@ -0,0 +1,30 @@ +import React from 'react' +import { + LiveProvider, + LivePreview, + LiveError +} from 'react-live' +import { ScopeConsumer } from 'react-scope-provider' +import { Box } from 'rebass' + +const transformCode = str => `${str}` + +export default ({ + code, + scope +}) => ( + + + {scope => ( + + + + + )} + + +) diff --git a/src/ScrollTop.js b/src/ScrollTop.js new file mode 100644 index 0000000..72da1ff --- /dev/null +++ b/src/ScrollTop.js @@ -0,0 +1,22 @@ +import React from 'react' +import { withRouter } from 'react-router-dom' + +export default withRouter(class extends React.Component { + componentDidUpdate (prev) { + const { pathname, hash } = this.props.location + if (prev.location.pathname !== pathname) { + window.scrollTo(0, 0) + } + + // check performance of this + if (hash) { + const el = document.getElementById(hash.slice(1)) + if (!el) return + el.scrollIntoView() + } + } + + render () { + return false + } +}) diff --git a/src/entry.js b/src/entry.js index 0606d3e..9ecd4ae 100644 --- a/src/entry.js +++ b/src/entry.js @@ -10,44 +10,41 @@ import { Link, withRouter } from 'react-router-dom' +import minimatch from 'minimatch' + +import Catch from './Catch' +import ScopeProvider from './ScopeProvider' +import FileList from './FileList' +import ScrollTop from './ScrollTop' const IS_CLIENT = typeof document !== 'undefined' -const req = require.context(DIRNAME, false, /\.(js|md|mdx|jsx)$/) +const req = require.context(DIRNAME, true, /\.(js|md|mdx|jsx)$/) const { filename, basename = '', disableScroll } = OPTIONS const index = filename ? path.basename(filename, path.extname(filename)) : 'index' -const getComponents = req => req.keys().map(key => ({ - key, - name: path.basename(key, path.extname(key)), - module: req(key), - Component: req(key).default || req(key) -})) +req.keys().forEach(key => { + console.log(key, minimatch(key.replace(/^\.\//, ''), MATCH) ) +}) + +const getComponents = req => req.keys() + .filter(key => !MATCH || minimatch(key.replace(/^\.\//, ''), MATCH)) + .map(key => ({ + key, + name: path.basename(key, path.extname(key)), + module: req(key), + Component: req(key).default || req(key) + })) .filter(component => !/^(\.|_)/.test(component.name)) .filter(component => typeof component.Component === 'function') const initialComponents = getComponents(req) -const Index = ({ routes = [] }) => ( - -
{DIRNAME}
-
    - {routes.map(route => ( -
  • - - {route.name} - -
  • - ))} -
-
-) - const DefaultApp = ({ render, routes }) => ( {render()} ( - @@ -55,58 +52,8 @@ const DefaultApp = ({ render, routes }) => ( ) -class Catch extends React.Component { - static getDerivedStateFromProps (props, state) { - if (!state.err) return null - return { err: null } - } - - state = { - err: null - } - - componentDidCatch (err) { - this.setState({ err }) - } - - render () { - const { err } = this.state - - if (err) { - return ( -
-      )
-    }
-
-    return this.props.children
-  }
-}
-
-const ScrollTop = withRouter(class extends React.Component {
-  componentDidUpdate(prevProps) {
-    if (this.props.location.pathname !== prevProps.location.pathname) {
-      window.scrollTo(0, 0)
-    }
-  }
-  render () {
-    return false
-  }
-})
-
 const Router = IS_CLIENT ? BrowserRouter : StaticRouter
-const App = withRouter(APP ? (require(APP).default || require(APP)) : DefaultApp)
+const App = APP ? (require(APP).default || require(APP)) : DefaultApp
 
 export const getRoutes = async (components = initialComponents) => {
   const routes = await components.map(async ({ key, name, module, Component }) => {
@@ -129,19 +76,29 @@ export const getRoutes = async (components = initialComponents) => {
   return Promise.all(routes)
 }
 
+const RouterState = withRouter(({ render, ...props }) => {
+  const route = props.routes.find(r => r.path === props.location.pathname)
+  return render({ ...props, route })
+})
+
 export default class Root extends React.Component {
   static defaultProps = {
     path: '/',
     basename
   }
-  state = this.props
+  state = {
+    ...this.props,
+    ...App.defaultProps
+  }
 
   render () {
     const {
       routes,
       basename,
       path = '/'
-    } = this.state
+    } = this.props
+
+    console.log('App', App.defaultProps)
 
     return (
       
         
-          
-             (
-                routes.map(({ Component, ...route }) => (
-                   (
-                      
-                        
+            
+               (
+                   (
+                      routes.map(({ Component, ...route }) => (
+                         (
+                            
+                              
+                            
+                          )}
                         />
-                      
+                      ))
                     )}
                   />
-                ))
-              )}
-            />
-          
-          {!disableScroll && }
+                )}
+              />
+            
+            {!disableScroll && }
+          
         
       
     )