diff --git a/.gitignore b/.gitignore index 6d0de8319..6585200af 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ dist .rpt2_cache *.log public -.next \ No newline at end of file +.next +out \ No newline at end of file diff --git a/core/loader/src/store.ts b/core/loader/src/store.ts index a6d24d74b..1192cdd85 100644 --- a/core/loader/src/store.ts +++ b/core/loader/src/store.ts @@ -3,9 +3,9 @@ import { StoryPackages, BuildConfiguration, RunConfiguration, + Pages, Document, defDocType, - Pages, DocType, docStoryToId, } from '@component-controls/core'; @@ -36,8 +36,6 @@ export interface LoadingStore { stores: (Partial> & { filePath: string; })[]; - getDocs: (type: DocType) => Pages; - getUniquesByField: (field: string) => { [key: string]: number }; } class Store implements LoadingStore { @@ -46,48 +44,54 @@ class Store implements LoadingStore { packages: LoadingStore['packages'] = {}; config: LoadingStore['config'] = {}; buildConfig: LoadingStore['buildConfig'] = {}; - getDocs = (docType: DocType) => - this.stores - .filter(store => { - if (store?.doc) { - const { type = defDocType } = store.doc; - return type === docType; - } - return false; - }) - .map( - store => - ({ - ...store.doc, - stories: - store.doc && store.stories - ? Object.keys(store.stories).map(id => - //@ts-ignore - docStoryToId(store.doc.title, id), - ) - : undefined, - } as Document), - ); - getUniquesByField = (field: string) => { - return this.stores.reduce((acc: { [key: string]: number }, store) => { - if (store?.doc) { - //@ts-ignore - const value = store.doc[field]; - const values = Array.isArray(value) ? value : [value]; - values.forEach(v => { - if (v !== undefined) { - if (typeof acc[v] === 'undefined') { - acc[v] = 0; - } - acc[v] = acc[v] = 1; - } - }); - } - return acc; - }, {}); - }; } +export const getDocs = ( + stores: LoadingStore['stores'], + docType: DocType, +): Pages => + stores + .filter(store => { + if (store?.doc) { + const { type = defDocType } = store.doc; + return type === docType; + } + return false; + }) + .map( + store => + ({ + ...store.doc, + stories: + store.doc && store.stories + ? Object.keys(store.stories).map(id => + //@ts-ignore + docStoryToId(store.doc.title, id), + ) + : undefined, + } as Document), + ); +export const getUniquesByField = ( + stores: LoadingStore['stores'], + field: string, +): { [key: string]: number } => { + return stores.reduce((acc: { [key: string]: number }, store) => { + if (store?.doc) { + //@ts-ignore + const value = store.doc[field]; + const values = Array.isArray(value) ? value : [value]; + values.forEach(v => { + if (v !== undefined) { + if (typeof acc[v] === 'undefined') { + acc[v] = 0; + } + acc[v] = acc[v] = 1; + } + }); + } + return acc; + }, {}); +}; export const store = new Store(); export const reserveStories = (filePaths: string[]) => { diff --git a/examples/nextjs/next.config.js b/examples/nextjs/next.config.js index f5eccdaa7..6a003c544 100644 --- a/examples/nextjs/next.config.js +++ b/examples/nextjs/next.config.js @@ -1,3 +1,3 @@ -const withStories = require('@component-controls/nextjs-plugin'); +const withStories = require('@component-controls/nextjs-plugin/build'); module.exports = withStories({ configPath: '.config', distDir: 'dist' }); diff --git a/examples/nextjs/package.json b/examples/nextjs/package.json index 6dc6fa02f..2cad60100 100644 --- a/examples/nextjs/package.json +++ b/examples/nextjs/package.json @@ -5,7 +5,7 @@ "main": "index.js", "license": "MIT", "scripts": { - "build-sample": "next build", + "build-sample": "next build && next export", "start": "next -p 9021" }, "repository": { @@ -16,6 +16,8 @@ "dependencies": { "@component-controls/nextjs-plugin": "^1.8.0", "@component-controls/pages": "^1.8.0", + "emotion": "^10.0.27", + "emotion-server": "^10.0.27", "next": "^9.4.4", "react": "^16.13.1", "react-dom": "^16.13.1" diff --git a/examples/nextjs/pages/[doctype].tsx b/examples/nextjs/pages/[doctype].tsx new file mode 100644 index 000000000..add7c58e6 --- /dev/null +++ b/examples/nextjs/pages/[doctype].tsx @@ -0,0 +1,50 @@ +import React, { FC } from 'react'; +import { GetStaticProps, GetStaticPaths } from 'next'; +import { DocType, defDocType, Pages } from '@component-controls/core'; +import { DocumentHomePage } from '@component-controls/app'; +import { getDocs } from '@component-controls/loader'; +import { Layout } from '@component-controls/nextjs-plugin'; + +interface PageListProps { + type: DocType; + docId?: string; +} + +const DocHomeTemplate: FC = ({ type = defDocType, docId }) => { + return ( + + + + ); +}; + +export const getStaticPaths: GetStaticPaths = async () => { + const paths: string[] = []; + const store = require('@component-controls/webpack-compile/bundle'); + const { pages } = store.buildConfig || {}; + if (pages) { + Object.keys(pages).forEach(type => { + const page = pages[type as DocType]; + //const docType = type as DocType; + // const docs = getDocs(store.stores, docType); + paths.push(`/${page.basePath}`); + }); + } + return { paths, fallback: false }; +}; + +export const getStaticProps: GetStaticProps = async ({ params }) => { + const store = require('@component-controls/webpack-compile/bundle'); + const { doctype: basepath } = params as { doctype: string }; + + const { pages } = store.buildConfig || {}; + const doctype = Object.keys(pages).find(key => { + return pages[key].basePath.replace(/\//g, '') === basepath; + }) as DocType; + const docs: Pages = getDocs(store.stores, doctype); + const page = pages[doctype]; + const docsPage = docs.find(doc => doc?.route === `/${page.basePath}`); + return { props: { docId: docsPage?.title || null, type: doctype } }; +}; + +export default DocHomeTemplate; diff --git a/examples/nextjs/pages/_app.js b/examples/nextjs/pages/_app.js new file mode 100644 index 000000000..4586187fc --- /dev/null +++ b/examples/nextjs/pages/_app.js @@ -0,0 +1,17 @@ +import React from 'react'; +import NextApp from 'next/app'; +import { CacheProvider } from '@emotion/core'; + +// Use only { cache } from 'emotion'. Don't use { css }. +import { cache } from 'emotion'; + +export default class App extends NextApp { + render() { + const { Component, pageProps } = this.props; + return ( + + + + ); + } +} diff --git a/examples/nextjs/pages/_document.js b/examples/nextjs/pages/_document.js new file mode 100644 index 000000000..12c08b388 --- /dev/null +++ b/examples/nextjs/pages/_document.js @@ -0,0 +1,34 @@ +import React from 'react'; +import Document, { Head, Main, NextScript } from 'next/document'; +import { extractCritical } from 'emotion-server'; + +export default class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx); + const styles = extractCritical(initialProps.html); + return { + ...initialProps, + styles: ( + <> + {initialProps.styles} +