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

[Pagination] Leverage @default over default values #19966

Merged
merged 3 commits into from
Mar 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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