Browse Source

feat(docs): Styling of generated docs pages

Michael Bromley 6 years ago
parent
commit
4d18cb373c

+ 9 - 0
docs/assets/scripts/docs-formatting.ts

@@ -0,0 +1,9 @@
+export function formatDocs() {
+
+    Array.from(document.querySelectorAll('h3')).forEach(h1 => {
+        const nextSibling = h1.nextElementSibling;
+        if (nextSibling && nextSibling.classList.contains('member-info')) {
+            h1.classList.add('member-title');
+        }
+    });
+}

+ 1 - 1
docs/assets/scripts/intro/sequencer.ts

@@ -3,7 +3,7 @@ import Timer = NodeJS.Timer;
 
 export class Sequencer {
 
-    private readonly playTimer: { [name: string]: Timer; };
+    private readonly playTimer: { [name: string]: any; };
     private readonly onTransition?: (className: string) => void;
 
     constructor(private sceneElement: HTMLDivElement,

+ 2 - 0
docs/assets/scripts/main.ts

@@ -5,6 +5,7 @@ import { initNavMenu } from './nav-menu';
 import { SearchWidget } from './search-widget';
 import { initTabs } from './tabs';
 import { TocHighlighter } from './toc-highlighter';
+import { formatDocs } from './docs-formatting';
 
 // tslint:disable-next-line
 require('../styles/main.scss');
@@ -37,5 +38,6 @@ document.addEventListener('DOMContentLoaded', () => {
     initTabs();
     initNavMenu();
     initGraphQlPlaygroundWidgets();
+    formatDocs();
 
 }, false);

+ 9 - 7
docs/assets/scripts/search-widget.ts

@@ -184,13 +184,15 @@ export class SearchWidget {
                         });
                         if (headings.length) {
                             for (const heading of headings) {
-                                denormalized.push({
-                                    section,
-                                    title,
-                                    parent,
-                                    heading,
-                                    url,
-                                });
+                                if (heading !== title) {
+                                    denormalized.push({
+                                        section,
+                                        title,
+                                        parent,
+                                        heading,
+                                        url,
+                                    });
+                                }
                             }
                         }
                     }

+ 1 - 1
docs/assets/scripts/toc-highlighter.ts

@@ -8,7 +8,7 @@ export class TocHighlighter {
     highlight() {
         const article = document.querySelector('article');
         if (this.tocElement && article) {
-            const headers: HTMLHeadingElement[] = Array.from(article.querySelectorAll('h1[id],h2[id],h3[id]'));
+            const headers: HTMLHeadingElement[] = Array.from(article.querySelectorAll('h1[id],h2[id],h3[id],h4[id]'));
 
             window.addEventListener('scroll', (e) => {
                 this.highlightCurrentSection(headers);

+ 30 - 5
docs/assets/styles/_markdown.scss

@@ -2,14 +2,25 @@
 
 $block-border-radius: 4px;
 
+@mixin codelike {
+    display: inline-block;
+    border-radius: 3px;
+    font-family: 'Source Code Pro', monospace;
+    background-color: $gray-100;
+    border: 1px solid $gray-200;
+}
+
 .markdown {
     line-height: 1.4;
-    margin-left: 12px;
+    @media all and (min-width: $sm-breakpoint) {
+        margin-left: 12px;
+    }
 
     h1:first-of-type {
         text-transform: capitalize;
         font-weight: 500;
         margin-top: 0;
+        margin-bottom: 0;
         font-size: 2.8em;
 
         @media all and (max-width: $sm-breakpoint){
@@ -17,18 +28,32 @@ $block-border-radius: 4px;
         }
     }
 
+    h1:not(:first-of-type) {
+        margin-top: 48px;
+        margin-left: -12px;
+        padding: 3px 12px;
+        @include codelike;
+    }
+
     h2 {
         margin-top: 48px;
+        margin-bottom: 6px;
     }
 
-    h3 {
-        margin-top: 36px;
-        color: $gray-700;
+    h3.member-title {
+        margin-top: 6px;
+        margin-left: 6px;
+        padding: 2px 6px;
+        @include codelike;
+    }
+
+    h4 {
+        margin-top: 32px;
     }
 
     h1, h2, h3, h4, h5 {
         font-family: $brand-font-face;
-        font-weight: 600;
+        font-weight: 400;
         line-height: 1.25;
 
         &[id]:target:before {

+ 23 - 0
docs/assets/styles/_menu.scss

@@ -1,6 +1,29 @@
 .book-menu {
     text-transform: capitalize;
     padding-left: 12px;
+
+    nav ul {
+        padding: 0;
+        margin: 0;
+        list-style: none;
+
+        li {
+            margin: 1em 0;
+        }
+
+        a {
+            display: block;
+        }
+
+        a:hover {
+            opacity: .5;
+        }
+
+        ul {
+            padding-left: $padding-16;
+        }
+    }
+
     .section {
         .section-link {
             display: flex;

+ 17 - 2
docs/assets/styles/_shortcodes.scss

@@ -22,8 +22,13 @@
 .member-info {
     display: flex;
     align-items: center;
+    @media screen and (max-width: $sm-breakpoint) {
+        flex-direction: column;
+        align-items: flex-start;
+    }
     margin-top: -16px;
-    font-size: 14px;
+    margin-left: 8px;
+    font-size: $font-size-12;
 
     .kind-label {
         font-size: $font-size-12;
@@ -50,12 +55,22 @@
     }
 }
 
+/**
+ Member description for generated docs
+ */
+.member-description {
+    margin-top: 3px;
+    margin-left: 8px;
+    margin-bottom: 32px;
+}
+
 /**
  Info on the generated document
  */
 .generation-info {
     font-size: $font-size-12;
-    border-bottom: 1px dashed $gray-400;
+    margin-top: -18px;
+    border-top: 1px dashed $gray-400;
     .label {
         color: $gray-600;
     }

+ 41 - 0
docs/assets/styles/_toc.scss

@@ -0,0 +1,41 @@
+@import "variables";
+
+aside.book-toc nav {
+    ul {
+        padding: 0;
+        margin: 0;
+        list-style: none;
+
+        li {
+            margin: 1em 0;
+        }
+
+        a {
+            display: block;
+        }
+
+        a:hover {
+            opacity: .5;
+        }
+    }
+    & > ul {
+        & > li:first-child {
+            & > a { display: none; }
+        }
+        & > li > a {
+            font-weight: bold;
+        }
+        & > li > ul {
+            padding-left: $padding-16;
+            & > li > ul {
+                padding-left: $padding-16;
+                li {
+                    // margin: 0.5em 0;
+                    a {
+                        color: lighten(desaturate($color-link, 70%), 25%);
+                    }
+                }
+            }
+        }
+    }
+}

+ 5 - 23
docs/assets/styles/main.scss

@@ -10,11 +10,11 @@
 @import "graphql-playground-widget";
 @import "breadcrumbs";
 @import "blog";
+@import "toc";
 
 html {
     font-size: $font-size-base;
     letter-spacing: 0.33px;
-    // scroll-behavior: smooth;
 }
 
 html,
@@ -60,28 +60,6 @@ img {
     vertical-align: middle;
 }
 
-aside nav ul {
-    padding: 0;
-    margin: 0;
-    list-style: none;
-
-    li {
-        margin: 1em 0;
-    }
-
-    a {
-        display: block;
-    }
-
-    a:hover {
-        opacity: .5;
-    }
-
-    ul {
-        padding-left: $padding-16;
-    }
-}
-
 ul.pagination {
     display: flex;
     justify-content: center;
@@ -126,7 +104,11 @@ ul.contents-list {
     min-height: 80vh;
     flex: 1;
     padding: $padding-16 * 1.6;
+    padding-right: 3px;
 
+    @media all and (max-width: $sm-breakpoint) {
+        padding: 6px;
+    }
     figure {
         img {
             max-width: 100%;

+ 3 - 0
docs/layouts/shortcodes/member-description.html

@@ -0,0 +1,3 @@
+<div class="member-description">
+    {{ .Inner | markdownify }}
+</div>

+ 1 - 1
docs/layouts/shortcodes/member-info.html

@@ -6,7 +6,7 @@
         <div class="label">type:</div>
         <code>{{ .Get "type" | safeHTML }}</code>
     </div>
-    {{ if isset .Params "default" }}
+    {{- if isset .Params "default" -}}
     <div class="default">
         <div class="label">default:</div>
         <code>{{ .Get "default" | safeHTML }}</code>

+ 22 - 5
scripts/docs/generate-typescript-docs.ts

@@ -10,12 +10,19 @@ import { TypescriptDocsRenderer } from './typescript-docs-renderer';
 
 interface DocsSectionConfig {
     sourceDirs: string[];
+    exclude?: RegExp[];
     outputPath: string;
 }
 
 const sections: DocsSectionConfig[] = [
     {
-        sourceDirs: ['packages/core/src/', 'packages/common/src/'],
+        sourceDirs: [
+            'packages/core/src/',
+            'packages/common/src/',
+        ],
+        exclude: [
+            /generated-shop-types/,
+        ],
         outputPath: 'typescript-api',
     },
     {
@@ -70,8 +77,8 @@ function generateTypescriptDocs(config: DocsSectionConfig[], isWatchMode: boolea
         }
     }
 
-    for (const { outputPath, sourceDirs } of config) {
-        const sourceFilePaths = getSourceFilePaths(sourceDirs);
+    for (const { outputPath, sourceDirs, exclude } of config) {
+        const sourceFilePaths = getSourceFilePaths(sourceDirs, exclude);
         const docsPages = new TypescriptDocsParser().parse(sourceFilePaths);
         for (const page of docsPages) {
             const { category, fileName, declarations } = page;
@@ -107,12 +114,22 @@ function absOutputPath(outputPath: string): string {
     return path.join(__dirname, '../../docs/content/docs/', outputPath);
 }
 
-function getSourceFilePaths(sourceDirs: string[]): string[] {
+function getSourceFilePaths(sourceDirs: string[], excludePatterns: RegExp[] = []): string[] {
     return sourceDirs
         .map(scanPath =>
             klawSync(path.join(__dirname, '../../', scanPath), {
                 nodir: true,
-                filter: item => path.extname(item.path) === '.ts',
+                filter: item => {
+                    if (path.extname(item.path) === '.ts') {
+                        for (const pattern of excludePatterns) {
+                            if (pattern.test(item.path)) {
+                                return false;
+                            }
+                        }
+                        return true;
+                    }
+                    return false;
+                },
                 traverseAll: true,
             }),
         )

+ 11 - 13
scripts/docs/typescript-docs-renderer.ts

@@ -31,8 +31,6 @@ export class TypescriptDocsRenderer {
             markdown += generateFrontMatter(page.title, 10);
             markdown += `\n# ${page.title}\n`;
             for (const info of page.declarations) {
-                // markdown += `## ${info.title}\n`;
-                // markdown += '{{< declaration >}}\n';
                 switch (info.kind) {
                     case 'interface':
                         markdown += this.renderInterfaceOrClass(info, typeMap, docsUrl);
@@ -78,13 +76,13 @@ export class TypescriptDocsRenderer {
     private renderInterfaceOrClass(info: InterfaceInfo | ClassInfo, knownTypeMap: TypeMap, docsUrl: string): string {
         const { title, weight, category, description, members } = info;
         let output = '';
-        output += `\n\n## ${title}\n\n`;
+        output += `\n\n# ${title}\n\n`;
         output += this.renderGenerationInfoShortcode(info);
         output += `${this.renderDescription(description, knownTypeMap, docsUrl)}\n\n`;
-        output += `### Signature\n\n`;
+        output += `## Signature\n\n`;
         output += info.kind === 'interface' ? this.renderInterfaceSignature(info) : this.renderClassSignature(info);
         if (info.members && info.members.length) {
-            output += `### Members\n\n`;
+            output += `## Members\n\n`;
             output += `${this.renderMembers(info, knownTypeMap, docsUrl)}\n`;
         }
         return output;
@@ -96,13 +94,13 @@ export class TypescriptDocsRenderer {
     private renderTypeAlias(typeAliasInfo: TypeAliasInfo, knownTypeMap: TypeMap, docsUrl: string): string {
         const { title, weight, description, type, fullText } = typeAliasInfo;
         let output = '';
-        output += `\n\n## ${title}\n\n`;
+        output += `\n\n# ${title}\n\n`;
         output += this.renderGenerationInfoShortcode(typeAliasInfo);
         output += `${this.renderDescription(description, knownTypeMap, docsUrl)}\n\n`;
-        output += `### Signature\n\n`;
+        output += `## Signature\n\n`;
         output += this.renderTypeAliasSignature(typeAliasInfo);
         if (typeAliasInfo.members && typeAliasInfo.members.length) {
-            output += `### Members\n\n`;
+            output += `## Members\n\n`;
             output += `${this.renderMembers(typeAliasInfo, knownTypeMap, docsUrl)}\n`;
         }
         return output;
@@ -111,10 +109,10 @@ export class TypescriptDocsRenderer {
     private renderEnum(enumInfo: EnumInfo, knownTypeMap: TypeMap, docsUrl: string): string {
         const { title, weight, description, fullText } = enumInfo;
         let output = '';
-        output += `\n\n## ${title}\n\n`;
+        output += `\n\n# ${title}\n\n`;
         output += this.renderGenerationInfoShortcode(enumInfo);
         output += `${this.renderDescription(description, knownTypeMap, docsUrl)}\n\n`;
-        output += `### Signature\n\n`;
+        output += `## Signature\n\n`;
         output += this.renderEnumSignature(enumInfo);
         return output;
     }
@@ -122,10 +120,10 @@ export class TypescriptDocsRenderer {
     private renderFunction(functionInfo: FunctionInfo, knownTypeMap: TypeMap, docsUrl: string): string {
         const { title, weight, description, fullText, parameters } = functionInfo;
         let output = '';
-        output += `\n\n## ${title}\n\n`;
+        output += `\n\n# ${title}\n\n`;
         output += this.renderGenerationInfoShortcode(functionInfo);
         output += `${this.renderDescription(description, knownTypeMap, docsUrl)}\n\n`;
-        output += `### Signature\n\n`;
+        output += `## Signature\n\n`;
         output += this.renderFunctionSignature(functionInfo, knownTypeMap);
         if (parameters.length) {
             output += `### Parameters\n\n`;
@@ -263,7 +261,7 @@ export class TypescriptDocsRenderer {
                     type = `(${args}) => ${this.renderType(member.type, knownTypeMap, docsUrl)}`;
                 }
             }
-            output += `#### ${member.name}\n\n`;
+            output += `### ${member.name}\n\n`;
             output += `{{< member-info kind="${[...member.modifiers, member.kind].join(' ')}" type="${type}" ${defaultParam}>}}\n\n`;
             output += `{{< member-description >}}${this.renderDescription(member.description, knownTypeMap, docsUrl)}{{< /member-description >}}\n\n`;
         }