From 50f9355ec803e19bff1a4a89be140d621280db8c Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 25 Jan 2018 11:53:46 -0800 Subject: [PATCH 01/10] ApiBrowser shows all known TS entities and ApiLink renders link to open browser to given member --- packages/docs-theme/src/common/context.ts | 4 ++ .../src/components/documentation.tsx | 22 +++++++++- .../src/components/typescript/apiBrowser.tsx | 41 +++++++++++++++++ .../src/components/typescript/apiLink.tsx | 36 +++++++++++++++ packages/docs-theme/src/docs-theme.scss | 1 + packages/docs-theme/src/styles/_api.scss | 44 +++++++++++++++++++ 6 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 packages/docs-theme/src/components/typescript/apiBrowser.tsx create mode 100644 packages/docs-theme/src/components/typescript/apiLink.tsx create mode 100644 packages/docs-theme/src/styles/_api.scss diff --git a/packages/docs-theme/src/common/context.ts b/packages/docs-theme/src/common/context.ts index 3be4922367..4498c4607d 100644 --- a/packages/docs-theme/src/common/context.ts +++ b/packages/docs-theme/src/common/context.ts @@ -45,6 +45,9 @@ export interface IDocumentationContext { /** Render the text of a "View source" link. */ renderViewSourceLinkText(entry: ITsDocBase): React.ReactNode; + + /** Open the API browser to the given member name. */ + showApiDocs(name: string): void; } /** @@ -66,6 +69,7 @@ export const DocumentationContextTypes: React.ValidationMap docs, renderBlock: block => renderBlock(block, this.props.tagRenderers), renderType: hasTypescriptData(docs) - ? type => linkify(type, docs.typescript, name => {name}) + ? type => linkify(type, docs.typescript, name => ) : type => type, renderViewSourceLinkText: Utils.isFunction(renderViewSourceLinkText) ? renderViewSourceLinkText : () => "View source", + showApiDocs: this.handleApiBrowserOpen, }; } @@ -138,6 +145,13 @@ export class Documentation extends React.PureComponent + + + ); @@ -248,6 +262,10 @@ export class Documentation extends React.PureComponent + this.setState({ activeApiMember, isApiBrowserOpen: true }); + private handleApiBrowserClose = () => this.setState({ isApiBrowserOpen: false }); } /** Shorthand for element.query() + cast to HTMLElement */ diff --git a/packages/docs-theme/src/components/typescript/apiBrowser.tsx b/packages/docs-theme/src/components/typescript/apiBrowser.tsx new file mode 100644 index 0000000000..ee62017fe1 --- /dev/null +++ b/packages/docs-theme/src/components/typescript/apiBrowser.tsx @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the terms of the LICENSE file distributed with this project. + */ + +import { Classes } from "@blueprintjs/core"; +import * as classNames from "classnames"; +import * as React from "react"; +import { DocumentationContextTypes, hasTypescriptData, IDocumentationContext } from "../../common/context"; +import { TypescriptExample } from "../../tags/typescript"; +import { ApiLink } from "./apiLink"; + +export interface IApiBrowserProps { + section: string; +} + +export class ApiBrowser extends React.PureComponent { + public static contextTypes = DocumentationContextTypes; + public context: IDocumentationContext; + + public render() { + const { section } = this.props; + const data = this.context.getDocsData(); + if (!hasTypescriptData(data)) { + return

No Typescript data found.

; + } + return ( +
+
+ {Object.keys(data.typescript).map(name => ( + + ))} +
+
+ +
+
+ ); + } +} diff --git a/packages/docs-theme/src/components/typescript/apiLink.tsx b/packages/docs-theme/src/components/typescript/apiLink.tsx new file mode 100644 index 0000000000..102e17b90f --- /dev/null +++ b/packages/docs-theme/src/components/typescript/apiLink.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the terms of the LICENSE file distributed with this project. + */ + +import { IProps } from "@blueprintjs/core"; +import * as React from "react"; +import { DocumentationContextTypes, IDocumentationContext } from "../../common/context"; + +export interface IApiLinkProps extends IProps { + children?: never; + name: string; +} + +/** + * Renders a link to open a symbol in the API Browser. + */ +export class ApiLink extends React.PureComponent { + public static contextTypes = DocumentationContextTypes; + public context: IDocumentationContext; + + public render() { + const { className, name } = this.props; + return ( + + {name} + + ); + } + + private handleClick = (evt: React.MouseEvent) => { + evt.preventDefault(); + this.context.showApiDocs(this.props.name); + }; +} diff --git a/packages/docs-theme/src/docs-theme.scss b/packages/docs-theme/src/docs-theme.scss index 0da00bc8b2..993ac38424 100644 --- a/packages/docs-theme/src/docs-theme.scss +++ b/packages/docs-theme/src/docs-theme.scss @@ -3,6 +3,7 @@ Copyright 2015 Palantir Technologies, Inc. All rights reserved. // Licensed under the terms of the LICENSE file distributed with this project. */ +@import "styles/api"; @import "styles/content"; @import "styles/examples"; @import "styles/layout"; diff --git a/packages/docs-theme/src/styles/_api.scss b/packages/docs-theme/src/styles/_api.scss new file mode 100644 index 0000000000..7155271a9d --- /dev/null +++ b/packages/docs-theme/src/styles/_api.scss @@ -0,0 +1,44 @@ +// Copyright 2017 Palantir Technologies, Inc. All rights reserved. +// Licensed under the terms of the LICENSE file distributed with this project. + +@import "variables"; + +.docs-api-dialog { + width: auto; + height: 80vh; + padding: 0; +} + +.docs-api-browser { + display: flex; + flex-direction: row; +} + +.docs-api-list { + display: flex; + flex-direction: column; + flex-shrink: 0; + border-right: 1px solid $pt-divider-black; + width: $pt-grid-size * 20; + overflow: auto; + padding: $pt-grid-size / 2; + + > * { + flex-shrink: 0; + } +} + +.docs-api-content { + flex: 1 1 auto; + width: $content-width; + overflow: auto; + + .docs-modifiers { + margin: $pt-grid-size * 2; + } +} + +.docs-code { + font-family: $pt-font-family-monospace; + font-weight: 600; +} From b325887335e1864a09b25643a9d4e45fb6de32bd Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 25 Jan 2018 12:18:32 -0800 Subject: [PATCH 02/10] simple filter for ApiBrowser --- .../src/components/typescript/apiBrowser.tsx | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/docs-theme/src/components/typescript/apiBrowser.tsx b/packages/docs-theme/src/components/typescript/apiBrowser.tsx index ee62017fe1..7728ca1d1e 100644 --- a/packages/docs-theme/src/components/typescript/apiBrowser.tsx +++ b/packages/docs-theme/src/components/typescript/apiBrowser.tsx @@ -4,33 +4,49 @@ * Licensed under the terms of the LICENSE file distributed with this project. */ -import { Classes } from "@blueprintjs/core"; +import { Classes, InputGroup } from "@blueprintjs/core"; import * as classNames from "classnames"; import * as React from "react"; import { DocumentationContextTypes, hasTypescriptData, IDocumentationContext } from "../../common/context"; import { TypescriptExample } from "../../tags/typescript"; +import { handleStringChange } from "../baseExample"; import { ApiLink } from "./apiLink"; export interface IApiBrowserProps { section: string; } -export class ApiBrowser extends React.PureComponent { +export interface IApiBrowserState { + query: string; +} + +export class ApiBrowser extends React.PureComponent { public static contextTypes = DocumentationContextTypes; public context: IDocumentationContext; + public state: IApiBrowserState = { query: "" }; + private handleQueryChange = handleStringChange(query => this.setState({ query })); + public render() { const { section } = this.props; + const { query } = this.state; const data = this.context.getDocsData(); if (!hasTypescriptData(data)) { return

No Typescript data found.

; } + const filteredLinks = Object.keys(data.typescript) + .filter(name => name.toLowerCase().indexOf(query.toLowerCase()) >= 0) + .map(name => ); return (
- {Object.keys(data.typescript).map(name => ( - - ))} + + {filteredLinks}
From 0c9a858d964e5a6c8fc7e8d891c955efee5b7fd9 Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 25 Jan 2018 12:18:43 -0800 Subject: [PATCH 03/10] simple at-see tag --- packages/docs-theme/src/tags/defaults.ts | 2 +- packages/docs-theme/src/tags/index.ts | 1 + packages/docs-theme/src/tags/see.tsx | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 packages/docs-theme/src/tags/see.tsx diff --git a/packages/docs-theme/src/tags/defaults.ts b/packages/docs-theme/src/tags/defaults.ts index f2d71ca029..6ca96d94c6 100644 --- a/packages/docs-theme/src/tags/defaults.ts +++ b/packages/docs-theme/src/tags/defaults.ts @@ -17,6 +17,6 @@ export function createDefaultRenderers(): Record null, - // TODO: @see + see: tags.SeeTag, }; } diff --git a/packages/docs-theme/src/tags/index.ts b/packages/docs-theme/src/tags/index.ts index ca4d7f1b86..54518731c8 100644 --- a/packages/docs-theme/src/tags/index.ts +++ b/packages/docs-theme/src/tags/index.ts @@ -15,4 +15,5 @@ export * from "./defaults"; export * from "./heading"; export * from "./reactDocs"; export * from "./reactExample"; +export * from "./see"; export * from "./typescript"; diff --git a/packages/docs-theme/src/tags/see.tsx b/packages/docs-theme/src/tags/see.tsx new file mode 100644 index 0000000000..0e91f3ffa5 --- /dev/null +++ b/packages/docs-theme/src/tags/see.tsx @@ -0,0 +1,15 @@ +/* + * Copyright 2017 Palantir Technologies, Inc. All rights reserved. + * + * Licensed under the terms of the LICENSE file distributed with this project. + */ + +import { ITag } from "documentalist/dist/client"; +import * as React from "react"; +import { DocumentationContextTypes, IDocumentationContext } from "../common/context"; + +export const SeeTag: React.SFC = ({ value }, { renderType }: IDocumentationContext) => ( +

See: {renderType(value)}

+); +SeeTag.contextTypes = DocumentationContextTypes; +SeeTag.displayName = "Docs.SeeTag"; From 88d21ecbe98875f202e6b47501addb5db6ced965 Mon Sep 17 00:00:00 2001 From: Gilad Gray Date: Thu, 25 Jan 2018 12:19:04 -0800 Subject: [PATCH 04/10] fix some docs issues discovered through browsing --- packages/core/src/components/menu/menu.md | 6 ++-- packages/table/src/common/cell.ts | 2 +- packages/table/src/common/utils.ts | 28 +------------------ .../src/quadrants/tableQuadrantStackCache.ts | 2 +- packages/table/src/regions.ts | 2 +- 5 files changed, 7 insertions(+), 33 deletions(-) diff --git a/packages/core/src/components/menu/menu.md b/packages/core/src/components/menu/menu.md index 1bc7e96544..537f39f58e 100644 --- a/packages/core/src/components/menu/menu.md +++ b/packages/core/src/components/menu/menu.md @@ -83,7 +83,7 @@ To add a submenu to a `Menu`, simply nest `MenuItem`s within another `MenuItem`. The submenu opens to the right of its parent by default, but will adjust and flip to the left if there is not enough room to the right. -```jsx +```tsx @@ -93,7 +93,7 @@ there is not enough room to the right. Alternatively, you can pass an array of `IMenuItemProps` to the `submenu` prop: -```jsx +```tsx React.createElement(MenuItem, { submenu: [ { text: "Child one" }, @@ -115,7 +115,7 @@ React.createElement(MenuItem, { The `Menu` component by itself simply renders a menu list. To make a dropdown menu, use a `Menu` element as the `content` property of a `Popover`: -```jsx +```tsx ...} position={Position.RIGHT_TOP}>
@@ -86,6 +89,27 @@ export class InterfaceTable extends React.PureComponent { ); }; + private renderIndexSignature(entry?: ITsSignature) { + if (entry == null) { + return null; + } + const { renderBlock, renderType } = this.context; + // HACKHACK: Documentalist's indexSignature support isn't _great_, but it's certainly _good enough_ + // entry.type looks like "{ [name: string]: (date: Date) => boolean }" + const [signature, returnType] = entry.type.slice(2, -2).split("]: "); + return ( + + + {renderType(signature)}] + + + {renderType(returnType)} +
{renderBlock(entry.documentation)}
+ + + ); + } + private renderTags(entry: ITsProperty | ITsMethod) { const { renderType } = this.context; const { flags: { isDeprecated, isOptional }, inheritedFrom } = entry;