Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs] Link to demos and API in IntelliSense #20078

Merged
merged 15 commits into from
Mar 18, 2020
Merged
2 changes: 1 addition & 1 deletion docs/pages/api-docs/menu-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { MenuList } from '@material-ui/core';

You can learn more about the difference by [reading this guide](/guides/minimizing-bundle-size/).

A permanently displayed menu following https://www.w3.org/TR/wai-aria-practices/#menubutton
A permanently displayed menu following https://www.w3.org/TR/wai-aria-practices/#menubutton.
It's exposed to help customization of the [`Menu`](/api/menu/) component. If you
use it separately you need to move focus into the component manually. Once
the focus is placed inside the component it is fully keyboard accessible.
Expand Down
117 changes: 117 additions & 0 deletions docs/scripts/buildApi.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
/* eslint-disable no-console */
import * as babel from '@babel/core';
import traverse from '@babel/traverse';
import { mkdir, readFileSync, writeFileSync } from 'fs';
import { getLineFeed } from './helpers';
import { rewriteUrlForNextExport } from 'next/dist/next-server/lib/router/rewrite-url-for-export';
import path from 'path';
import kebabCase from 'lodash/kebabCase';
import uniqBy from 'lodash/uniqBy';
import { defaultHandlers, parse as docgenParse } from 'react-docgen';
import remark from 'remark';
import remarkVisit from 'unist-util-visit';
import muiDefaultPropsHandler from '../src/modules/utils/defaultPropsHandler';
import generateMarkdown from '../src/modules/utils/generateMarkdown';
import { findPagesMarkdown, findComponents } from '../src/modules/utils/find';
import { getHeaders } from '../src/modules/utils/parseMarkdown';
import parseTest from '../src/modules/utils/parseTest';
import { pageToTitle } from '../src/modules/utils/helpers';
import createMuiTheme from '../../packages/material-ui/src/styles/createMuiTheme';
import getStylesCreator from '../../packages/material-ui-styles/src/getStylesCreator';
import createGenerateClassName from '../../packages/material-ui-styles/src/createGenerateClassName';
Expand Down Expand Up @@ -80,6 +87,114 @@ function getInheritance(testInfo, src) {
};
}

/**
* Produces markdown of the description that can be hosted anywhere.
*
* By default we assume that the markdown is hosted on material-ui.com which is
* why the source includes relative url. We transform them to absolute urls with
* this method.
*
* @param {object} api
* @param {object} options
*/
function computeApiDescription(api, options) {
const { host } = options;
return new Promise((resolve, reject) => {
remark()
.use(function docsLinksAttacher() {
return function transformer(tree) {
remarkVisit(tree, 'link', linkNode => {
if (linkNode.url.startsWith('/')) {
linkNode.url = `${host}${linkNode.url}`;
}
});
};
})
.process(api.description, (error, file) => {
if (error) reject(error);

resolve(file.contents.replace(/\n/g, '\n * '));
});
});
}

async function annotateComponentDefinition(component, api) {
const HOST = 'https://material-ui.com';

const typesFilename = component.filename.replace(/\.js$/, '.d.ts');
const typesSource = readFileSync(typesFilename, { encoding: 'utf8' });
const typesAST = await babel.parseAsync(typesSource, {
configFile: false,
filename: typesFilename,
presets: [require.resolve('@babel/preset-typescript')],
});

let start = null;
let end = null;
traverse(typesAST, {
ExportDefaultDeclaration(babelPath) {
// export default function Menu() {}
let node = babelPath.node;
if (node.declaration.type === 'Identifier') {
// declare const Menu: {};
// export default Menu;
const bindingId = babelPath.node.declaration.name;
const binding = babelPath.scope.bindings[bindingId];
node = binding.path.parentPath.node;
}

const { leadingComments = [] } = node;
const [jsdocBlock, ...rest] = leadingComments;
if (rest.length > 0) {
throw new Error('Should only have a single leading jsdoc block');
}
if (jsdocBlock !== undefined) {
start = jsdocBlock.start;
end = jsdocBlock.end;
} else {
start = node.start - 1;
end = start;
}
},
});

if (end === null || start === 0) {
throw new TypeError(
"Don't know where to insert the jsdoc block. Probably no `default export` found",
);
}

const demos = uniqBy(
api.pagesMarkdown.filter(page => {
return page.components.includes(api.name);
}, []),
page => page.pathname,
);

let inheritanceAPILink = null;
if (api.inheritance !== null) {
const url = api.inheritance.pathname.startsWith('/')
? `${HOST}${rewriteUrlForNextExport(api.inheritance.pathname)}`
: api.inheritance.pathname;

inheritanceAPILink = `[${api.inheritance.component} API](${url})`;
}

const jsdoc = `/**
* ${await computeApiDescription(api, { host: HOST })}
* Demos:
* - ${demos
.map(page => `[${pageToTitle(page)}](${HOST}${rewriteUrlForNextExport(page.pathname)})`)
.join('\n * - ')}
*
* API:
* - [${api.name} API](${HOST}/api/${kebabCase(api.name)}/)
* ${api.inheritance !== null ? `- inherits ${inheritanceAPILink}` : ''}
*/`;
const typesSourceNew = typesSource.slice(0, start) + jsdoc + typesSource.slice(end);
writeFileSync(typesFilename, typesSourceNew, { encoding: 'utf8' });
}

async function buildDocs(options) {
const { component: componentObject, pagesMarkdown } = options;
const src = readFileSync(componentObject.filename, 'utf8');
Expand Down Expand Up @@ -209,6 +324,8 @@ export default function Page() {

console.log('Built markdown docs for', reactAPI.name);
});

await annotateComponentDefinition(componentObject, reactAPI);
}

function run() {
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"deduplicate": "node scripts/deduplicate.js",
"argos": "argos upload test/regressions/screenshots/chrome --token $ARGOS_TOKEN",
"build:codesandbox": "lerna run --parallel --scope \"@material-ui/*\" build",
"docs:api": "rimraf ./docs/pages/api && cross-env BABEL_ENV=test __NEXT_EXPORT_TRAILING_SLASH=true babel-node ./docs/scripts/buildApi.js ./packages/material-ui/src ./docs/pages/api-docs && cross-env BABEL_ENV=test __NEXT_EXPORT_TRAILING_SLASH=true babel-node ./docs/scripts/buildApi.js ./packages/material-ui-lab/src ./docs/pages/api-docs",
"docs:api": "rimraf ./docs/pages/api && cross-env BABEL_ENV=test __NEXT_EXPORT_TRAILING_SLASH=true babel-node ./docs/scripts/buildApi.js ./packages/material-ui/src ./docs/pages/api-docs && cross-env BABEL_ENV=test __NEXT_EXPORT_TRAILING_SLASH=true babel-node ./docs/scripts/buildApi.js ./packages/material-ui-lab/src ./docs/pages/api-docs && yarn prettier",
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
"docs:build": "yarn workspace docs build",
"docs:build-sw": "yarn workspace docs build-sw",
"docs:build-color-preview": "babel-node scripts/buildColorTypes",
Expand Down Expand Up @@ -127,6 +127,7 @@
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-test-renderer": "^16.13.0",
"remark": "^11.0.2",
"rimraf": "^3.0.0",
"rollup": "^1.21.4",
"rollup-plugin-babel": "^4.3.3",
Expand All @@ -141,6 +142,7 @@
"tslint": "5.14.0",
"typescript": "^3.8.2",
"typescript-to-proptypes": "^1.4.0",
"unist-util-visit": "^2.0.2",
"vrtest-mui": "^0.3.3",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9",
Expand Down
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/Alert/Alert.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,14 @@ export type AlertClassKey =
| 'message'
| 'action';

/**
*
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
*
* Demos:
* - [Alert](https://material-ui.com/components/alert/)
*
* API:
* - [Alert API](https://material-ui.com/api/alert/)
* - inherits [Paper API](https://material-ui.com/api/paper/)
*/
export default function Alert(props: AlertProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/AlertTitle/AlertTitle.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ export interface AlertTitleProps

export type AlertTitleClassKey = 'root';

/**
*
*
* Demos:
* -
oliviertassinari marked this conversation as resolved.
Show resolved Hide resolved
*
* API:
* - [AlertTitle API](https://material-ui.com/api/alert-title/)
*
*/
export default function AlertTitle(props: AlertTitleProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,16 @@ export type AutocompleteClassKey =
| 'groupLabel'
| 'groupUl';

/**
*
*
* Demos:
* - [Autocomplete](https://material-ui.com/components/autocomplete/)
eps1lon marked this conversation as resolved.
Show resolved Hide resolved
*
* API:
* - [Autocomplete API](https://material-ui.com/api/autocomplete/)
*
*/
export default function Autocomplete<T>(
props: AutocompleteProps<T> & UseAutocompleteProps<T>,
): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/AvatarGroup/AvatarGroup.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,14 @@ export interface AvatarGroupProps

export type AvatarGroupClassKey = 'root' | 'avatar';

/**
*
*
* Demos:
* - [Avatars](https://material-ui.com/components/avatars/)
*
* API:
* - [AvatarGroup API](https://material-ui.com/api/avatar-group/)
*
*/
export default function AvatarGroup(props: AvatarGroupProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/Pagination/Pagination.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,14 @@ export interface PaginationProps

export type PaginationClassKey = 'root' | 'ul';

/**
*
*
* Demos:
* - [Pagination](https://material-ui.com/components/pagination/)
*
* API:
* - [Pagination API](https://material-ui.com/api/pagination/)
*
*/
export default function Pagination(props: PaginationProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/PaginationItem/PaginationItem.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ export interface PaginationItemTypeMap<P = {}, D extends React.ElementType = 'di
classKey: PaginationItemClassKey;
}

/**
*
*
* Demos:
* - [Pagination](https://material-ui.com/components/pagination/)
*
* API:
* - [PaginationItem API](https://material-ui.com/api/pagination-item/)
*
*/
declare const PaginationItem: OverridableComponent<PaginationItemTypeMap>;

export type PaginationItemClassKey =
Expand Down
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/Rating/Rating.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ export type RatingClassKey =
| 'iconActive'
| 'decimal';

/**
*
*
* Demos:
* - [Rating](https://material-ui.com/components/rating/)
*
* API:
* - [Rating API](https://material-ui.com/api/rating/)
*
*/
declare const Rating: React.ComponentType<RatingProps>;

export default Rating;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/Skeleton/Skeleton.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ export interface SkeletonTypeMap<P = {}, D extends React.ElementType = 'span'> {
classKey: SkeletonClassKey;
}

/**
*
*
* Demos:
* - [Skeleton](https://material-ui.com/components/skeleton/)
*
* API:
* - [Skeleton API](https://material-ui.com/api/skeleton/)
*
*/
declare const Skeleton: OverridableComponent<SkeletonTypeMap>;

export type SkeletonClassKey = 'root' | 'text' | 'rect' | 'circle' | 'pulse' | 'wave';
Expand Down
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/SpeedDial/SpeedDial.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,14 @@ export type SpeedDialClassKey =
| 'actions'
| 'actionsClosed';

/**
*
*
* Demos:
* - [Speed Dial](https://material-ui.com/components/speed-dial/)
*
* API:
* - [SpeedDial API](https://material-ui.com/api/speed-dial/)
*
*/
export default function SpeedDial(props: SpeedDialProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/SpeedDialAction/SpeedDialAction.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,14 @@ export type SpeedDialActionClassKey =
| 'staticTooltipLabel'
| 'tooltipPlacementLeft';

/**
*
*
* Demos:
* - [Speed Dial](https://material-ui.com/components/speed-dial/)
*
* API:
* - [SpeedDialAction API](https://material-ui.com/api/speed-dial-action/)
* - inherits [Tooltip API](https://material-ui.com/api/tooltip/)
*/
export default function SpeedDialAction(props: SpeedDialActionProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/SpeedDialIcon/SpeedDialIcon.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ export type SpeedDialIconClassKey =
| 'openIcon'
| 'openIconOpen';

/**
*
*
* Demos:
* - [Speed Dial](https://material-ui.com/components/speed-dial/)
*
* API:
* - [SpeedDialIcon API](https://material-ui.com/api/speed-dial-icon/)
*
*/
export default function SpeedDialIcon(props: SpeedDialIconProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/ToggleButton/ToggleButton.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ export type ToggleButtonTypeMap<
classKey: ToggleButtonClassKey;
}>;

/**
*
*
* Demos:
* - [Toggle Button](https://material-ui.com/components/toggle-button/)
*
* API:
* - [ToggleButton API](https://material-ui.com/api/toggle-button/)
* - inherits [ButtonBase API](https://material-ui.com/api/button-base/)
*/
declare const ToggleButton: ExtendButtonBase<ToggleButtonTypeMap>;

export type ToggleButtonProps<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,14 @@ export type ToggleButtonGroupClassKey =
| 'groupedSizeSmall'
| 'groupedSizeLarge';

/**
*
*
* Demos:
* - [Toggle Button](https://material-ui.com/components/toggle-button/)
*
* API:
* - [ToggleButtonGroup API](https://material-ui.com/api/toggle-button-group/)
*
*/
export default function ToggleButtonGroup(props: ToggleButtonGroupProps): JSX.Element;
10 changes: 10 additions & 0 deletions packages/material-ui-lab/src/TreeItem/TreeItem.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,14 @@ export type TreeItemClassKey =
| 'iconContainer'
| 'label';

/**
*
*
* Demos:
* - [Tree View](https://material-ui.com/components/tree-view/)
*
* API:
* - [TreeItem API](https://material-ui.com/api/tree-item/)
*
*/
export default function TreeItem(props: TreeItemProps): JSX.Element;
Loading