diff --git a/src/components/accordion/Accordion.js b/src/components/accordion/Accordion.js index af03b79c7..50b914977 100644 --- a/src/components/accordion/Accordion.js +++ b/src/components/accordion/Accordion.js @@ -14,13 +14,13 @@ const Accordion = props => { let { children, active_item, - always_open, - start_collapsed, loading_state, key, setProps, class_name, className, + always_open = false, + start_collapsed = false, ...otherProps } = props; children = parseChildrenToArray(children); @@ -87,11 +87,9 @@ const Accordion = props => { ); }; -Accordion.defaultProps = { +Accordion.dashPersistence = { persisted_props: ['active_item'], - persistence_type: 'local', - start_collapsed: false, - always_open: false + persistence_type: 'local' }; Accordion.propTypes = { diff --git a/src/components/accordion/AccordionItem.js b/src/components/accordion/AccordionItem.js index c53028768..7602ed7c0 100644 --- a/src/components/accordion/AccordionItem.js +++ b/src/components/accordion/AccordionItem.js @@ -35,11 +35,7 @@ const AccordionItem = ({ (loading_state && loading_state.is_loading) || undefined } > - { - toggle(itemID); - }} - > + toggle(itemID)}> {title} {children} diff --git a/src/components/alert/Alert.js b/src/components/alert/Alert.js index 299e1e68a..f478df413 100644 --- a/src/components/alert/Alert.js +++ b/src/components/alert/Alert.js @@ -10,22 +10,20 @@ import {bootstrapColors} from '../../private/BootstrapColors'; * Control the visibility using callbacks with the `is_open` prop, or set it to * auto-dismiss with the `duration` prop. */ -const Alert = props => { - const { - children, - dismissable, - duration, - is_open, - loading_state, - setProps, - color, - style, - class_name, - className, - fade, - ...otherProps - } = props; - +const Alert = ({ + children, + dismissable, + loading_state, + setProps, + style, + class_name, + className, + fade, + color = 'success', + is_open = true, + duration = null, + ...otherProps +}) => { const timeout = useRef(null); useEffect(() => { @@ -69,10 +67,7 @@ const Alert = props => { ); }; -Alert.defaultProps = { - color: 'success', - is_open: true, - duration: null, +Alert.dashPersistence = { persisted_props: ['is_open'], persistence_type: 'local' }; diff --git a/src/components/badge/Badge.js b/src/components/badge/Badge.js index ee0ac9366..ffd612700 100644 --- a/src/components/badge/Badge.js +++ b/src/components/badge/Badge.js @@ -14,18 +14,20 @@ const Badge = props => { href, loading_state, setProps, - color, style, className, class_name, text_color, + color = 'secondary', + n_clicks = 0, + n_clicks_timestamp = -1, ...otherProps } = props; const incrementClicks = () => { if (setProps) { setProps({ - n_clicks: props.n_clicks + 1, + n_clicks: n_clicks + 1, n_clicks_timestamp: Date.now() }); } @@ -42,7 +44,7 @@ const Badge = props => { text={text_color} className={class_name || className} style={!isBootstrapColor ? {backgroundColor: color, ...style} : style} - {...omit(['setProps', 'n_clicks', 'n_clicks_timestamp'], otherProps)} + {...omit(['setProps'], otherProps)} data-dash-is-loading={ (loading_state && loading_state.is_loading) || undefined } @@ -52,12 +54,6 @@ const Badge = props => { ); }; -Badge.defaultProps = { - color: 'secondary', - n_clicks: 0, - n_clicks_timestamp: -1 -}; - Badge.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/button/Button.js b/src/components/button/Button.js index 4a1d26792..cc052f76d 100644 --- a/src/components/button/Button.js +++ b/src/components/button/Button.js @@ -73,7 +73,7 @@ const Button = props => { ); }; -Button.defaultProps = { +Button.dashPersistence = { n_clicks: 0, n_clicks_timestamp: -1 }; diff --git a/src/components/card/CardLink.js b/src/components/card/CardLink.js index bbdbbee48..95d6acddf 100644 --- a/src/components/card/CardLink.js +++ b/src/components/card/CardLink.js @@ -1,6 +1,5 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {omit} from 'ramda'; import RBCard from 'react-bootstrap/Card'; import Link from '../../private/Link'; @@ -8,20 +7,20 @@ import Link from '../../private/Link'; * Use card link to add consistently styled links to your cards. Links can be * used like buttons, external links, or internal Dash style links. */ -const CardLink = props => { - const { - children, - loading_state, - disabled, - className, - class_name, - ...otherProps - } = props; - +const CardLink = ({ + children, + loading_state, + disabled, + className, + class_name, + n_clicks = 0, + setProps, + ...otherProps +}) => { const incrementClicks = () => { - if (!disabled && props.setProps) { - props.setProps({ - n_clicks: props.n_clicks + 1, + if (!disabled && setProps) { + setProps({ + n_clicks: n_clicks + 1, n_clicks_timestamp: Date.now() }); } @@ -36,18 +35,13 @@ const CardLink = props => { preOnClick={incrementClicks} disabled={disabled} className={class_name || className} - {...omit(['setProps', 'n_clicks', 'n_clicks_timestamp'], otherProps)} + {...otherProps} > {children} ); }; -CardLink.defaultProps = { - n_clicks: 0, - n_clicks_timestamp: -1 -}; - CardLink.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/carousel/Carousel.js b/src/components/carousel/Carousel.js index 39fec3c2b..d3d9d64ad 100644 --- a/src/components/carousel/Carousel.js +++ b/src/components/carousel/Carousel.js @@ -13,13 +13,15 @@ import Link from '../../private/Link'; const Carousel = props => { const { items, - active_index, style, class_name, className, loading_state, setProps, interval, + active_index = 0, + controls = true, + indicators = true, ...otherProps } = props; @@ -81,10 +83,7 @@ const Carousel = props => { ); }; -Carousel.defaultProps = { - active_index: 0, - controls: true, - indicators: true, +Carousel.dashPersistence = { persisted_props: ['active_index'], persistence_type: 'local' }; diff --git a/src/components/collapse/Collapse.js b/src/components/collapse/Collapse.js index b472d25fb..0f2c6a561 100644 --- a/src/components/collapse/Collapse.js +++ b/src/components/collapse/Collapse.js @@ -8,36 +8,39 @@ import RBCollapse from 'react-bootstrap/Collapse'; * children is controlled by the `is_open` prop which can be targetted by * callbacks. */ -const Collapse = React.forwardRef((props, ref) => { - const { - children, - is_open, - navbar, - loading_state, - className, - class_name, - tag, - ...otherProps - } = props; - - return ( - -
- {children} -
-
- ); -}); - -Collapse.defaultProps = {dimension: 'height'}; +const Collapse = React.forwardRef( + ( + { + children, + is_open, + navbar, + loading_state, + className, + class_name, + tag, + dimension = 'height', + ...otherProps + }, + ref + ) => { + return ( + +
+ {children} +
+
+ ); + } +); Collapse.propTypes = { /** diff --git a/src/components/dropdownmenu/DropdownMenu.js b/src/components/dropdownmenu/DropdownMenu.js index b9d0b8dfa..5e7f95831 100644 --- a/src/components/dropdownmenu/DropdownMenu.js +++ b/src/components/dropdownmenu/DropdownMenu.js @@ -14,31 +14,29 @@ import DropdownToggle from '../../private/DropdownToggle'; * DropdownMenu creates an overlay useful for grouping together links and other * content to organise navigation or other interactive elements. */ -const DropdownMenu = props => { - const { - children, - nav, - label, - disabled, - caret, - in_navbar, - addon_type, - size, - right, - align_end, - menu_variant, - direction, - loading_state, - color, - group, - toggle_style, - toggleClassName, - toggle_class_name, - className, - class_name, - ...otherProps - } = props; - +const DropdownMenu = ({ + children, + nav, + label, + in_navbar, + addon_type, + size, + right, + align_end, + direction, + loading_state, + color, + group, + toggle_style, + toggleClassName, + toggle_class_name, + className, + class_name, + caret = true, + disabled = false, + menu_variant = 'light', + ...otherProps +}) => { const [dropdownOpen, setDropdownOpen] = useState(false); const isBootstrapColor = bootstrapColors.has(color) || color === 'link'; const toggle = () => { @@ -105,12 +103,6 @@ const DropdownMenu = props => { ); }; -DropdownMenu.defaultProps = { - caret: true, - disabled: false, - menu_variant: 'light' -}; - DropdownMenu.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/dropdownmenu/DropdownMenuItem.js b/src/components/dropdownmenu/DropdownMenuItem.js index 7a19d6ca9..87a953cfa 100644 --- a/src/components/dropdownmenu/DropdownMenuItem.js +++ b/src/components/dropdownmenu/DropdownMenuItem.js @@ -9,23 +9,22 @@ import {DropdownMenuContext} from '../../private/DropdownMenuContext'; /** * Use DropdownMenuItem to build up the content of a DropdownMenu. */ -const DropdownMenuItem = props => { - let { - children, - href, - loading_state, - target, - disabled, - n_clicks, - toggle, - setProps, - className, - class_name, - header, - divider, - ...otherProps - } = props; - +const DropdownMenuItem = ({ + children, + href, + loading_state, + target, + disabled, + setProps, + className, + class_name, + header, + divider, + n_clicks = 0, + n_clicks_timestamp = -1, + toggle = true, + ...otherProps +}) => { const context = useContext(DropdownMenuContext); const handleClick = e => { @@ -182,10 +181,4 @@ DropdownMenuItem.propTypes = { target: PropTypes.string }; -DropdownMenuItem.defaultProps = { - n_clicks: 0, - n_clicks_timestamp: -1, - toggle: true -}; - export default DropdownMenuItem; diff --git a/src/components/form/Form.js b/src/components/form/Form.js index fe96132da..1296db08f 100644 --- a/src/components/form/Form.js +++ b/src/components/form/Form.js @@ -7,17 +7,17 @@ import RBForm from 'react-bootstrap/Form'; * The Form component can be used to organise collections of input components * and apply consistent styling. */ -const Form = props => { - const { - children, - loading_state, - n_submit, - prevent_default_on_submit, - setProps, - className, - class_name, - ...otherProps - } = props; +const Form = ({ + children, + loading_state, + setProps, + className, + class_name, + prevent_default_on_submit = true, + n_submit = 0, + n_submit_timestamp = -1, + ...otherProps +}) => { return ( { @@ -32,7 +32,7 @@ const Form = props => { } }} className={class_name || className} - {...omit(['n_submit_timestamp'], otherProps)} + {...otherProps} data-dash-is-loading={ (loading_state && loading_state.is_loading) || undefined } @@ -42,12 +42,6 @@ const Form = props => { ); }; -Form.defaultProps = { - prevent_default_on_submit: true, - n_submit: 0, - n_submit_timestamp: -1 -}; - Form.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/form/Label.js b/src/components/form/Label.js index 465ed75ae..53624a5a9 100644 --- a/src/components/form/Label.js +++ b/src/components/form/Label.js @@ -16,28 +16,26 @@ const colWidths = ['width', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl']; /** * A component for adding labels to inputs in forms with added sizing controls. */ -const Label = props => { - const { - children, - html_for, - width, - xs, - sm, - md, - lg, - xl, - xxl, - align, - size, - className, - class_name, - color, - style, - loading_state, - check, - ...otherProps - } = props; - +const Label = ({ + children, + html_for, + width, + xs, + sm, + md, + lg, + xl, + xxl, + size, + className, + class_name, + color, + style, + loading_state, + check, + align = 'center', + ...otherProps +}) => { const isBootstrapColor = bootstrapTextColors.has(color); // check if column width has been specified, use alignment attribute if so @@ -233,8 +231,4 @@ Label.propTypes = { }) }; -Label.defaultProps = { - align: 'center' -}; - export default Label; diff --git a/src/components/input/Checkbox.js b/src/components/input/Checkbox.js index 55994e067..9ff29e396 100644 --- a/src/components/input/Checkbox.js +++ b/src/components/input/Checkbox.js @@ -10,69 +10,67 @@ import classNames from 'classnames'; * Each checkbox is rendered as an input / label pair. `Checklist` must be * given an `id` to work properly. */ -const Checkbox = props => { - const { - value, - disabled, - className, - class_name, - style, - id, - input_class_name, - inputClassName, - input_style, - label, - label_id, - label_style, - label_class_name, - labelClassName, - loading_state, - name, - setProps - } = props; - - return ( -
- { - if (!disabled) { - if (setProps) { - setProps({value: !value}); - } +const Checkbox = ({ + className, + class_name, + style, + id, + label, + label_id, + loading_state, + name, + setProps, + value = false, + disabled = false, + inputStyle = {}, + input_style = null, + inputClassName = '', + input_class_name = '', + labelStyle = {}, + label_style = null, + labelClassName = '', + label_class_name = '' +}) => ( +
+ { + if (!disabled) { + if (setProps) { + setProps({value: !value}); } - }} - /> - -
- ); -}; + } + }} + /> + +
+); Checkbox.propTypes = { /** @@ -224,19 +222,9 @@ Checkbox.propTypes = { setProps: PropTypes.func }; -Checkbox.defaultProps = { - inputStyle: {}, - input_style: null, - inputClassName: '', - input_class_name: '', - labelStyle: {}, - label_style: null, - labelClassName: '', - label_class_name: '', +Checkbox.dashPersistence = { persisted_props: ['value'], - persistence_type: 'local', - value: false, - disabled: false + persistence_type: 'local' }; export default Checkbox; diff --git a/src/components/input/Checklist.js b/src/components/input/Checklist.js index ed139a00e..5a787baf7 100644 --- a/src/components/input/Checklist.js +++ b/src/components/input/Checklist.js @@ -12,34 +12,38 @@ import {sanitizeOptions} from '../../private/util'; * Each checkbox is rendered as an input / label pair. `Checklist` must be * given an `id` to work properly. */ -const Checklist = props => { - const {className, class_name, id, options, style, key, loading_state, name} = - props; - +const Checklist = ({ + className, + class_name, + id, + style, + key, + loading_state, + name, + inputCheckedClassName, + input_checked_class_name, + inputCheckedStyle, + input_checked_style, + labelCheckedClassName, + label_checked_class_name, + labelCheckedStyle, + label_checked_style, + setProps, + inline, + switch: switches, + inputStyle, + input_style, + inputClassName, + input_class_name, + labelStyle, + label_style, + labelClassName, + label_class_name, + value = [], + options = [] +}) => { const listItem = option => { - const { - id, - inputClassName, - input_class_name, - inputCheckedClassName, - input_checked_class_name, - inputStyle, - input_style, - inputCheckedStyle, - input_checked_style, - labelClassName, - label_class_name, - labelCheckedClassName, - label_checked_class_name, - labelStyle, - label_style, - labelCheckedStyle, - label_checked_style, - setProps, - inline, - value, - switch: switches - } = props; + const {} = props; const checked = includes(option.value, value); @@ -420,17 +424,7 @@ Checklist.propTypes = { name: PropTypes.string }; -Checklist.defaultProps = { - inputStyle: {}, - input_style: null, - inputClassName: '', - input_class_name: '', - labelStyle: {}, - label_style: null, - labelClassName: '', - label_class_name: '', - options: [], - value: [], +Checklist.dashPersistence = { persisted_props: ['value'], persistence_type: 'local' }; diff --git a/src/components/input/Input.js b/src/components/input/Input.js index df1c54f79..6ac341012 100644 --- a/src/components/input/Input.js +++ b/src/components/input/Input.js @@ -17,37 +17,37 @@ const isEquivalent = (v1, v2) => v1 === v2 || (isNaN(v1) && isNaN(v2)); * the Checklist and RadioItems component. Dates, times, and file uploads * are supported through separate components in other libraries. */ -const Input = props => { - const { - type, - value, - n_blur, - n_submit, - valid, - invalid, - plaintext, - size, - html_size, - setProps, - debounce, - loading_state, - className, - class_name, - autoComplete, - autocomplete, - autoFocus, - autofocus, - inputMode, - inputmode, - maxLength, - maxlength, - minLength, - minlength, - readonly, - tabIndex, - tabindex, - ...otherProps - } = props; +const Input = ({ + type, + value, + valid, + invalid, + plaintext, + size, + html_size, + setProps, + loading_state, + className, + class_name, + autoComplete, + autocomplete, + autoFocus, + autofocus, + inputMode, + inputmode, + maxLength, + maxlength, + minLength, + minlength, + readonly, + tabIndex, + tabindex, + n_blur = 0, + n_submit = 0, + debounce = false, + step = 'any', + ...otherProps +}) => { const inputRef = useRef(null); const debounceRef = useRef(null); @@ -669,15 +669,9 @@ Input.propTypes = { tabIndex: PropTypes.string }; -Input.defaultProps = { - n_blur: 0, - n_blur_timestamp: -1, - n_submit: 0, - n_submit_timestamp: -1, - debounce: false, +Input.dashPersistence = { persisted_props: ['value'], - persistence_type: 'local', - step: 'any' + persistence_type: 'local' }; export default Input; diff --git a/src/components/input/RadioButton.js b/src/components/input/RadioButton.js index 6db699765..441f45935 100644 --- a/src/components/input/RadioButton.js +++ b/src/components/input/RadioButton.js @@ -10,70 +10,66 @@ import classNames from 'classnames'; * Each checkbox is rendered as an input / label pair. `Checklist` must be * given an `id` to work properly. */ -const RadioButton = props => { - const { - value, - disabled, - className, - class_name, - style, - id, - input_class_name, - inputClassName, - input_style, - label, - label_id, - label_style, - label_class_name, - labelClassName, - loading_state, - name, - setProps - } = props; - - return ( -
- { - if (!disabled) { - if (setProps) { - setProps({value: !value}); - } +const RadioButton = ({ + className, + class_name, + style, + id, + input_class_name, + inputClassName, + input_style, + label, + label_id, + label_style, + label_class_name, + labelClassName, + loading_state, + name, + setProps, + disabled = false, + value = false +}) => ( +
+ { + if (!disabled) { + if (setProps) { + setProps({value: !value}); } - }} - onChange={() => {}} - /> - -
- ); -}; + } + }} + onChange={() => {}} + /> + +
+); RadioButton.propTypes = { /** @@ -225,19 +221,9 @@ RadioButton.propTypes = { setProps: PropTypes.func }; -RadioButton.defaultProps = { - inputStyle: {}, - input_style: null, - inputClassName: '', - input_class_name: '', - labelStyle: {}, - label_style: null, - labelClassName: '', - label_class_name: '', +RadioButton.dashPersistence = { persisted_props: ['value'], - persistence_type: 'local', - value: false, - disabled: false + persistence_type: 'local' }; export default RadioButton; diff --git a/src/components/input/RadioItems.js b/src/components/input/RadioItems.js index 5988fe3ed..5313b9348 100644 --- a/src/components/input/RadioItems.js +++ b/src/components/input/RadioItems.js @@ -11,34 +11,37 @@ import {sanitizeOptions} from '../../private/util'; * Each radio item is rendered as an input and associated label which are * siblings of each other. */ -const RadioItems = props => { - const {id, className, class_name, style, options, key, loading_state, name} = - props; - +const RadioItems = ({ + className, + class_name, + style, + key, + loading_state, + name, + id, + inputClassName, + input_class_name, + inputCheckedStyle, + input_checked_style, + inputStyle, + input_style, + inputCheckedClassName, + input_checked_class_name, + labelClassName, + label_class_name, + labelCheckedClassName, + label_checked_class_name, + labelStyle, + label_style, + labelCheckedStyle, + label_checked_style, + setProps, + inline, + switch: switches, + options = [] +}) => { const listItem = option => { - const { - id, - inputClassName, - input_class_name, - inputCheckedStyle, - input_checked_style, - inputStyle, - input_style, - inputCheckedClassName, - input_checked_class_name, - labelClassName, - label_class_name, - labelCheckedClassName, - label_checked_class_name, - labelStyle, - label_style, - labelCheckedStyle, - label_checked_style, - setProps, - inline, - value, - switch: switches - } = props; + const {} = props; const checked = option.value === value; @@ -412,16 +415,7 @@ RadioItems.propTypes = { name: PropTypes.string }; -RadioItems.defaultProps = { - inputStyle: {}, - input_style: null, - inputClassName: '', - input_class_name: '', - labelStyle: {}, - label_style: null, - labelClassName: '', - label_class_name: '', - options: [], +RadioItems.dashPersistence = { persisted_props: ['value'], persistence_type: 'local' }; diff --git a/src/components/input/Select.js b/src/components/input/Select.js index af04d1251..c0623c7f0 100644 --- a/src/components/input/Select.js +++ b/src/components/input/Select.js @@ -9,34 +9,28 @@ import {sanitizeOptions} from '../../private/util'; * Create a HTML select element with Bootstrap styles. Specify options as a * list of dictionaries with keys label, value and disabled. */ -const Select = props => { - const { - className, - class_name, - html_size, - valid, - invalid, - value, - ...otherProps - } = props; - +const Select = ({ + className, + class_name, + html_size, + valid, + invalid, + value = '', + placeholder = '', + options = [], + setProps, + ...otherProps +}) => { const handleChange = e => { - if (props.setProps) { - props.setProps({value: e.target.value}); + if (setProps) { + setProps({value: e.target.value}); } }; return ( { ); }; -Select.defaultProps = { - value: '', +Select.dashPersistence = { persisted_props: ['value'], - persistence_type: 'local', - placeholder: '' + persistence_type: 'local' }; Select.propTypes = { diff --git a/src/components/input/Switch.js b/src/components/input/Switch.js index 040108cf4..435ab44b7 100644 --- a/src/components/input/Switch.js +++ b/src/components/input/Switch.js @@ -10,69 +10,65 @@ import classNames from 'classnames'; * Each checkbox is rendered as an input / label pair. `Checklist` must be * given an `id` to work properly. */ -const Switch = props => { - const { - value, - disabled, - className, - class_name, - style, - id, - input_class_name, - inputClassName, - input_style, - label, - label_id, - label_style, - label_class_name, - labelClassName, - loading_state, - name, - setProps - } = props; - - return ( -
- { - if (!disabled) { - if (setProps) { - setProps({value: !value}); - } +const Switch = ({ + className, + class_name, + style, + id, + input_class_name, + inputClassName, + input_style, + label, + label_id, + label_style, + label_class_name, + labelClassName, + loading_state, + name, + value = false, + disabled = false, + setProps +}) => ( +
+ { + if (!disabled) { + if (setProps) { + setProps({value: !value}); } - }} - /> - -
- ); -}; + } + }} + /> + +
+); Switch.propTypes = { /** @@ -224,19 +220,9 @@ Switch.propTypes = { setProps: PropTypes.func }; -Switch.defaultProps = { - inputStyle: {}, - input_style: null, - inputClassName: '', - input_class_name: '', - labelStyle: {}, - label_style: null, - labelClassName: '', - label_class_name: '', +Switch.dashPersistence = { persisted_props: ['value'], - persistence_type: 'local', - value: false, - disabled: false + persistence_type: 'local' }; export default Switch; diff --git a/src/components/input/Textarea.js b/src/components/input/Textarea.js index 01d7e1f5f..031efaa1a 100644 --- a/src/components/input/Textarea.js +++ b/src/components/input/Textarea.js @@ -7,41 +7,43 @@ import classNames from 'classnames'; * A basic HTML textarea for entering multiline text based on the corresponding * component in dash-core-components */ -const Textarea = props => { - const { - value, - n_clicks, - n_blur, - n_submit, - setProps, - className, - class_name, - invalid, - valid, - size, - debounce, - loading_state, - autoFocus, - autofocus, - maxLength, - maxlength, - minLength, - minlength, - readOnly, - readonly, - accessKey, - accesskey, - contentEditable, - contenteditable, - contextMenu, - contextmenu, - spellCheck, - spellcheck, - tabIndex, - tabindex, - submit_on_enter, - ...otherProps - } = props; +const Textarea = ({ + setProps, + className, + class_name, + invalid, + valid, + size, + loading_state, + autoFocus, + autofocus, + maxLength, + maxlength, + minLength, + minlength, + readOnly, + readonly, + accessKey, + accesskey, + contentEditable, + contenteditable, + contextMenu, + contextmenu, + spellCheck, + spellcheck, + tabIndex, + tabindex, + n_blur = 0, + n_blur_timestamp = -1, + n_submit = 0, + n_submit_timestamp = -1, + n_clicks = 0, + n_clicks_timestamp = -1, + debounce = false, + value = '', + submit_on_enter = true, + ...otherProps +}) => { const [valueState, setValueState] = useState(value || ''); const debounceRef = useRef(null); @@ -499,18 +501,9 @@ Textarea.propTypes = { persistence_type: PropTypes.oneOf(['local', 'session', 'memory']) }; -Textarea.defaultProps = { - n_blur: 0, - n_blur_timestamp: -1, - n_submit: 0, - n_submit_timestamp: -1, - n_clicks: 0, - n_clicks_timestamp: -1, - debounce: false, +Textarea.dashPersistence = { persisted_props: ['value'], - persistence_type: 'local', - value: '', - submit_on_enter: true + persistence_type: 'local' }; export default Textarea; diff --git a/src/components/listgroup/ListGroup.js b/src/components/listgroup/ListGroup.js index ea4994e3b..41e4959c4 100644 --- a/src/components/listgroup/ListGroup.js +++ b/src/components/listgroup/ListGroup.js @@ -15,7 +15,8 @@ const ListGroup = props => { className, class_name, flush, - tag, + tag = 'ul', + numbered = false, ...otherProps } = props; return ( @@ -23,6 +24,7 @@ const ListGroup = props => { className={class_name || className} variant={flush ? 'flush' : null} as={tag} + numbered={numbered} {...omit(['setProps'], otherProps)} data-dash-is-loading={ (loading_state && loading_state.is_loading) || undefined @@ -33,11 +35,6 @@ const ListGroup = props => { ); }; -ListGroup.defaultProps = { - tag: 'ul', - numbered: false -}; - ListGroup.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/listgroup/ListGroupItem.js b/src/components/listgroup/ListGroupItem.js index 3a7e9d957..9653cf837 100644 --- a/src/components/listgroup/ListGroupItem.js +++ b/src/components/listgroup/ListGroupItem.js @@ -15,12 +15,12 @@ const ListGroupItem = props => { href, loading_state, target, - n_clicks, setProps, color, style, className, class_name, + n_clicks = 0, ...otherProps } = props; @@ -55,11 +55,6 @@ const ListGroupItem = props => { ); }; -ListGroupItem.defaultProps = { - n_clicks: 0, - n_clicks_timestamp: -1 -}; - ListGroupItem.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/modal/Modal.js b/src/components/modal/Modal.js index 1cd55ddfe..d6a074f9e 100644 --- a/src/components/modal/Modal.js +++ b/src/components/modal/Modal.js @@ -242,7 +242,7 @@ Modal.propTypes = { * Renders a fullscreen modal. Specifying a breakpoint will render the modal * as fullscreen below the breakpoint size. */ - fullscreen: PropTypes.oneOf([ + fullscreen: PropTypes.oneOfType([ PropTypes.bool, PropTypes.oneOf(['sm-down', 'md-down', 'lg-down', 'xl-down', 'xxl-down']) ]), diff --git a/src/components/modal/ModalHeader.js b/src/components/modal/ModalHeader.js index e665b18cf..b3b77ac36 100644 --- a/src/components/modal/ModalHeader.js +++ b/src/components/modal/ModalHeader.js @@ -6,34 +6,27 @@ import RBModalHeader from 'react-bootstrap/ModalHeader'; /** * Add a header to any modal. */ -const ModalHeader = props => { - const { - children, - loading_state, - className, - class_name, - tag, - close_button, - ...otherProps - } = props; - return ( - - {children} - - ); -}; - -ModalHeader.defaultProps = { - close_button: true -}; +const ModalHeader = ({ + children, + loading_state, + className, + class_name, + tag, + close_button = true, + ...otherProps +}) => ( + + {children} + +); ModalHeader.propTypes = { /** diff --git a/src/components/nav/NavLink.js b/src/components/nav/NavLink.js index e597a9e12..248a94c3d 100644 --- a/src/components/nav/NavLink.js +++ b/src/components/nav/NavLink.js @@ -9,20 +9,19 @@ import Link from '../../private/Link'; * Add a link to a `Nav`. Can be used as a child of `NavItem` or of `Nav` * directly. */ -const NavLink = props => { +const NavLink = ({ + children, + className, + class_name, + loading_state, + setProps, + href, + active = false, + disabled = false, + n_clicks = 0, + ...otherProps +}) => { const [linkActive, setLinkActive] = useState(false); - const { - children, - disabled, - className, - class_name, - active, - loading_state, - setProps, - n_clicks, - href, - ...otherProps - } = props; const pathnameToActive = pathname => { setLinkActive( @@ -72,13 +71,6 @@ const NavLink = props => { ); }; -NavLink.defaultProps = { - active: false, - disabled: false, - n_clicks: 0, - n_clicks_timestamp: -1 -}; - NavLink.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/nav/Navbar.js b/src/components/nav/Navbar.js index 89a7edbea..d9c3a3481 100644 --- a/src/components/nav/Navbar.js +++ b/src/components/nav/Navbar.js @@ -7,21 +7,20 @@ import {bootstrapColors} from '../../private/BootstrapColors'; /** * The Navbar component can be used to make fully customisable navbars. */ -const Navbar = props => { - const { - children, - color, - style, - loading_state, - className, - class_name, - light, - dark, - tag, - ...otherProps - } = props; +const Navbar = ({ + children, + style, + loading_state, + className, + class_name, + dark, + tag, + color = 'light', + light = true, + expand = 'md', + ...otherProps +}) => { const isBootstrapColor = bootstrapColors.has(color); - return ( { bg={isBootstrapColor ? color : null} style={{backgroundColor: !isBootstrapColor && color, ...style}} className={class_name || className} + expand={expand} {...omit(['setProps'], otherProps)} data-dash-is-loading={ (loading_state && loading_state.is_loading) || undefined @@ -39,12 +39,6 @@ const Navbar = props => { ); }; -Navbar.defaultProps = { - color: 'light', - light: true, - expand: 'md' -}; - Navbar.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/nav/NavbarSimple.js b/src/components/nav/NavbarSimple.js index d7a03f534..11617645b 100644 --- a/src/components/nav/NavbarSimple.js +++ b/src/components/nav/NavbarSimple.js @@ -20,15 +20,16 @@ const NavbarSimple = props => { brand_href, brand_style, brand_external_link, - links_left, - fluid, - color, dark, - light, style, loading_state, className, class_name, + fluid = false, + color = 'light', + light = true, + expand = 'md', + links_left = false, ...otherProps } = props; const isBootstrapColor = bootstrapColors.has(color); @@ -44,6 +45,7 @@ const NavbarSimple = props => { color={isBootstrapColor ? color : null} style={!isBootstrapColor ? {backgroundColor: color, ...style} : style} className={class_name || className} + expand={expand} {...omit(['setProps'], otherProps)} data-dash-is-loading={ (loading_state && loading_state.is_loading) || undefined @@ -68,14 +70,6 @@ const NavbarSimple = props => { ); }; -NavbarSimple.defaultProps = { - fluid: false, - color: 'light', - light: true, - expand: 'md', - links_left: false -}; - NavbarSimple.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/nav/NavbarToggler.js b/src/components/nav/NavbarToggler.js index deebea3f1..328ef4745 100644 --- a/src/components/nav/NavbarToggler.js +++ b/src/components/nav/NavbarToggler.js @@ -7,14 +7,20 @@ import RBNavbarToggle from 'react-bootstrap/NavbarToggle'; * Use this component to create a navbar toggle to show navlinks when the * navbar collapses on smaller screens. */ -const NavbarToggler = props => { - const {children, loading_state, className, class_name, ...otherProps} = props; +const NavbarToggler = ({ + children, + loading_state, + className, + class_name, + n_clicks = 0, + ...otherProps +}) => { return ( { if (props.setProps) { props.setProps({ - n_clicks: props.n_clicks + 1, + n_clicks: n_clicks + 1, n_clicks_timestamp: Date.now() }); } @@ -30,11 +36,6 @@ const NavbarToggler = props => { ); }; -NavbarToggler.defaultProps = { - n_clicks: 0, - n_clicks_timestamp: -1 -}; - NavbarToggler.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/offcanvas/Offcanvas.js b/src/components/offcanvas/Offcanvas.js index a63d19648..bb5a03567 100644 --- a/src/components/offcanvas/Offcanvas.js +++ b/src/components/offcanvas/Offcanvas.js @@ -6,27 +6,25 @@ import RBOffcanvas from 'react-bootstrap/Offcanvas'; * Create a toggleable hidden sidebar using the Offcanvas component. * Toggle the visibility with the `is_open` prop. */ -const Offcanvas = props => { - const { - is_open, - setProps, - children, - loading_state, - class_name, - className, - backdrop, - backdrop_class_name, - backdropClassName, - labelledby, - labelledBy, - scrollable, - autofocus, - autoFocus, - close_button, - title, - ...otherProps - } = props; - +const Offcanvas = ({ + setProps, + children, + loading_state, + class_name, + className, + backdrop_class_name, + backdropClassName, + labelledby, + labelledBy, + scrollable, + autofocus, + autoFocus, + title, + close_button = true, + is_open = false, + backdrop = true, + ...otherProps +}) => { const onHide = () => { if (setProps) { setProps({is_open: !is_open}); @@ -64,12 +62,6 @@ const Offcanvas = props => { ); }; -Offcanvas.defaultProps = { - close_button: true, - is_open: false, - backdrop: true -}; - Offcanvas.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/pagination/Pagination.js b/src/components/pagination/Pagination.js index 59df17ac7..f78aa0712 100644 --- a/src/components/pagination/Pagination.js +++ b/src/components/pagination/Pagination.js @@ -7,22 +7,20 @@ import RBPagination from 'react-bootstrap/Pagination'; * Individual pages should be added as children using the `PaginationItem` * component. */ -const Pagination = props => { - const { - step, - active_page, - min_value, - fully_expanded, - previous_next, - first_last, - setProps, - class_name, - className, - loading_state, - ...otherProps - } = props; - - let {max_value} = props; +const Pagination = ({ + setProps, + class_name, + className, + loading_state, + min_value = 1, + step = 1, + active_page = 1, + fully_expanded = true, + previous_next = false, + first_last = false, + max_value, + ...otherProps +}) => { // Check max_value is correct value re. step size and if not, change it // i.e. min = 1, step = 2, max_value = 4 doesn't work, so need max_value = 5 if ((max_value - min_value) % step !== 0) { @@ -151,15 +149,6 @@ const Pagination = props => { ); }; -Pagination.defaultProps = { - min_value: 1, - step: 1, - active_page: 1, - fully_expanded: true, - previous_next: false, - first_last: false -}; - Pagination.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/placeholder/Placeholder.js b/src/components/placeholder/Placeholder.js index 1385921d0..4a10e88f6 100644 --- a/src/components/placeholder/Placeholder.js +++ b/src/components/placeholder/Placeholder.js @@ -9,22 +9,20 @@ import classNames from 'classnames'; * Use loading Placeholders for your components or pages to indicate * something may still be loading. */ -const Placeholder = props => { - const { - children, - loading_state, - className, - class_name, - color, - button, - style, - delay_hide, - delay_show, - show_initially, - animation, - ...otherProps - } = props; - +const Placeholder = ({ + children, + loading_state, + className, + class_name, + color, + style, + animation, + delay_hide = 0, + delay_show = 0, + show_initially = true, + button = false, + ...otherProps +}) => { const [showPlaceholder, setShowPlaceholder] = useState(show_initially); const dismissTimer = useRef(); const showTimer = useRef(); @@ -141,13 +139,6 @@ const Placeholder = props => { Placeholder._dashprivate_isLoadingComponent = true; -Placeholder.defaultProps = { - delay_hide: 0, - delay_show: 0, - show_initially: true, - button: false -}; - Placeholder.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/popover/Popover.js b/src/components/popover/Popover.js index 7ccd7e3a7..f2a7285df 100644 --- a/src/components/popover/Popover.js +++ b/src/components/popover/Popover.js @@ -26,6 +26,10 @@ const Popover = props => { hide_arrow, offset, body, + delay = {show: 0, hide: 50}, + placement = 'right', + flip = true, + autohide = false, ...otherProps } = props; @@ -53,6 +57,10 @@ const Popover = props => { } defaultShow={is_open} popperConfig={popperConfig} + delay={delay} + placement={placement} + flip={flip} + autohide={autohide} {...omit( ['persistence', 'persisted_props', 'persistence_type'], otherProps @@ -73,11 +81,7 @@ const Popover = props => { ); }; -Popover.defaultProps = { - delay: {show: 0, hide: 50}, - placement: 'right', - flip: true, - autohide: false, +Popover.dashPersistence = { persisted_props: ['is_open'], persistence_type: 'local' }; diff --git a/src/components/progress/Progress.js b/src/components/progress/Progress.js index be323f968..2b2e7ae3f 100644 --- a/src/components/progress/Progress.js +++ b/src/components/progress/Progress.js @@ -26,13 +26,14 @@ function renderProgressBar( now, max, label, - visuallyHidden, - striped, - animated, className, style, variant, barStyle, + animated = false, + isChild = false, + visuallyHidden = false, + striped = false, ...props }, ref @@ -41,6 +42,10 @@ function renderProgressBar(
{ ); }); -ProgressBar.defaultProps = { - animated: false, - isChild: false, - visuallyHidden: false, - striped: false -}; - -const Progress = props => { - const { - children, - loading_state, - color, - className, - class_name, - value, - hide_label, - bar, - ...otherProps - } = props; +const Progress = ({ + children, + loading_state, + color, + className, + class_name, + value, + bar, + hide_label = false, + ...otherProps +}) => { const isBootstrapColor = bootstrapColors.has(color); return ( { ); }; -Progress.defaultProps = { - hide_label: false -}; - Progress.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/spinner/Spinner.js b/src/components/spinner/Spinner.js index f366e4823..e27a30abe 100644 --- a/src/components/spinner/Spinner.js +++ b/src/components/spinner/Spinner.js @@ -23,10 +23,10 @@ const Spinner = props => { fullscreenClassName, fullscreen_class_name, fullscreen_style, - delay_hide, - delay_show, - show_initially, - type, + delay_hide = 0, + delay_show = 0, + show_initially = true, + type = 'border', ...otherProps } = props; @@ -153,13 +153,6 @@ const Spinner = props => { Spinner._dashprivate_isLoadingComponent = true; -Spinner.defaultProps = { - delay_hide: 0, - delay_show: 0, - show_initially: true, - type: 'border' -}; - Spinner.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/tabs/Tab.js b/src/components/tabs/Tab.js index d68aed278..f59998c41 100644 --- a/src/components/tabs/Tab.js +++ b/src/components/tabs/Tab.js @@ -8,10 +8,6 @@ const Tab = props => { return
{props.children}
; }; -Tab.defaultProps = { - disabled: false -}; - Tab.propTypes = { /** * The ID of this component, used to identify dash components diff --git a/src/components/tabs/Tabs.js b/src/components/tabs/Tabs.js index d8f96dabd..6225d5a1b 100644 --- a/src/components/tabs/Tabs.js +++ b/src/components/tabs/Tabs.js @@ -15,18 +15,17 @@ import { * Create Bootstrap styled tabs. Use the `active_tab` property to set, or get * get the currently active tab in a callback. */ -const Tabs = props => { - let { - children, - id, - className, - class_name, - style, - active_tab, - key, - loading_state, - setProps - } = props; +const Tabs = ({ + children, + id, + className, + class_name, + style, + active_tab, + key, + loading_state, + setProps +}) => { children = parseChildrenToArray(children); // if active_tab not set initially, choose first tab @@ -119,6 +118,7 @@ const Tabs = props => { activeLabelClassName, active_label_class_name, loading_state, + disabled = false, ...otherProps } = childProps; const tabId = tab_id || 'tab-' + idx; @@ -127,6 +127,7 @@ const Tabs = props => { { ); }; -Tabs.defaultProps = { +Tabs.dashPersistence = { persisted_props: ['active_tab'], persistence_type: 'local' }; diff --git a/src/components/toast/Toast.js b/src/components/toast/Toast.js index f13caca6d..02514aa05 100644 --- a/src/components/toast/Toast.js +++ b/src/components/toast/Toast.js @@ -21,14 +21,14 @@ const Toast = props => { body_style, bodyClassName, body_class_name, - dismissable, duration, - n_dismiss, - is_open, setProps, className, class_name, color, + is_open = true, + n_dismiss = 0, + dismissable = false, ...otherProps } = props; @@ -108,11 +108,7 @@ const Toast = props => { ); }; -Toast.defaultProps = { - is_open: true, - n_dismiss: 0, - n_dismiss_timestamp: -1, - dismissable: false, +Toast.dashPersistence = { persisted_props: ['is_open'], persistence_type: 'local' }; diff --git a/src/components/tooltip/Tooltip.js b/src/components/tooltip/Tooltip.js index 3421a255b..f57cb48b4 100644 --- a/src/components/tooltip/Tooltip.js +++ b/src/components/tooltip/Tooltip.js @@ -12,47 +12,40 @@ import Overlay from '../../private/Overlay'; * component to which the tooltip should be attached) */ -const Tooltip = props => { - const { - id, - children, - is_open, - loading_state, - className, - class_name, - style, - fade, - ...otherProps - } = props; - - return ( - - - {children} - - - ); -}; - -Tooltip.defaultProps = { - delay: {show: 0, hide: 50}, - placement: 'auto', - flip: true, - autohide: true, - fade: true, - trigger: 'hover focus' -}; +const Tooltip = ({ + id, + children, + is_open, + loading_state, + className, + class_name, + style, + delay = {show: 0, hide: 50}, + placement = 'auto', + flip = true, + autohide = true, + fade = true, + trigger = 'hover focus', + ...otherProps +}) => ( + + + {children} + + +); Tooltip.propTypes = { /** diff --git a/src/private/Link.js b/src/private/Link.js index f5b32da71..c7271877b 100644 --- a/src/private/Link.js +++ b/src/private/Link.js @@ -66,12 +66,12 @@ class Link extends Component { render() { const { children, - external_link, preOnClick, target, linkTarget, href, download, + external_link = false, ...otherProps } = this.props; const linkIsExternal = href && isExternalLink(external_link, href); @@ -154,9 +154,4 @@ Link.propTypes = { download: PropTypes.string }; -Link.defaultProps = { - disabled: false, - external_link: null -}; - export {Link as default, isExternalLink}; diff --git a/src/private/Modal.js b/src/private/Modal.js index 973796ca9..50aea60d6 100644 --- a/src/private/Modal.js +++ b/src/private/Modal.js @@ -22,17 +22,6 @@ import {useBootstrapPrefix, useIsRTL} from 'react-bootstrap/ThemeProvider'; import ModalDialog from './ModalDialog'; -const defaultProps = { - show: false, - backdrop: true, - keyboard: true, - autoFocus: true, - enforceFocus: true, - restoreFocus: true, - animation: true, - dialogAs: ModalDialog -}; - /* eslint-disable no-use-before-define, react/no-multi-comp */ function DialogTransition(props) { return ; @@ -54,7 +43,6 @@ const Modal = React.forwardRef( children, dialogStyle, contentStyle, - dialogAs: Dialog, 'data-bs-theme': dataBsTheme, 'aria-labelledby': ariaLabelledby, 'aria-describedby': ariaDescribedby, @@ -62,17 +50,10 @@ const Modal = React.forwardRef( /* BaseModal props */ - show, - animation, - backdrop, - keyboard, onEscapeKeyDown, onShow, onHide, container, - autoFocus, - enforceFocus, - restoreFocus, restoreFocusOptions, onEntered, onExit, @@ -83,6 +64,14 @@ const Modal = React.forwardRef( backdropClassName, zIndex, manager: propsManager, + show = false, + backdrop = true, + keyboard = true, + autoFocus = true, + enforceFocus = true, + restoreFocus = true, + animation = true, + dialogAs: Dialog = ModalDialog, ...props }, ref @@ -314,6 +303,4 @@ const Modal = React.forwardRef( } ); -Modal.defaultProps = defaultProps; - export default Modal;