From d1505e874aa5297e77d0e2e365773e2362782ac0 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Tue, 17 Nov 2020 21:30:05 +0100 Subject: [PATCH 01/22] First stab at adding drag_value to Slider --- src/components/Slider.react.js | 5 +++++ src/fragments/Slider.react.js | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/components/Slider.react.js b/src/components/Slider.react.js index 37fcd4ecf..fd1269e80 100644 --- a/src/components/Slider.react.js +++ b/src/components/Slider.react.js @@ -48,6 +48,11 @@ Slider.propTypes = { */ value: PropTypes.number, + /** + * The value of the input during a drag + */ + drag_value: PropTypes.number, + /** * Additional CSS class for the root DOM node */ diff --git a/src/fragments/Slider.react.js b/src/fragments/Slider.react.js index 63eda8bdc..ea6fbe630 100644 --- a/src/fragments/Slider.react.js +++ b/src/fragments/Slider.react.js @@ -18,14 +18,16 @@ export default class Slider extends Component { ? createSliderWithTooltip(ReactSlider) : ReactSlider; this._computeStyle = computeSliderStyle(); + this.drag_value = props.value; this.state = { value: props.value, + drag_value: props.value, }; } propsToState(newProps) { if (newProps.value !== this.props.value) { - this.setState({value: newProps.value}); + this.setState({value: newProps.value, drag_value: newProps.value}); } } @@ -87,9 +89,10 @@ export default class Slider extends Component { { if (updatemode === 'drag') { - setProps({value}); + setProps({value: value, drag_value: value}); } else { - this.setState({value}); + this.setState({value: value}); + setProps({drag_value: value}); } }} onAfterChange={value => { From 704a8441b1ff8bfe8c08e244ead19604ee9c1cb9 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Tue, 1 Dec 2020 22:25:56 +0100 Subject: [PATCH 02/22] Make an initial fire of drag_value with the value of 'value' --- src/components/Slider.react.js | 2 +- src/fragments/Slider.react.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/Slider.react.js b/src/components/Slider.react.js index fd1269e80..71807a946 100644 --- a/src/components/Slider.react.js +++ b/src/components/Slider.react.js @@ -141,7 +141,7 @@ Slider.propTypes = { updatemode: PropTypes.oneOf(['mouseup', 'drag']), /** - * Dash-assigned callback that gets fired when the value changes. + * Dash-assigned callback that gets fired when the value or drag_value changes. */ setProps: PropTypes.func, diff --git a/src/fragments/Slider.react.js b/src/fragments/Slider.react.js index ea6fbe630..7453f0e9f 100644 --- a/src/fragments/Slider.react.js +++ b/src/fragments/Slider.react.js @@ -23,6 +23,7 @@ export default class Slider extends Component { value: props.value, drag_value: props.value, }; + this.props.setProps({drag_value: props.value}); } propsToState(newProps) { @@ -117,6 +118,7 @@ export default class Slider extends Component { 'setProps', 'updatemode', 'value', + 'drag_value', 'marks', 'verticalHeight', ], From e74b5198ae8f99b39fb90388840d9ecb9f9be7c3 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Tue, 1 Dec 2020 22:32:58 +0100 Subject: [PATCH 03/22] update updatemode docs --- src/components/Slider.react.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/Slider.react.js b/src/components/Slider.react.js index 71807a946..51a344d8a 100644 --- a/src/components/Slider.react.js +++ b/src/components/Slider.react.js @@ -130,13 +130,13 @@ Slider.propTypes = { verticalHeight: PropTypes.number, /** - * Determines when the component should update - * its value. If `mouseup`, then the slider - * will only trigger its value when the user has - * finished dragging the slider. If `drag`, then - * the slider will update its value continuously - * as it is being dragged. - * Only use `drag` if your updates are fast. + * Determines when the component should update its `value` + * property. If `mouseup` (the default) then the slider + * will only trigger its value when the user has finished + * dragging the slider. If `drag`, then the slider will + * update its value continuously as it is being dragged. + * Note that for the latter case, the `drag_value` + * property could be used instead. */ updatemode: PropTypes.oneOf(['mouseup', 'drag']), From cbd7d229974de5ab0f59962b0f491d434bc10b56 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Wed, 2 Dec 2020 12:17:00 +0100 Subject: [PATCH 04/22] Implement drag_value for RangeSlider --- src/components/RangeSlider.react.js | 23 ++++++++++++++--------- src/fragments/RangeSlider.react.js | 10 +++++++--- src/fragments/Slider.react.js | 1 - 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/components/RangeSlider.react.js b/src/components/RangeSlider.react.js index 3b3e02bbc..fdf45d1ef 100644 --- a/src/components/RangeSlider.react.js +++ b/src/components/RangeSlider.react.js @@ -49,6 +49,11 @@ RangeSlider.propTypes = { */ value: PropTypes.arrayOf(PropTypes.number), + /** + * The value of the input during a drag + */ + drag_value: PropTypes.arrayOf(PropTypes.number), + /** * allowCross could be set as true to allow those handles to cross. */ @@ -144,19 +149,19 @@ RangeSlider.propTypes = { */ verticalHeight: PropTypes.number, - /** - * Determines when the component should update - * its value. If `mouseup`, then the slider - * will only trigger its value when the user has - * finished dragging the slider. If `drag`, then - * the slider will update its value continuously - * as it is being dragged. - * Only use `drag` if your updates are fast. + /** + * Determines when the component should update its `value` + * property. If `mouseup` (the default) then the slider + * will only trigger its value when the user has finished + * dragging the slider. If `drag`, then the slider will + * update its value continuously as it is being dragged. + * Note that for the latter case, the `drag_value` + * property could be used instead. */ updatemode: PropTypes.oneOf(['mouseup', 'drag']), /** - * Dash-assigned callback that gets fired when the value changes. + * Dash-assigned callback that gets fired when the value or drag_value changes. */ setProps: PropTypes.func, diff --git a/src/fragments/RangeSlider.react.js b/src/fragments/RangeSlider.react.js index 932c6b5d8..55ee7b24b 100644 --- a/src/fragments/RangeSlider.react.js +++ b/src/fragments/RangeSlider.react.js @@ -17,12 +17,14 @@ export default class RangeSlider extends Component { this._computeStyle = computeSliderStyle(); this.state = { value: props.value, + drag_value: props.value, }; + this.props.setProps({drag_value: props.value}); } propsToState(newProps) { if (newProps.value !== this.props.value) { - this.setState({value: newProps.value}); + this.setState({value: newProps.value, drag_value: newProps.value}); } } @@ -84,9 +86,10 @@ export default class RangeSlider extends Component { { if (updatemode === 'drag') { - setProps({value}); + setProps({value: value, drag_value: value}); } else { - this.setState({value}); + this.setState({value: value}); + setProps({drag_value: value}); } }} onAfterChange={value => { @@ -101,6 +104,7 @@ export default class RangeSlider extends Component { [ 'className', 'value', + 'drag_value', 'setProps', 'marks', 'updatemode', diff --git a/src/fragments/Slider.react.js b/src/fragments/Slider.react.js index 7453f0e9f..8ae23a323 100644 --- a/src/fragments/Slider.react.js +++ b/src/fragments/Slider.react.js @@ -18,7 +18,6 @@ export default class Slider extends Component { ? createSliderWithTooltip(ReactSlider) : ReactSlider; this._computeStyle = computeSliderStyle(); - this.drag_value = props.value; this.state = { value: props.value, drag_value: props.value, From 04dfd9800836dfc501e883ce9dc3ebd127a77267 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Wed, 2 Dec 2020 12:26:20 +0100 Subject: [PATCH 05/22] lint --- src/components/RangeSlider.react.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/RangeSlider.react.js b/src/components/RangeSlider.react.js index fdf45d1ef..2b293044b 100644 --- a/src/components/RangeSlider.react.js +++ b/src/components/RangeSlider.react.js @@ -149,7 +149,7 @@ RangeSlider.propTypes = { */ verticalHeight: PropTypes.number, - /** + /** * Determines when the component should update its `value` * property. If `mouseup` (the default) then the slider * will only trigger its value when the user has finished From c7adc18fb4d0c7b9332198afca2ab047e10de817 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 3 Dec 2020 10:01:53 +0100 Subject: [PATCH 06/22] Update src/components/Slider.react.js Co-authored-by: Alex Johnson --- src/components/Slider.react.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/Slider.react.js b/src/components/Slider.react.js index 51a344d8a..116180dd6 100644 --- a/src/components/Slider.react.js +++ b/src/components/Slider.react.js @@ -135,8 +135,9 @@ Slider.propTypes = { * will only trigger its value when the user has finished * dragging the slider. If `drag`, then the slider will * update its value continuously as it is being dragged. - * Note that for the latter case, the `drag_value` - * property could be used instead. + * If you want different actions during and after drag, + * leave `updatemode` as `mouseup` and use `drag_value` + * for the continuously updating value. */ updatemode: PropTypes.oneOf(['mouseup', 'drag']), From f67f75ce297724a5a371a82549f45d2f58b44eea Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 12:34:51 +0100 Subject: [PATCH 07/22] add tests for slider --- tests/dash_core_components_page.py | 17 +++++++++++ tests/integration/sliders/test_sliders.py | 36 +++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/tests/dash_core_components_page.py b/tests/dash_core_components_page.py index b7cc962f4..aeb4471aa 100644 --- a/tests/dash_core_components_page.py +++ b/tests/dash_core_components_page.py @@ -100,3 +100,20 @@ def _wait_until_day_is_clickable(self, timeout=1): @property def date_picker_day_locator(self): return 'div[data-visible="true"] td.CalendarDay' + + def click_and_hold_at_coord_fractions(self, elem_or_selector, fx, fy): + elem = self._get_element(elem_or_selector) + + ActionChains(self.driver).move_to_element_with_offset( + elem, elem.size["width"] * fx, elem.size["height"] * fy + ).click_and_hold().perform() + + def move_to_coord_fractions(self, elem_or_selector, fx, fy): + elem = self._get_element(elem_or_selector) + + ActionChains(self.driver).move_to_element_with_offset( + elem, elem.size["width"] * fx, elem.size["height"] * fy + ).perform() + + def release(self): + ActionChains(self.driver).release().perform() diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index a5483e093..d695badb1 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -160,3 +160,39 @@ def test_slsl005_slider_tooltip(dash_dcc): dash_dcc.percy_snapshot( "slider-make sure tooltips are only visible if parent slider is visible" ) + + +def test_slsl006_drag_value_slider(dash_dcc): + app = dash.Dash(__name__) + app.layout = html.Div( + [ + dcc.Slider( + id="slider", + min=0, + max=20, + step=1, + value=5, + ), + html.Div(id="out"), + ] + ) + + @app.callback(Output("out", "children"), [Input("slider", "drag_value")]) + def update_output(value): + return "You have dragged {}".format(value) + + dash_dcc.start_server(app) + dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") + + slider = dash_dcc.find_element("#slider") + dash_dcc.click_and_hold_at_coord_fractions(slider, 0.5, 0.25) + dash_dcc.move_to_coord_fractions(slider, 0.75, 0.25) + dash_dcc.wait_for_text_to_equal("#out", "You have dragged 15") + dash_dcc.move_to_coord_fractions(slider, 0.25, 0.25) + dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") + dash_dcc.release() + + + +def test_slsl007_drag_value_rangeslider(dash_dcc): + pass # todo: xx From 4763f7826619b853708a5cb2403ebe73bdbc8090 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 12:47:43 +0100 Subject: [PATCH 08/22] lint and add missing import --- tests/dash_core_components_page.py | 1 + tests/integration/sliders/test_sliders.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/dash_core_components_page.py b/tests/dash_core_components_page.py index aeb4471aa..909de7a3f 100644 --- a/tests/dash_core_components_page.py +++ b/tests/dash_core_components_page.py @@ -2,6 +2,7 @@ from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.common.action_chains import ActionChains logger = logging.getLogger(__name__) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index d695badb1..acb21542a 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -193,6 +193,5 @@ def update_output(value): dash_dcc.release() - def test_slsl007_drag_value_rangeslider(dash_dcc): pass # todo: xx From 966f227464847294320c6e3e7ff5202baa4bd98a Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 13:00:00 +0100 Subject: [PATCH 09/22] black? --- tests/integration/sliders/test_sliders.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index acb21542a..8ef448745 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -165,16 +165,7 @@ def test_slsl005_slider_tooltip(dash_dcc): def test_slsl006_drag_value_slider(dash_dcc): app = dash.Dash(__name__) app.layout = html.Div( - [ - dcc.Slider( - id="slider", - min=0, - max=20, - step=1, - value=5, - ), - html.Div(id="out"), - ] + [dcc.Slider(id="slider", min=0, max=20, step=1, value=5,), html.Div(id="out"),] ) @app.callback(Output("out", "children"), [Input("slider", "drag_value")]) From 4d0a3e2d68e01f98f2d6618fc86d8f40a43fe95f Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 13:12:52 +0100 Subject: [PATCH 10/22] fix test, hopefully --- tests/integration/sliders/test_sliders.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 8ef448745..df82cc5d0 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -165,15 +165,19 @@ def test_slsl005_slider_tooltip(dash_dcc): def test_slsl006_drag_value_slider(dash_dcc): app = dash.Dash(__name__) app.layout = html.Div( - [dcc.Slider(id="slider", min=0, max=20, step=1, value=5,), html.Div(id="out"),] + [dcc.Slider(id="slider", min=0, max=20, step=1, value=5), html.Div(id="out")] ) + @app.callback(Output("out", "children"), [Input("slider", "value")]) + def update_output(value): + return "You have selected {}".format(value) + @app.callback(Output("out", "children"), [Input("slider", "drag_value")]) def update_output(value): return "You have dragged {}".format(value) dash_dcc.start_server(app) - dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") + dash_dcc.wait_for_text_to_equal("#out", "You have selected 5") slider = dash_dcc.find_element("#slider") dash_dcc.click_and_hold_at_coord_fractions(slider, 0.5, 0.25) @@ -182,6 +186,7 @@ def update_output(value): dash_dcc.move_to_coord_fractions(slider, 0.25, 0.25) dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") dash_dcc.release() + dash_dcc.wait_for_text_to_equal("#out", "You have selected 5") def test_slsl007_drag_value_rangeslider(dash_dcc): From a0740c2521d5db391d2e11155441de1510f73cdb Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 13:37:42 +0100 Subject: [PATCH 11/22] fix test --- tests/integration/sliders/test_sliders.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index df82cc5d0..66708fafd 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -168,16 +168,11 @@ def test_slsl006_drag_value_slider(dash_dcc): [dcc.Slider(id="slider", min=0, max=20, step=1, value=5), html.Div(id="out")] ) - @app.callback(Output("out", "children"), [Input("slider", "value")]) - def update_output(value): - return "You have selected {}".format(value) - @app.callback(Output("out", "children"), [Input("slider", "drag_value")]) def update_output(value): return "You have dragged {}".format(value) dash_dcc.start_server(app) - dash_dcc.wait_for_text_to_equal("#out", "You have selected 5") slider = dash_dcc.find_element("#slider") dash_dcc.click_and_hold_at_coord_fractions(slider, 0.5, 0.25) @@ -186,7 +181,6 @@ def update_output(value): dash_dcc.move_to_coord_fractions(slider, 0.25, 0.25) dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") dash_dcc.release() - dash_dcc.wait_for_text_to_equal("#out", "You have selected 5") def test_slsl007_drag_value_rangeslider(dash_dcc): From 7ddd835b007342b44f36a92b8ea8bb02f8f8f224 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 13:52:49 +0100 Subject: [PATCH 12/22] fix test --- tests/integration/sliders/test_sliders.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 66708fafd..e01fab5fb 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -175,11 +175,11 @@ def update_output(value): dash_dcc.start_server(app) slider = dash_dcc.find_element("#slider") - dash_dcc.click_and_hold_at_coord_fractions(slider, 0.5, 0.25) + dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) dash_dcc.move_to_coord_fractions(slider, 0.75, 0.25) dash_dcc.wait_for_text_to_equal("#out", "You have dragged 15") - dash_dcc.move_to_coord_fractions(slider, 0.25, 0.25) - dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") + dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) + dash_dcc.wait_for_text_to_equal("#out", "You have dragged 10") dash_dcc.release() From b9c72c46817743b467f83a332159e5ff56b3f92d Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 14:21:26 +0100 Subject: [PATCH 13/22] fix test? --- tests/integration/sliders/test_sliders.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index e01fab5fb..63728c9d7 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -165,7 +165,10 @@ def test_slsl005_slider_tooltip(dash_dcc): def test_slsl006_drag_value_slider(dash_dcc): app = dash.Dash(__name__) app.layout = html.Div( - [dcc.Slider(id="slider", min=0, max=20, step=1, value=5), html.Div(id="out")] + [ + dcc.Slider(id="slider", min=0, max=20, step=1, value=5), + html.Div(id="out", children="init"), + ] ) @app.callback(Output("out", "children"), [Input("slider", "drag_value")]) @@ -173,6 +176,7 @@ def update_output(value): return "You have dragged {}".format(value) dash_dcc.start_server(app) + dash_dcc.wait_for_text_to_equal("#out", "init") slider = dash_dcc.find_element("#slider") dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) From 0799af5f2f2fa2bb6cf90ddfb427ea24c6172a13 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 15:51:46 +0100 Subject: [PATCH 14/22] fix? --- tests/integration/sliders/test_sliders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 63728c9d7..c2bae7c6a 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -176,7 +176,7 @@ def update_output(value): return "You have dragged {}".format(value) dash_dcc.start_server(app) - dash_dcc.wait_for_text_to_equal("#out", "init") + dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") slider = dash_dcc.find_element("#slider") dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) From 1be148f0701db7c16c18be454c8bf8ac9a3bb4a9 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 16:08:38 +0100 Subject: [PATCH 15/22] use exact same code as other example. Im running out of ideas --- tests/integration/sliders/test_sliders.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index c2bae7c6a..0ae1311ca 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -166,8 +166,15 @@ def test_slsl006_drag_value_slider(dash_dcc): app = dash.Dash(__name__) app.layout = html.Div( [ - dcc.Slider(id="slider", min=0, max=20, step=1, value=5), - html.Div(id="out", children="init"), + dcc.Slider( + id="slider", + min=0, + max=20, + step=1, + value=5, + tooltip={"always_visible": True}, + ), + html.Div(id="out"), ] ) From b3ccc08395da02e789103239dea337c0764ffb81 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 16:31:39 +0100 Subject: [PATCH 16/22] bring test down to minimum --- tests/integration/sliders/test_sliders.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 0ae1311ca..637056a26 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -180,18 +180,18 @@ def test_slsl006_drag_value_slider(dash_dcc): @app.callback(Output("out", "children"), [Input("slider", "drag_value")]) def update_output(value): - return "You have dragged {}".format(value) + return "You have selected {}".format(value) dash_dcc.start_server(app) - dash_dcc.wait_for_text_to_equal("#out", "You have dragged 5") + dash_dcc.wait_for_text_to_equal("#out", "You have selected 5") - slider = dash_dcc.find_element("#slider") - dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) - dash_dcc.move_to_coord_fractions(slider, 0.75, 0.25) - dash_dcc.wait_for_text_to_equal("#out", "You have dragged 15") - dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) - dash_dcc.wait_for_text_to_equal("#out", "You have dragged 10") - dash_dcc.release() + # slider = dash_dcc.find_element("#slider") + # dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) + # dash_dcc.move_to_coord_fractions(slider, 0.75, 0.25) + # dash_dcc.wait_for_text_to_equal("#out", "You have selected 15") + # dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) + # dash_dcc.wait_for_text_to_equal("#out", "You have selected 10") + # dash_dcc.release() def test_slsl007_drag_value_rangeslider(dash_dcc): From 24600cf778d36a62b0254e37a8c1e07c14a5d553 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Thu, 10 Dec 2020 16:51:47 +0100 Subject: [PATCH 17/22] also include output for value --- tests/integration/sliders/test_sliders.py | 27 ++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 637056a26..252aea916 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -174,24 +174,31 @@ def test_slsl006_drag_value_slider(dash_dcc): value=5, tooltip={"always_visible": True}, ), - html.Div(id="out"), + html.Div(id="out-value"), + html.Div(id="out-drag-value"), ] ) - @app.callback(Output("out", "children"), [Input("slider", "drag_value")]) + @app.callback(Output("out-drag-value", "children"), [Input("slider", "drag_value")]) + def update_output(value): + return "You have dragged {}".format(value) + + @app.callback(Output("out-value", "children"), [Input("slider", "value")]) def update_output(value): return "You have selected {}".format(value) dash_dcc.start_server(app) - dash_dcc.wait_for_text_to_equal("#out", "You have selected 5") + dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 5") + assert dash_dcc.find_element("#out-drag-value").text == "You have dragged 5" - # slider = dash_dcc.find_element("#slider") - # dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) - # dash_dcc.move_to_coord_fractions(slider, 0.75, 0.25) - # dash_dcc.wait_for_text_to_equal("#out", "You have selected 15") - # dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) - # dash_dcc.wait_for_text_to_equal("#out", "You have selected 10") - # dash_dcc.release() + slider = dash_dcc.find_element("#slider") + dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) + dash_dcc.move_to_coord_fractions(slider, 0.75, 0.25) + dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 15") + dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) + dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 10") + dash_dcc.release() + dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 10") def test_slsl007_drag_value_rangeslider(dash_dcc): From 82c87632673a6f6a63be14727ac65c302dd55540 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 11 Dec 2020 13:27:48 +0100 Subject: [PATCH 18/22] refactor slicer implementation a bit --- src/fragments/Slider.react.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/fragments/Slider.react.js b/src/fragments/Slider.react.js index 8ae23a323..edd3e71ac 100644 --- a/src/fragments/Slider.react.js +++ b/src/fragments/Slider.react.js @@ -13,22 +13,13 @@ import {propTypes, defaultProps} from '../components/Slider.react'; export default class Slider extends Component { constructor(props) { super(props); - this.propsToState = this.propsToState.bind(this); this.DashSlider = props.tooltip ? createSliderWithTooltip(ReactSlider) : ReactSlider; this._computeStyle = computeSliderStyle(); this.state = { - value: props.value, - drag_value: props.value, + value: props.value }; - this.props.setProps({drag_value: props.value}); - } - - propsToState(newProps) { - if (newProps.value !== this.props.value) { - this.setState({value: newProps.value, drag_value: newProps.value}); - } } UNSAFE_componentWillReceiveProps(newProps) { @@ -37,11 +28,15 @@ export default class Slider extends Component { ? createSliderWithTooltip(ReactSlider) : ReactSlider; } - this.propsToState(newProps); + if (newProps.value !== this.props.value) { + this.props.setProps({drag_value: newProps.value}); + this.setState({value: newProps.value}); + } } UNSAFE_componentWillMount() { - this.propsToState(this.props); + this.props.setProps({drag_value: this.props.value}); + this.setState({value: this.props.value}); } render() { From 4c19122ea51fc7364cb874fc6e992796aa39c1cb Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 11 Dec 2020 13:53:42 +0100 Subject: [PATCH 19/22] change test and tweak code --- src/fragments/Slider.react.js | 10 +++++----- tests/integration/sliders/test_sliders.py | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/fragments/Slider.react.js b/src/fragments/Slider.react.js index edd3e71ac..178014e39 100644 --- a/src/fragments/Slider.react.js +++ b/src/fragments/Slider.react.js @@ -17,9 +17,7 @@ export default class Slider extends Component { ? createSliderWithTooltip(ReactSlider) : ReactSlider; this._computeStyle = computeSliderStyle(); - this.state = { - value: props.value - }; + this.state = {value: props.value}; } UNSAFE_componentWillReceiveProps(newProps) { @@ -35,8 +33,10 @@ export default class Slider extends Component { } UNSAFE_componentWillMount() { - this.props.setProps({drag_value: this.props.value}); - this.setState({value: this.props.value}); + if (this.props.value !== null) { + this.props.setProps({drag_value: this.props.value}); + this.setState({value: this.props.value}); + } } render() { diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 252aea916..92f8d293b 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -189,7 +189,8 @@ def update_output(value): dash_dcc.start_server(app) dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 5") - assert dash_dcc.find_element("#out-drag-value").text == "You have dragged 5" + #assert dash_dcc.find_element("#out-drag-value").text == "You have dragged 5" + dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 5") slider = dash_dcc.find_element("#slider") dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) From 773c88119bd372d17726667e989833f2cad47df3 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 11 Dec 2020 14:19:01 +0100 Subject: [PATCH 20/22] maybe only the initialization fails? --- tests/integration/sliders/test_sliders.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 92f8d293b..2f8a80b26 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -189,8 +189,8 @@ def update_output(value): dash_dcc.start_server(app) dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 5") - #assert dash_dcc.find_element("#out-drag-value").text == "You have dragged 5" - dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 5") + # assert dash_dcc.find_element("#out-drag-value").text == "You have dragged 5" + # dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 5") slider = dash_dcc.find_element("#slider") dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) From 1322548ee18d7f6454715429542067e4196362d5 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 11 Dec 2020 23:55:05 +0100 Subject: [PATCH 21/22] update rangeslider and add a test for it --- src/fragments/RangeSlider.react.js | 23 +++++------- tests/integration/sliders/test_sliders.py | 43 ++++++++++++++++++++--- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/fragments/RangeSlider.react.js b/src/fragments/RangeSlider.react.js index 55ee7b24b..75130b94e 100644 --- a/src/fragments/RangeSlider.react.js +++ b/src/fragments/RangeSlider.react.js @@ -10,22 +10,11 @@ import {propTypes, defaultProps} from '../components/RangeSlider.react'; export default class RangeSlider extends Component { constructor(props) { super(props); - this.propsToState = this.propsToState.bind(this); this.DashSlider = props.tooltip ? createSliderWithTooltip(Range) : Range; this._computeStyle = computeSliderStyle(); - this.state = { - value: props.value, - drag_value: props.value, - }; - this.props.setProps({drag_value: props.value}); - } - - propsToState(newProps) { - if (newProps.value !== this.props.value) { - this.setState({value: newProps.value, drag_value: newProps.value}); - } + this.state = {value: props.value}; } UNSAFE_componentWillReceiveProps(newProps) { @@ -34,11 +23,17 @@ export default class RangeSlider extends Component { ? createSliderWithTooltip(Range) : Range; } - this.propsToState(newProps); + if (newProps.value !== this.props.value) { + this.props.setProps({drag_value: newProps.value}); + this.setState({value: newProps.value}); + } } UNSAFE_componentWillMount() { - this.propsToState(this.props); + if (this.props.value !== null) { + this.props.setProps({drag_value: this.props.value}); + this.setState({value: this.props.value}); + } } render() { diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index 2f8a80b26..c80d2e9b5 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -188,11 +188,11 @@ def update_output(value): return "You have selected {}".format(value) dash_dcc.start_server(app) + slider = dash_dcc.find_element("#slider") + dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 5") - # assert dash_dcc.find_element("#out-drag-value").text == "You have dragged 5" - # dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 5") + dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 5") - slider = dash_dcc.find_element("#slider") dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) dash_dcc.move_to_coord_fractions(slider, 0.75, 0.25) dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 15") @@ -203,4 +203,39 @@ def update_output(value): def test_slsl007_drag_value_rangeslider(dash_dcc): - pass # todo: xx + app = dash.Dash(__name__) + app.layout = html.Div( + [ + dcc.RangeSlider( + id="slider", + min=0, + max=20, + step=1, + value=(5, 15), + tooltip={"always_visible": True}, + ), + html.Div(id="out-value"), + html.Div(id="out-drag-value"), + ] + ) + + @app.callback(Output("out-drag-value", "children"), [Input("slider", "drag_value")]) + def update_output(value): + value = value or (None, None) + return "You have dragged {}-{}".format(*value) + + @app.callback(Output("out-value", "children"), [Input("slider", "value")]) + def update_output(value): + return "You have selected {}-{}".format(*value) + + dash_dcc.start_server(app) + slider = dash_dcc.find_element("#slider") + + dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 5-15") + dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 5-15") + + dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) + dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) + dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 10-15") + dash_dcc.release() + dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 10-15") From 6c9bcda718f20973115860a04f932f67e7a029a1 Mon Sep 17 00:00:00 2001 From: Alex Johnson Date: Sun, 13 Dec 2020 21:58:21 -0500 Subject: [PATCH 22/22] verify that `value` only changes on mouseup while `drag_value` changes on drag --- tests/integration/sliders/test_sliders.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/integration/sliders/test_sliders.py b/tests/integration/sliders/test_sliders.py index c80d2e9b5..09ab15963 100644 --- a/tests/integration/sliders/test_sliders.py +++ b/tests/integration/sliders/test_sliders.py @@ -198,6 +198,7 @@ def update_output(value): dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 15") dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 10") + dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 5") dash_dcc.release() dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 10") @@ -237,5 +238,6 @@ def update_output(value): dash_dcc.click_and_hold_at_coord_fractions(slider, 0.25, 0.25) dash_dcc.move_to_coord_fractions(slider, 0.5, 0.25) dash_dcc.wait_for_text_to_equal("#out-drag-value", "You have dragged 10-15") + dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 5-15") dash_dcc.release() dash_dcc.wait_for_text_to_equal("#out-value", "You have selected 10-15")