From c634ac5ab42ec5a835d91433c269da3d5a811854 Mon Sep 17 00:00:00 2001 From: Marija Najdova Date: Fri, 20 Nov 2020 16:19:07 +0100 Subject: [PATCH] [docs] Generate default values for docs from the unstyled components (#23614) --- docs/pages/api-docs/slider.md | 27 ++++++++++++++------------- docs/scripts/buildApi.ts | 31 +++++++++++++++++++++++++++++-- docs/scripts/helpers.js | 20 ++++++++++---------- scripts/generateProptypes.ts | 4 ++-- 4 files changed, 55 insertions(+), 27 deletions(-) diff --git a/docs/pages/api-docs/slider.md b/docs/pages/api-docs/slider.md index 671ec19ad7bc80..026836c7c7e5fd 100644 --- a/docs/pages/api-docs/slider.md +++ b/docs/pages/api-docs/slider.md @@ -32,28 +32,29 @@ The `MuiSlider` name can be used for providing [default props](/customization/gl | aria-labelledby | string | | The id of the element containing a label for the slider. | | aria-valuetext | string | | A string value that provides a user-friendly name for the current value of the slider. | | classes | object | | Override or extend the styles applied to the component. See [CSS API](#css) below for more details. | -| color | 'primary'
| 'secondary'
| | The color of the component. It supports those theme colors that make sense for this component. | +| color | 'primary'
| 'secondary'
| 'primary' | The color of the component. It supports those theme colors that make sense for this component. | | components | { Mark?: elementType, MarkLabel?: elementType, Rail?: elementType, Root?: elementType, Thumb?: elementType, Track?: elementType, ValueLabel?: elementType } | {} | The components used for each slot inside the Slider. Either a string to use a HTML element or a component. | -| componentsProps | object | | The props used for each slot inside the Slider. | +| componentsProps | object | {} | The props used for each slot inside the Slider. | | defaultValue | Array<number>
| number
| | The default element value. Use when the component is not controlled. | -| disabled | bool | | If `true`, the slider is disabled. | +| disabled | bool | false | If `true`, the slider is disabled. | | getAriaLabel | func | | Accepts a function which returns a string value that provides a user-friendly name for the thumb labels of the slider.

**Signature:**
`function(index: number) => string`
*index:* The thumb label's index to format. | | getAriaValueText | func | | Accepts a function which returns a string value that provides a user-friendly name for the current value of the slider.

**Signature:**
`function(value: number, index: number) => string`
*value:* The thumb label's value to format.
*index:* The thumb label's index to format. | -| isRtl | bool | | Indicates whether the theme context has rtl direction. It is set automatically. | -| marks | Array<{ label?: node, value: number }>
| bool
| | Marks indicate predetermined values to which the user can move the slider. If `true` the marks are spaced according the value of the `step` prop. If an array, it should contain objects with `value` and an optional `label` keys. | -| max | number | | The maximum allowed value of the slider. Should not be equal to min. | -| min | number | | The minimum allowed value of the slider. Should not be equal to max. | +| isRtl | bool | false | Indicates whether the theme context has rtl direction. It is set automatically. | +| marks | Array<{ label?: node, value: number }>
| bool
| false | Marks indicate predetermined values to which the user can move the slider. If `true` the marks are spaced according the value of the `step` prop. If an array, it should contain objects with `value` and an optional `label` keys. | +| max | number | 100 | The maximum allowed value of the slider. Should not be equal to min. | +| min | number | 0 | The minimum allowed value of the slider. Should not be equal to max. | | name | string | | Name attribute of the hidden `input` element. | | onChange | func | | Callback function that is fired when the slider's value changed.

**Signature:**
`function(event: object, value: number \| number[]) => void`
*event:* The event source of the callback. **Warning**: This is a generic event not a change event.
*value:* The new value. | | onChangeCommitted | func | | Callback function that is fired when the `mouseup` is triggered.

**Signature:**
`function(event: object, value: number \| number[]) => void`
*event:* The event source of the callback. **Warning**: This is a generic event not a change event.
*value:* The new value. | -| orientation | 'horizontal'
| 'vertical'
| | The slider orientation. | -| scale | func | | A transformation function, to change the scale of the slider. | -| step | number | | The granularity with which the slider can step through values. (A "discrete" slider.) The `min` prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.
When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. | +| orientation | 'horizontal'
| 'vertical'
| 'horizontal' | The slider orientation. | +| scale | func | (x) => x | A transformation function, to change the scale of the slider. | +| step | number | 1 | The granularity with which the slider can step through values. (A "discrete" slider.) The `min` prop serves as the origin for the valid values. We recommend (max - min) to be evenly divisible by the step.
When step is `null`, the thumb can only be slid onto marks provided with the `marks` prop. | | sx | object | | The system prop that allows defining system overrides as well as additional CSS styles. | -| track | 'inverted'
| 'normal'
| false
| | The track presentation:
- `normal` the track will render a bar representing the slider value. - `inverted` the track will render a bar representing the remaining slider value. - `false` the track will render without a bar. | +| track | 'inverted'
| 'normal'
| false
| 'normal' | The track presentation:
- `normal` the track will render a bar representing the slider value. - `inverted` the track will render a bar representing the remaining slider value. - `false` the track will render without a bar. | | value | Array<number>
| number
| | The value of the slider. For ranged sliders, provide an array with two values. | -| valueLabelDisplay | 'auto'
| 'off'
| 'on'
| | Controls when the value label is displayed:
- `auto` the value label will display when the thumb is hovered or focused. - `on` will display persistently. - `off` will never display. | -| valueLabelFormat | func
| string
| | The format function the value label's value.
When a function is provided, it should have the following signature:
- {number} value The value label's value to format - {number} index The value label's index to format | +| valueLabelDisplay | 'auto'
| 'off'
| 'on'
| 'off' | Controls when the value label is displayed:
- `auto` the value label will display when the thumb is hovered or focused. - `on` will display persistently. - `off` will never display. | +| valueLabelFormat | func
| string
| (x) => x | The format function the value label's value.
When a function is provided, it should have the following signature:
- {number} value The value label's value to format - {number} index The value label's index to format | +| component | elementType | 'span' | The component used for the root node. Either a string to use a HTML element or a component. | The `ref` is forwarded to the root element. diff --git a/docs/scripts/buildApi.ts b/docs/scripts/buildApi.ts index c0fc41d5b10208..0e19d8e2122969 100644 --- a/docs/scripts/buildApi.ts +++ b/docs/scripts/buildApi.ts @@ -19,7 +19,7 @@ import { pageToTitle } from 'docs/src/modules/utils/helpers'; import createGenerateClassName from '../../packages/material-ui-styles/src/createGenerateClassName'; import getStylesCreator from '../../packages/material-ui-styles/src/getStylesCreator'; import createMuiTheme from '../../packages/material-ui/src/styles/createMuiTheme'; -import { getLineFeed, getUnstyledDefinitionFilename } from './helpers'; +import { getLineFeed, getUnstyledFilename } from './helpers'; const generateClassName = createGenerateClassName(); @@ -224,7 +224,7 @@ async function updateStylesDefinition(context: { const typesFilename = component.filename.replace(/\.js$/, '.d.ts'); - const unstyledFileName = getUnstyledDefinitionFilename(typesFilename); + const unstyledFileName = getUnstyledFilename(typesFilename, true); try { // If the JSON file doesn't exists try extracting the info from the TS definition @@ -451,6 +451,33 @@ async function buildDocs(options: { throw err; } + const unstyledFileName = getUnstyledFilename(componentObject.filename); + let unstyledSrc; + + // Try to get data for the unstyled component + try { + unstyledSrc = readFileSync(unstyledFileName, 'utf8'); + } catch (err) { + // Unstyled component does not exist + } + + if (unstyledSrc) { + const unstyledReactAPI = docgenParse( + unstyledSrc, + null, + defaultHandlers.concat(muiDefaultPropsHandler), + { + filename: unstyledFileName, + }, + ); + + Object.keys(unstyledReactAPI.props).forEach((prop) => { + if (unstyledReactAPI.props[prop].defaultValue) { + reactAPI.props[prop] = unstyledReactAPI.props[prop]; + } + }); + } + reactAPI.name = name; reactAPI.styles = styles; reactAPI.pagesMarkdown = pagesMarkdown; diff --git a/docs/scripts/helpers.js b/docs/scripts/helpers.js index d999761cf83106..ae21845e57cfe3 100644 --- a/docs/scripts/helpers.js +++ b/docs/scripts/helpers.js @@ -27,23 +27,23 @@ function fixLineEndings(source, target) { /** * Converts styled or regular component d.ts file to unstyled d.ts * - * @param {string} tsFile - the definition file of the styled or regular mui component + * @param {string} filename - the file of the styled or regular mui component */ -function getUnstyledDefinitionFilename(tsFile) { - if (tsFile.indexOf('Unstyled') > -1) { - return tsFile; +function getUnstyledFilename(filename, definitionFile = false) { + if (filename.indexOf('Unstyled') > -1) { + return filename; } let unstyledFile = ''; - const separator = tsFile.indexOf('/') > -1 ? '/' : '\\'; + const separator = filename.indexOf('/') > -1 ? '/' : '\\'; - if (tsFile.endsWith('.d.ts') && tsFile.indexOf('material-ui-unstyled') === -1) { - unstyledFile = tsFile; + if (filename.indexOf('material-ui-unstyled') === -1) { + unstyledFile = filename.replace('.d.ts', '').replace('.ts', '').replace('.js', ''); unstyledFile = unstyledFile.replace(/Styled/g, ''); const pathParts = unstyledFile.split(separator); - const componentName = pathParts[pathParts.length - 1].replace('.d.ts', ''); + const componentName = pathParts[pathParts.length - 1]; const directoryName = pathParts[pathParts.length - 2]; const componentNameReg = new RegExp(componentName, 'g'); @@ -68,12 +68,12 @@ function getUnstyledDefinitionFilename(tsFile) { } } - return unstyledFile; + return definitionFile ? `${unstyledFile}.d.ts` : `${unstyledFile}.js`; } module.exports = { getLineFeed, fixBabelGeneratorIssues, fixLineEndings, - getUnstyledDefinitionFilename, + getUnstyledFilename, }; diff --git a/scripts/generateProptypes.ts b/scripts/generateProptypes.ts index 712cce5f2ab7e6..0ec4d06f537892 100644 --- a/scripts/generateProptypes.ts +++ b/scripts/generateProptypes.ts @@ -9,7 +9,7 @@ import * as yargs from 'yargs'; import { fixBabelGeneratorIssues, fixLineEndings, - getUnstyledDefinitionFilename, + getUnstyledFilename, } from '../docs/scripts/helpers'; enum GenerateResult { @@ -231,7 +231,7 @@ async function generateProptypes( const isTsFile = /(\.(ts|tsx))/.test(sourceFile); - const unstyledFile = getUnstyledDefinitionFilename(tsFile); + const unstyledFile = getUnstyledFilename(tsFile, true); const result = ttp.inject(proptypes, sourceContent, { disableTypescriptPropTypesValidation: tsTodo,