diff --git a/CHANGELOG.md b/CHANGELOG.md index 6717ee3c7f..d6b2950079 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,18 @@ All notable changes to `dash` will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). + ## [UNRELEASED] ## Fixed - [#2596](https://github.com/plotly/dash/pull/2596) Fix react-dom throwing unique key prop error for markdown table, fix [#1433](https://github.com/plotly/dash/issues/1433) +- [#2589](https://github.com/plotly/dash/pull/2589) CSS for input elements not scoped to Dash application +- [#2599](https://github.com/plotly/dash/pull/2599) Fix background callback cancel inputs used in multiple callbacks and mixed cancel inputs across pages. + +## Changed + +- [#2593](https://github.com/plotly/dash/pull/2593) dcc.Input accepts a number for its debounce argument ## [2.11.1] - 2023-06-29 diff --git a/components/dash-core-components/.eslintrc b/components/dash-core-components/.eslintrc index 85388405b3..7d73d3670a 100644 --- a/components/dash-core-components/.eslintrc +++ b/components/dash-core-components/.eslintrc @@ -117,7 +117,7 @@ }], "no-magic-numbers": ["error", { "ignoreArrayIndexes": true, - "ignore": [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 10, 16, 0.5, 25] + "ignore": [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 10, 16, 0.5, 25, 1000] }], "no-underscore-dangle": ["off"], "no-useless-escape": ["off"] diff --git a/components/dash-core-components/src/components/Input.react.js b/components/dash-core-components/src/components/Input.react.js index 18bf374a99..62d3834b79 100644 --- a/components/dash-core-components/src/components/Input.react.js +++ b/components/dash-core-components/src/components/Input.react.js @@ -20,18 +20,28 @@ export default class Input extends PureComponent { constructor(props) { super(props); + this.state = { + pendingEvent: undefined, + value: '', + }; + this.input = React.createRef(); this.onBlur = this.onBlur.bind(this); this.onChange = this.onChange.bind(this); this.onEvent = this.onEvent.bind(this); this.onKeyPress = this.onKeyPress.bind(this); + this.debounceEvent = this.debounceEvent.bind(this); this.setInputValue = this.setInputValue.bind(this); this.setPropValue = this.setPropValue.bind(this); } UNSAFE_componentWillReceiveProps(nextProps) { const {value} = this.input.current; + if (this.state.pendingEvent) { + // avoid updating the input while awaiting a debounced event + return; + } const valueAsNumber = convert(value); this.setInputValue( isNil(valueAsNumber) ? value : valueAsNumber, @@ -61,11 +71,14 @@ export default class Input extends PureComponent { const valprops = this.props.type === 'number' ? {} : {value: this.state.value}; const {loading_state} = this.props; + let {className} = this.props; + className = 'dash-input' + (className ? ` ${className}` : ''); return ( { + this.onEvent(); + }, seconds * 1000); + + this.setState({ + value, + pendingEvent, + }); } onBlur() { @@ -129,7 +158,7 @@ export default class Input extends PureComponent { n_blur_timestamp: Date.now(), }); this.input.current.checkValidity(); - return this.props.debounce && this.onEvent(); + return this.props.debounce === true && this.onEvent(); } onKeyPress(e) { @@ -140,14 +169,22 @@ export default class Input extends PureComponent { }); this.input.current.checkValidity(); } - return this.props.debounce && e.key === 'Enter' && this.onEvent(); + return ( + this.props.debounce === true && e.key === 'Enter' && this.onEvent() + ); } onChange() { - if (!this.props.debounce) { + const {debounce} = this.props; + if (debounce) { + if (Number.isFinite(debounce)) { + this.debounceEvent(debounce); + } + if (this.props.type !== 'number') { + this.setState({value: this.input.current.value}); + } + } else { this.onEvent(); - } else if (this.props.type !== 'number') { - this.setState({value: this.input.current.value}); } } } @@ -188,9 +225,11 @@ Input.propTypes = { /** * If true, changes to input will be sent back to the Dash server only on enter or when losing focus. - * If it's false, it will sent the value back on every change. + * If it's false, it will send the value back on every change. + * If a number, it will not send anything back to the Dash server until the user has stopped + * typing for that number of seconds. */ - debounce: PropTypes.bool, + debounce: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]), /** * A hint to the user of what can be entered in the control . The placeholder text must not contain carriage returns or line-feeds. Note: Do not use the placeholder attribute instead of a