Skip to content

Commit

Permalink
[Pagination] Leverage @default over default values (#19966)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Mar 4, 2020
1 parent 0055e50 commit 89c0ed4
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 17 deletions.
37 changes: 31 additions & 6 deletions docs/src/modules/utils/defaultPropsHandler.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const astTypes = require('ast-types');
const { parse: parseDoctrine } = require('doctrine');
const { utils: docgenUtils } = require('react-docgen');

const { getPropertyName, isReactForwardRefCall, printValue, resolveToValue } = docgenUtils;
Expand All @@ -8,7 +9,12 @@ const { getPropertyName, isReactForwardRefCall, printValue, resolveToValue } = d

const { namedTypes: types } = astTypes;

function getDefaultValue(path) {
function getDefaultValue(propertyPath) {
if (!types.AssignmentPattern.check(propertyPath.get('value').node)) {
return null;
}
let path = propertyPath.get('value', 'right');

let node = path.node;
let defaultValue;
if (types.Literal.check(node)) {
Expand Down Expand Up @@ -39,19 +45,38 @@ function getDefaultValue(path) {
return null;
}

function getJsdocDefaultValue(jsdoc) {
const defaultTag = jsdoc.tags.find(tag => tag.title === 'default');
if (defaultTag === undefined) {
return undefined;
}
return { value: defaultTag.description };
}

function getDefaultValuesFromProps(properties, documentation) {
properties
.filter(propertyPath => types.Property.check(propertyPath.node))
// Don't evaluate property if component is functional and the node is not an AssignmentPattern
.filter(propertyPath => types.AssignmentPattern.check(propertyPath.get('value').node))
.forEach(propertyPath => {
const propName = getPropertyName(propertyPath);
if (!propName) return;

const propDescriptor = documentation.getPropDescriptor(propName);
const defaultValue = getDefaultValue(propertyPath.get('value', 'right'));
if (defaultValue) {
propDescriptor.defaultValue = defaultValue;

const jsdocDefaultValue = getJsdocDefaultValue(
parseDoctrine(propDescriptor.description, {
sloppy: true,
}),
);
const defaultValue = getDefaultValue(propertyPath);

if (jsdocDefaultValue != null && defaultValue != null) {
throw new Error(
`Can't have JavaScript default value and jsdoc @defaultValue in prop '${propName}'. Remove the @defaultValue if you need the JavaScript default value at runtime.`,
);
}
const usedDefaultValue = defaultValue || jsdocDefaultValue;
if (usedDefaultValue) {
propDescriptor.defaultValue = usedDefaultValue;
}
});
}
Expand Down
30 changes: 19 additions & 11 deletions packages/material-ui-lab/src/Pagination/Pagination.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,29 @@ function defaultGetAriaLabel(type, page, selected) {
}

const Pagination = React.forwardRef(function Pagination(props, ref) {
/* eslint-disable no-unused-vars */
const {
boundaryCount = 1,
boundaryCount,
children,
classes,
className,
color = 'standard',
count = 1,
defaultPage = 1,
disabled = false,
count,
defaultPage,
disabled,
getItemAriaLabel: getAriaLabel = defaultGetAriaLabel,
hideNextButton = false,
hidePrevButton = false,
hideNextButton,
hidePrevButton,
onChange,
page,
renderItem = item => <PaginationItem {...item} />,
shape = 'round',
showFirstButton = false,
showLastButton = false,
siblingCount = 1,
showFirstButton,
showLastButton,
siblingCount,
size = 'medium',
variant = 'text',
...other
} = props;
/* eslint-enable no-unused-vars */

const { items } = usePagination({ ...props, componentName: 'Pagination' });

Expand Down Expand Up @@ -81,9 +79,11 @@ const Pagination = React.forwardRef(function Pagination(props, ref) {
);
});

// @default tags synced with default values from usePagination
Pagination.propTypes = {
/**
* Number of always visible pages at the beginning and end.
* @default 1
*/
boundaryCount: PropTypes.number,
/**
Expand All @@ -105,14 +105,17 @@ Pagination.propTypes = {
color: PropTypes.oneOf(['default', 'primary', 'secondary']),
/**
* The total number of pages.
* @default 1
*/
count: PropTypes.number,
/**
* The page selected by default when the component is uncontrolled.
* @default 1
*/
defaultPage: PropTypes.number,
/**
* If `true`, all the pagination component will be disabled.
* @default false
*/
disabled: PropTypes.bool,
/**
Expand All @@ -128,10 +131,12 @@ Pagination.propTypes = {
getItemAriaLabel: PropTypes.func,
/**
* If `true`, hide the next-page button.
* @default false
*/
hideNextButton: PropTypes.bool,
/**
* If `true`, hide the previous-page button.
* @default false
*/
hidePrevButton: PropTypes.bool,
/**
Expand All @@ -158,14 +163,17 @@ Pagination.propTypes = {
shape: PropTypes.oneOf(['round', 'rounded']),
/**
* If `true`, show the first-page button.
* @default false
*/
showFirstButton: PropTypes.bool,
/**
* If `true`, show the last-page button.
* @default false
*/
showLastButton: PropTypes.bool,
/**
* Number of always visible pages before and after the current page.
* @default 1
*/
siblingCount: PropTypes.number,
/**
Expand Down
1 change: 1 addition & 0 deletions packages/material-ui-lab/src/Pagination/usePagination.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useControlled } from '@material-ui/core/utils';

export default function usePagination(props = {}) {
// keep default values in sync with @default tags in Pagination.propTypes
const {
boundaryCount: boundaryCountProp = 1,
componentName = 'usePagination',
Expand Down

0 comments on commit 89c0ed4

Please sign in to comment.