Log prop-types warnings to console in development (#14635)

* enable debug for warnings in dev env

* remove preact/devtools call no longer needed

* fix majority of proptype errors on home page

* sweep up proptype errors from listings page

* fix article form error
This commit is contained in:
Suzanne Aitchison 2021-09-01 09:27:58 +01:00 committed by GitHub
parent e45b6c5ab2
commit dcecc8bf00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 61 additions and 44 deletions

View file

@ -10,11 +10,13 @@ export const Tabs = ({ onPreview, previewShowing }) => {
<ul className="crayons-tabs__list">
<li>
<button
data-text='Edit'
data-text="Edit"
className={`crayons-tabs__item ${
previewShowing ? '' : 'crayons-tabs__item--current'
}`}
onClick={previewShowing && onPreview}
onClick={(e) => {
previewShowing && onPreview(e);
}}
type="button"
aria-current={previewShowing ? null : 'page'}
>
@ -23,11 +25,13 @@ export const Tabs = ({ onPreview, previewShowing }) => {
</li>
<li>
<button
data-text='Preview'
data-text="Preview"
className={`crayons-tabs__item ${
previewShowing ? 'crayons-tabs__item--current' : ''
}`}
onClick={!previewShowing && onPreview}
onClick={(e) => {
!previewShowing && onPreview(e);
}}
type="button"
aria-current={previewShowing ? 'page' : null}
>

View file

@ -29,5 +29,5 @@ export const LoadingArticle = ({ version }) => {
);
};
LoadingArticle.propTypes = {
version: PropTypes.string.isRequired,
version: PropTypes.string,
};

View file

@ -37,7 +37,7 @@ PublishDate.defaultProps = {
PublishDate.propTypes = {
readablePublishDate: PropTypes.string.isRequired,
publishedTimestamp: PropTypes.string,
publishedAtInt: PropTypes.string,
publishedAtInt: PropTypes.number,
};
PublishDate.displayName = 'PublishDate';

View file

@ -29,8 +29,7 @@ export const SearchSnippet = ({ highlightText }) => {
};
SearchSnippet.propTypes = {
// eslint-disable-next-line no-underscore-dangle
highlightText: articleSnippetResultPropTypes.isRequired,
highlightText: articleSnippetResultPropTypes,
};
SearchSnippet.displayName = 'SearchSnippet';

View file

@ -1,5 +1,5 @@
import { h } from 'preact';
import { tagPropTypes } from '../../common-prop-types';
import PropTypes from 'prop-types';
export const TagList = ({ tags = [], flare_tag }) => {
let tagsToDisplay = tags;
@ -22,7 +22,7 @@ export const TagList = ({ tags = [], flare_tag }) => {
</a>
)}
{tagsToDisplay.map((tag) => (
<a className="crayons-tag" href={`/t/${tag}`}>
<a key={`tag-${tag}`} className="crayons-tag" href={`/t/${tag}`}>
<span className="crayons-tag__prefix">#</span>
{tag}
</a>
@ -32,7 +32,7 @@ export const TagList = ({ tags = [], flare_tag }) => {
};
TagList.propTypes = {
tags: tagPropTypes.isRequired,
tags: PropTypes.arrayOf(PropTypes.string).isRequired,
};
TagList.displayName = 'TagList';

View file

@ -1,5 +1,4 @@
import PropTypes from 'prop-types';
import { tagPropTypes } from './tag-prop-types';
import { organizationPropType } from './organization-prop-type';
export const articleSnippetResultPropTypes = PropTypes.shape({
@ -11,10 +10,14 @@ export const articlePropTypes = PropTypes.shape({
title: PropTypes.string.isRequired,
path: PropTypes.string.isRequired,
cloudinary_video_url: PropTypes.string,
video_duration_in_minutes: PropTypes.number,
video_duration_in_minutes: PropTypes.string,
type_of: PropTypes.oneOf(['podcast_episodes']),
class_name: PropTypes.oneOf(['PodcastEpisode', 'User', 'Article']),
flare_tag: tagPropTypes,
flare_tag: PropTypes.shape({
name: PropTypes.string.isRequired,
bg_color_hex: PropTypes.string,
text_color_hex: PropTypes.string,
}),
tag_list: PropTypes.arrayOf(PropTypes.string),
cached_tag_list_array: PropTypes.arrayOf(PropTypes.string),
podcast: PropTypes.shape({
@ -22,7 +25,7 @@ export const articlePropTypes = PropTypes.shape({
title: PropTypes.string.isRequired,
image_url: PropTypes.string.isRequired,
}),
user_id: PropTypes.string.isRequired,
user_id: PropTypes.number.isRequired,
user: PropTypes.shape({
username: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,

View file

@ -1,6 +1,5 @@
export * from './user-prop-types';
export * from './default-children-prop-types';
export * from './organization-prop-type';
export * from './tag-prop-types';
export * from './article-prop-types';
export * from './selected-tags-prop-types';

View file

@ -1,10 +0,0 @@
import PropTypes from 'prop-types';
export const tagPropTypes = PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
hotness_score: PropTypes.number.isRequired,
points: PropTypes.number.isRequired,
bg_color_hex: PropTypes.string.isRequired,
text_color_hex: PropTypes.string.isRequired,
});

View file

@ -43,10 +43,10 @@ export const Button = (props) => {
const {
children,
variant = 'primary',
tagName = 'button',
tagName,
inverted,
contentType = 'text',
size = 'default',
contentType,
size,
className,
icon,
url,
@ -121,10 +121,13 @@ Button.defaultProps = {
onBlur: undefined,
tabIndex: undefined,
title: undefined,
tagName: 'button',
size: 'default',
contentType: 'text',
};
Button.propTypes = {
children: defaultChildrenPropTypes.isRequired,
children: defaultChildrenPropTypes,
variant: PropTypes.oneOf([
'primary',
'secondary',
@ -146,7 +149,7 @@ Button.propTypes = {
inverted: PropTypes.bool,
tagName: PropTypes.oneOf(['a', 'button']).isRequired,
className: PropTypes.string,
icon: PropTypes.node,
icon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
url: PropTypes.string,
buttonType: PropTypes.string,
disabled: PropTypes.bool,

View file

@ -64,7 +64,7 @@ const CloseIcon = () => (
*/
export const Modal = ({
children,
size = 'default',
size,
className,
title,
overlay = true,
@ -120,6 +120,10 @@ export const Modal = ({
Modal.displayName = 'Modal';
Modal.defaultProps = {
size: 'default',
};
Modal.propTypes = {
children: defaultChildrenPropTypes.isRequired,
className: PropTypes.string,

View file

@ -1,6 +1,5 @@
import { h, Fragment } from 'preact';
import PropTypes from 'prop-types';
import { tagPropTypes } from '../common-prop-types';
export const TagsFollowed = ({ tags = [] }) => {
return (
@ -25,6 +24,13 @@ export const TagsFollowed = ({ tags = [] }) => {
};
TagsFollowed.displayName = 'TagsFollowed';
TagsFollowed.propTypes = {
tags: PropTypes.arrayOf(tagPropTypes).isRequired,
};
TagsFollowed.propTypes = PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
hotness_score: PropTypes.number.isRequired,
points: PropTypes.number.isRequired,
bg_color_hex: PropTypes.string.isRequired,
text_color_hex: PropTypes.string.isRequired,
}),
);

View file

@ -36,10 +36,12 @@ export const ListingFilters = ({
};
ListingFilters.propTypes = {
categories: PropTypes.shape({
slug: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}).isRequired,
categories: PropTypes.arrayOf(
PropTypes.shape({
slug: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
}),
).isRequired,
category: PropTypes.string.isRequired,
onSelectCategory: PropTypes.func.isRequired,
message: PropTypes.isRequired,

View file

@ -36,7 +36,10 @@ export const Header = ({
{title}
</a>
</h2>
<DateTime dateTime={listingDate} className="single-listing__date" />
<DateTime
dateTime={new Date(listingDate)}
className="single-listing__date"
/>
<TagLinks tags={listing.tags || listing.tag_list} onClick={onAddTag} />
<DropdownMenu

View file

@ -177,7 +177,10 @@ KeyboardShortcuts.propTypes = {
options: PropTypes.shape({
timeout: PropTypes.number,
}),
eventTarget: PropTypes.instanceOf(Element),
eventTarget: PropTypes.oneOfType([
PropTypes.instanceOf(Element),
PropTypes.instanceOf(Window),
]),
};
KeyboardShortcuts.defaultProps = {

View file

@ -3,17 +3,18 @@
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const environment = require('./environment');
const config = environment.toWebpackConfig();
// For more information, see https://webpack.js.org/configuration/devtool/#devtool
config.devtool = 'eval-source-map';
// Inject the preact/devtools import into all the webpacker pack files (webpack entry points) that reference at least one Preact component
// Inject the preact/debug import into all the webpacker pack files (webpack entry points) that reference at least one Preact component
// so that Preact compoonents can be debugged with the Preact DevTools.
config.entry = Object.entries(config.entry).reduce(
(previous, [entryPointName, entryPointFileName]) => {
if (/\.jsx$/.test(entryPointFileName)) {
previous[entryPointName] = ['preact/devtools', entryPointFileName];
previous[entryPointName] = ['preact/debug', entryPointFileName];
} else {
previous[entryPointName] = entryPointFileName;
}