Skip to content

Commit 44df799

Browse files
fix: Remove propTypes + defaultProps from <Chip>, <Toast>, <FormLabel> and <IconButton> (#3789)
* refactor: remove propTypes and defaultProps Chip * refactor: remove propTypes and defaultProps Toast * refactor: remove propTypes and defaultProps FormLabel * refactor: remove propTypes and defaultProps IconButton * fix: changing docstring, hardcoding default values * fix: iconButton forwardedref syntax * chore: add missing default value for iconButton * chore: address feedback on docs * chore: address feedback on docs * docs: add links to type definition * docs: add back deprecated comment for icon FA
1 parent 63e8704 commit 44df799

File tree

4 files changed

+66
-190
lines changed

4 files changed

+66
-190
lines changed

src/Chip/index.tsx

Lines changed: 26 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,59 @@
11
import React, { ForwardedRef, KeyboardEventHandler, MouseEventHandler } from 'react';
2-
import PropTypes, { type Requireable } from 'prop-types';
32
import classNames from 'classnames';
4-
// @ts-ignore
5-
import { requiredWhen } from '../utils/propTypes';
6-
import { STYLE_VARIANTS } from './constants';
73
import ChipIcon from './ChipIcon';
4+
import { STYLE_VARIANTS } from './constants';
85

96
export const CHIP_PGN_CLASS = 'pgn__chip';
107

118
export interface IChip {
9+
/** Specifies the content of the `Chip`. */
1210
children: React.ReactNode,
11+
/** Click handler for the whole `Chip`, has effect only when Chip does not have any interactive icons. */
1312
onClick?: KeyboardEventHandler & MouseEventHandler,
13+
/** Specifies an additional `className` to add to the base element. */
1414
className?: string,
15+
/** The `Chip` style [variant](https://github.com/openedx/paragon/blob/release-23.x/src/Chip/constants.ts) to use. */
1516
variant?: typeof STYLE_VARIANTS[keyof typeof STYLE_VARIANTS],
17+
/**
18+
* An icon component to render before the content.
19+
* Example import of a Paragon icon component:
20+
*
21+
* `import { Check } from '@openedx/paragon/icons';`
22+
*/
1623
iconBefore?: React.ComponentType,
24+
/** Specifies icon alt text. */
1725
iconBeforeAlt?: string,
26+
/**
27+
* An icon component to render before after the content.
28+
* Example import of a Paragon icon component:
29+
*
30+
* `import { Check } from '@openedx/paragon/icons';`
31+
*/
1832
iconAfter?: React.ComponentType,
33+
/** Specifies icon alt text. */
1934
iconAfterAlt?: string,
35+
/** A click handler for the `Chip` icon before. */
2036
onIconBeforeClick?: KeyboardEventHandler & MouseEventHandler,
37+
/** A click handler for the `Chip` icon after. */
2138
onIconAfterClick?: KeyboardEventHandler & MouseEventHandler,
39+
/** Disables the `Chip`. */
2240
disabled?: boolean,
41+
/** Indicates if `Chip` has been selected. */
2342
isSelected?: boolean,
2443
}
2544

2645
const Chip = React.forwardRef(({
2746
children,
2847
className,
29-
variant,
48+
variant = 'light',
3049
iconBefore,
3150
iconBeforeAlt,
3251
iconAfter,
3352
iconAfterAlt,
3453
onIconBeforeClick,
3554
onIconAfterClick,
36-
disabled,
37-
isSelected,
55+
disabled = false,
56+
isSelected = false,
3857
onClick,
3958
...props
4059
}: IChip, ref: ForwardedRef<HTMLDivElement>) => {
@@ -92,56 +111,4 @@ const Chip = React.forwardRef(({
92111
);
93112
});
94113

95-
Chip.propTypes = {
96-
/** Specifies the content of the `Chip`. */
97-
// @ts-ignore
98-
children: PropTypes.node.isRequired,
99-
/** Specifies an additional `className` to add to the base element. */
100-
className: PropTypes.string,
101-
/** The `Chip` style variant to use. */
102-
variant: PropTypes.oneOf(['light', 'dark']),
103-
/** Disables the `Chip`. */
104-
disabled: PropTypes.bool,
105-
/** Click handler for the whole Chip, has effect only when Chip does not have any interactive icons. */
106-
onClick: PropTypes.func,
107-
/**
108-
* An icon component to render before the content.
109-
* Example import of a Paragon icon component:
110-
*
111-
* `import { Check } from '@openedx/paragon/icons';`
112-
*/
113-
iconBefore: PropTypes.elementType as Requireable<React.ComponentType>,
114-
/** Specifies icon alt text. */
115-
iconBeforeAlt: requiredWhen(PropTypes.string, ['iconBefore', 'onIconBeforeClick']),
116-
/** A click handler for the `Chip` icon before. */
117-
onIconBeforeClick: PropTypes.func,
118-
/**
119-
* An icon component to render before after the content.
120-
* Example import of a Paragon icon component:
121-
*
122-
* `import { Check } from '@openedx/paragon/icons';`
123-
*/
124-
iconAfter: PropTypes.elementType as Requireable<React.ComponentType>,
125-
/** Specifies icon alt text. */
126-
iconAfterAlt: requiredWhen(PropTypes.string, ['iconAfter', 'onIconAfterClick']),
127-
/** A click handler for the `Chip` icon after. */
128-
onIconAfterClick: PropTypes.func,
129-
/** Indicates if `Chip` has been selected. */
130-
isSelected: PropTypes.bool,
131-
};
132-
133-
Chip.defaultProps = {
134-
className: undefined,
135-
variant: STYLE_VARIANTS.LIGHT,
136-
disabled: false,
137-
onClick: undefined,
138-
iconBefore: undefined,
139-
iconAfter: undefined,
140-
onIconBeforeClick: undefined,
141-
onIconAfterClick: undefined,
142-
isSelected: false,
143-
iconAfterAlt: undefined,
144-
iconBeforeAlt: undefined,
145-
};
146-
147114
export default Chip;

src/Form/FormLabel.tsx

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import PropTypes from 'prop-types';
32
import classNames from 'classnames';
43
import { useFormGroupContext } from './FormGroupContext';
54
import { FORM_CONTROL_SIZES } from './constants';
@@ -9,6 +8,8 @@ interface Props {
98
children: React.ReactNode;
109
/** Specifies whether the component should be displayed with inline styling. */
1110
isInline?: boolean;
11+
/** Specifies an additional `className` to add to the base element. */
12+
className?: string;
1213
}
1314

1415
function FormLabel({ children, isInline = false, ...props }: Props & React.ComponentPropsWithoutRef<'label'>) {
@@ -27,13 +28,4 @@ function FormLabel({ children, isInline = false, ...props }: Props & React.Compo
2728
return React.createElement(componentType, labelProps, children);
2829
}
2930

30-
FormLabel.propTypes = {
31-
/** Specifies class name to append to the base element. */
32-
className: PropTypes.string,
33-
/** Specifies contents of the component. */
34-
children: PropTypes.node.isRequired,
35-
/** Specifies whether the component should be displayed with inline styling. */
36-
isInline: PropTypes.bool,
37-
};
38-
3931
export default FormLabel;

src/IconButton/index.tsx

Lines changed: 17 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React from 'react';
2-
import PropTypes from 'prop-types';
32
import classNames from 'classnames';
43
import { type Placement } from 'react-bootstrap/Overlay';
54
import { OverlayTrigger } from '../Overlay';
65
import Tooltip from '../Tooltip';
76
import Icon from '../Icon';
87

98
interface Props extends React.HTMLAttributes<HTMLButtonElement> {
9+
/** Component that renders the icon, currently defaults to `Icon` */
1010
iconAs?: React.ComponentType<any>,
1111
/** Additional CSS class[es] to apply to this button */
1212
className?: string;
@@ -26,33 +26,33 @@ interface Props extends React.HTMLAttributes<HTMLButtonElement> {
2626
iconClassNames?: string;
2727
/** Click handler for the button */
2828
onClick?: React.MouseEventHandler<HTMLButtonElement>;
29-
/** whether to show the `IconButton` in an active state, whose styling is distinct from default state */
29+
/** Whether to show the `IconButton` in an active state, whose styling is distinct from default state */
3030
isActive?: boolean;
3131
/** @deprecated Using FontAwesome icons is deprecated. Instead, pass iconAs={Icon} src={...} */
3232
icon?: { prefix?: string; iconName?: string, icon?: any[] },
33-
/** Type of button (uses Bootstrap options) */
33+
/** Type of button (uses Bootstrap options). */
3434
variant?: 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'light' | 'dark' | 'black' | 'brand';
35-
/** size of button to render */
35+
/** Size of button to render */
3636
size?: 'sm' | 'md' | 'inline';
37-
/** no children */
37+
/** No children */
3838
children?: never;
3939
}
4040

41-
const IconButton = React.forwardRef<HTMLButtonElement, Props>(({
41+
const IconButton = React.forwardRef(({
4242
className,
4343
alt,
44-
invertColors,
44+
invertColors = false,
4545
icon,
4646
src,
4747
iconClassNames,
48-
onClick,
49-
size,
50-
variant,
51-
iconAs,
52-
isActive,
48+
onClick = () => {},
49+
size = 'md',
50+
variant = 'primary',
51+
iconAs = Icon,
52+
isActive = false,
5353
children, // unused, just here because we don't want it to be part of 'attrs'
5454
...attrs
55-
}, ref) => {
55+
} : Props, ref: React.ForwardedRef<HTMLButtonElement>) => {
5656
const invert = invertColors ? 'inverse-' : '';
5757
const activeStyle = isActive ? `${variant}-` : '';
5858
const IconComponent = iconAs;
@@ -87,66 +87,18 @@ const IconButton = React.forwardRef<HTMLButtonElement, Props>(({
8787
);
8888
});
8989

90-
IconButton.defaultProps = {
91-
iconAs: Icon,
92-
src: undefined,
93-
icon: undefined,
94-
iconClassNames: undefined,
95-
className: undefined,
96-
invertColors: false,
97-
variant: 'primary',
98-
size: 'md',
99-
onClick: () => {},
100-
isActive: false,
101-
children: undefined,
102-
};
103-
104-
IconButton.propTypes = {
105-
/** A custom class name. */
106-
className: PropTypes.string,
107-
/** Component that renders the icon, currently defaults to `Icon` */
108-
iconAs: PropTypes.elementType as any,
109-
/** An icon component to render. Example import of a Paragon icon component:
110-
* `import { Check } from '@openedx/paragon/icons';`
111-
* */
112-
src: PropTypes.elementType as any,
113-
/** Alt text for your icon. For best practice, avoid using alt text to describe
114-
* the image in the `IconButton`. Instead, we recommend describing the function
115-
* of the button. */
116-
alt: PropTypes.string.isRequired,
117-
/** Changes icon styles for dark background */
118-
invertColors: PropTypes.bool,
119-
/** Accepts a [Paragon icon](https://paragon-openedx.netlify.app/foundations/icons) */
120-
icon: PropTypes.shape({
121-
prefix: PropTypes.string,
122-
iconName: PropTypes.string,
123-
// eslint-disable-next-line react/forbid-prop-types
124-
icon: PropTypes.array,
125-
}) as any,
126-
/** Extra class names that will be added to the icon */
127-
iconClassNames: PropTypes.string,
128-
/** Click handler for the button */
129-
onClick: PropTypes.func,
130-
/** Type of button (uses Bootstrap options) */
131-
variant: PropTypes.oneOf(['primary', 'secondary', 'success', 'warning', 'danger', 'light', 'dark', 'black', 'brand']),
132-
/** size of button to render */
133-
size: PropTypes.oneOf(['sm', 'md', 'inline']),
134-
/** whether to show the `IconButton` in an active state, whose styling is distinct from default state */
135-
isActive: PropTypes.bool,
136-
};
137-
13890
interface PropsWithTooltip extends Props {
139-
/** choose from https://popper.js.org/docs/v2/constructors/#options */
140-
tooltipPlacement: Placement,
141-
/** any content to pass to tooltip content area */
91+
/** Tooltip placement can be top, left, right etc, choose from https://popper.js.org/docs/v2/constructors/#options */
92+
tooltipPlacement?: Placement,
93+
/** Any content to pass to tooltip content area */
14294
tooltipContent: React.ReactNode,
14395
}
14496

14597
/**
14698
* An icon button wrapped in overlaytrigger to display a tooltip.
14799
*/
148100
function IconButtonWithTooltip({
149-
tooltipPlacement, tooltipContent, ...props
101+
tooltipPlacement = 'top', tooltipContent, ...props
150102
}: PropsWithTooltip) {
151103
const invert = props.invertColors ? 'inverse-' : '';
152104
return (
@@ -166,22 +118,6 @@ function IconButtonWithTooltip({
166118
);
167119
}
168120

169-
IconButtonWithTooltip.defaultProps = {
170-
...IconButton.defaultProps,
171-
tooltipPlacement: 'top',
172-
};
173-
174-
IconButtonWithTooltip.propTypes = {
175-
/** tooltip placement can be top, left, right etc, per https://popper.js.org/docs/v2/constructors/#options */
176-
tooltipPlacement: PropTypes.string,
177-
/** any valid JSX or text to be rendered as tooltip contents */
178-
tooltipContent: PropTypes.node.isRequired,
179-
/** Type of button (uses Bootstrap options) */
180-
variant: PropTypes.oneOf(['primary', 'secondary', 'success', 'warning', 'danger', 'light', 'dark', 'black', 'brand']),
181-
/** Changes icon styles for dark background */
182-
invertColors: PropTypes.bool,
183-
};
184-
185121
(IconButton as any).IconButtonWithTooltip = IconButtonWithTooltip;
186122

187123
export default IconButton as typeof IconButton & {

0 commit comments

Comments
 (0)