Skip to content

Commit

Permalink
Merge pull request #2884 from plotly/master-2.17.1
Browse files Browse the repository at this point in the history
Master 2.17.1
  • Loading branch information
T4rk1n authored Jun 12, 2024
2 parents 95520f7 + 18f2f85 commit 791c1eb
Show file tree
Hide file tree
Showing 54 changed files with 894 additions and 261 deletions.
42 changes: 21 additions & 21 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ jobs:
steps:
- checkout
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- attach_workspace:
at: ~/dash
- store_artifacts:
Expand All @@ -42,9 +42,9 @@ jobs:
steps:
- checkout
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- run:
name: 🏁 Build Component Packages & Update Dependencies/Artifacts
command: |
Expand All @@ -67,7 +67,7 @@ jobs:
cat /home/circleci/.npm/_logs/*
fi
- save_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
paths:
- venv
- persist_to_workspace:
Expand Down Expand Up @@ -101,9 +101,9 @@ jobs:
- checkout
- run: sudo apt-get update
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- browser-tools/install-browser-tools:
chrome-version: 120.0.6099.71
- run:
Expand Down Expand Up @@ -191,9 +191,9 @@ jobs:
path: ~/dash
- run: sudo apt-get update
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- browser-tools/install-browser-tools:
chrome-version: 120.0.6099.71
install-firefox: false
Expand Down Expand Up @@ -268,9 +268,9 @@ jobs:
- checkout:
path: ~/dash
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- run:
name: 🌸 Lint
command: |
Expand Down Expand Up @@ -308,9 +308,9 @@ jobs:
path: ~/dash
- run: sudo apt-get update
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- browser-tools/install-browser-tools:
chrome-version: 120.0.6099.71
install-firefox: false
Expand Down Expand Up @@ -377,9 +377,9 @@ jobs:
path: ~/dash
- run: sudo apt-get update
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- restore_cache:
key: html-{{ checksum "components/dash-html-components/package.json" }}-{{ checksum "components/dash-html-components/package-lock.json" }}
- browser-tools/install-browser-tools:
Expand Down Expand Up @@ -453,9 +453,9 @@ jobs:
path: ~/dash
- run: sudo apt-get update
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- browser-tools/install-browser-tools:
chrome-version: 120.0.6099.71
install-firefox: false
Expand Down Expand Up @@ -507,9 +507,9 @@ jobs:
path: ~/dash
- run: sudo apt-get update
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- restore_cache:
key: table-{{ checksum "components/dash-table/package.json" }}-{{ checksum "components/dash-table/package-lock.json" }}
- browser-tools/install-browser-tools:
Expand Down Expand Up @@ -581,9 +581,9 @@ jobs:
- checkout:
path: ~/dash
- run: echo $PYVERSION > ver.txt
- run: cat requires-*.txt > requires-all.txt
- run: cat requirements/*.txt > requirements-all.txt
- restore_cache:
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requires-all.txt" }}
key: dep-{{ checksum ".circleci/config.yml" }}-{{ checksum "ver.txt" }}-{{ checksum "requirements-all.txt" }}
- restore_cache:
key: dep-{{ .Branch }}-{{ checksum "components/dash-table/package-lock.json" }}-{{ checksum "components/dash-table/package.json" }}
- run:
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
All notable changes to `dash` will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/).

## [2.17.1] - 2024-06-12

## Fixed

- [#2860](https://github.com/plotly/dash/pull/2860) Fix dcc.Loading to apply overlay_style only to the children and not the spinner. Fixes [#2858](https://github.com/plotly/dash/issues/2858)
- [#2854](https://github.com/plotly/dash/pull/2854) Fix dcc.Dropdown resetting empty values to null and triggering callbacks. Fixes [#2850](https://github.com/plotly/dash/issues/2850)
- [#2859](https://github.com/plotly/dash/pull/2859) Fix base patch operators. fixes [#2855](https://github.com/plotly/dash/issues/2855)
- [#2856](https://github.com/plotly/dash/pull/2856) Fix multiple consecutive calls with same id to set_props only keeping the last props. Fixes [#2852](https://github.com/plotly/dash/issues/2852)
- [#2867](https://github.com/plotly/dash/pull/2867) Fix clientside no output callback. Fixes [#2866](https://github.com/plotly/dash/issues/2866)
- [#2876](https://github.com/plotly/dash/pull/2876) Fix pattern matching in callback running argument. Fixes [#2863](https://github.com/plotly/dash/issues/2863)

## [2.17.0] - 2024-05-03

## Added
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include README.md
include LICENSE
include requires-*.txt
include requirements/*.txt
include dash/favicon.ico
include dash/extract-meta.js
include dash/deps/*.js
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ Built on top of [Plotly.js](https://github.com/plotly/plotly.js), [React](https:

- [dash.gallery](https://dash.gallery): Dash app gallery with Python & R code

<div align="center">
<a href="https://dash.plotly.com/project-maintenance">
<img src="https://dash.plotly.com/assets/images/maintained-by-plotly.png" width="400px" alt="Maintained by Plotly">
</a>
</div>


### Dash App Examples

| Dash App | Description |
Expand Down
4 changes: 2 additions & 2 deletions components/dash-core-components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion components/dash-core-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dash-core-components",
"version": "2.14.0",
"version": "2.14.1",
"description": "Core component suite for Dash",
"repository": {
"type": "git",
Expand Down
26 changes: 15 additions & 11 deletions components/dash-core-components/src/components/Loading.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import DefaultSpinner from '../fragments/Loading/spinners/DefaultSpinner.jsx';
import CubeSpinner from '../fragments/Loading/spinners/CubeSpinner.jsx';
import CircleSpinner from '../fragments/Loading/spinners/CircleSpinner.jsx';
import DotSpinner from '../fragments/Loading/spinners/DotSpinner.jsx';
import {mergeRight} from 'ramda';

const spinnerComponentOptions = {
graph: GraphSpinner,
Expand Down Expand Up @@ -49,10 +48,6 @@ const Loading = ({
justifyContent: 'center',
alignItems: 'center',
};
const hiddenContainer = mergeRight(
{visibility: 'hidden', position: 'relative'},
overlay_style
);

/* Overrides default Loading behavior if target_components is set. By default,
* Loading fires when any recursive child enters loading state. This makes loading
Expand Down Expand Up @@ -132,14 +127,23 @@ const Loading = ({

return (
<div
style={{position: 'relative', ...parent_style}}
className={parent_className}
style={
showSpinner
? mergeRight(hiddenContainer, parent_style)
: parent_style
}
>
{children}
<div
className={parent_className}
style={
showSpinner
? {
visibility: 'hidden',
...overlay_style,
...parent_style,
}
: parent_style
}
>
{children}
</div>
<div style={showSpinner ? coveringSpinner : {}}>
{showSpinner &&
(custom_spinner || (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export default class Tabs extends Component {
parseChildrenToArray() {
if (this.props.children && !is(Array, this.props.children)) {
// if dcc.Tabs.children contains just one single element, it gets passed as an object
// instead of an array - so we put in in a array ourselves!
// instead of an array - so we put it in an array ourselves!
return [this.props.children];
}
return this.props.children;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {isNil, pluck, without, pick} from 'ramda';
import {isNil, pluck, without, pick, isEmpty} from 'ramda';
import React, {useState, useCallback, useEffect, useMemo, useRef} from 'react';
import ReactDropdown from 'react-virtualized-select';
import createFilterOptions from 'react-select-fast-filter-options';
Expand Down Expand Up @@ -125,7 +125,8 @@ const Dropdown = props => {
!search_value &&
!isNil(sanitizedOptions) &&
optionsCheck !== sanitizedOptions &&
!isNil(value)
!isNil(value) &&
!isEmpty(value)
) {
const values = sanitizedOptions.map(option => option.value);
if (multi && Array.isArray(value)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

import pytest

from dash import Dash, html, dcc, Output, Input, State
from dash import Dash, html, dcc, Output, Input, State, Patch
from dash.exceptions import PreventUpdate

from selenium.webdriver.common.keys import Keys

sample_dropdown_options = [
{"label": "New York City", "value": "NYC"},
Expand Down Expand Up @@ -147,3 +148,44 @@ def print_value(n_clicks, options, value):
btn.click()
dash_dcc.wait_for_text_to_equal("#value-output", '["NYC"]')
dash_dcc.wait_for_text_to_equal("#options-output", '["MTL", "NYC"]')


def test_ddro004_empty_string_not_updated(dash_dcc):
# The value should stay as empty string and not null.
app = Dash()
app.layout = html.Div(
[
dcc.Dropdown(["a", "b", "c"], value="", id="drop"),
html.Div(id="output"),
dcc.Store(data={"count": 0}, id="count"),
html.Div(id="count-output"),
]
)

@app.callback(
Output("output", "children"),
Output("count", "data"),
Input("drop", "value"),
)
def on_value(value):
count = Patch()
count.count += 1
if value is None:
return "Value is none", count
return f"Value={value}", count

app.clientside_callback(
"data => data.count", Output("count-output", "children"), Input("count", "data")
)

dash_dcc.start_server(app)
dash_dcc.wait_for_text_to_equal("#output", "Value=")

dash_dcc.wait_for_text_to_equal("#count-output", "1")

select_input = dash_dcc.find_element("#drop input")
select_input.send_keys("a")
select_input.send_keys(Keys.ENTER)

dash_dcc.wait_for_text_to_equal("#output", "Value=a")
dash_dcc.wait_for_text_to_equal("#count-output", "2")
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def updateDiv(n_clicks):
dash_dcc.find_element(".loading .dash-spinner")
# unlike the default, the content should be visible
dash_dcc.wait_for_text_to_equal("#div-1", "content")
dash_dcc.wait_for_style_to_equal("#root > div", "opacity", "0.5")
dash_dcc.wait_for_style_to_equal("#root > div > div", "opacity", "0.5")

dash_dcc.wait_for_text_to_equal("#div-1", "changed")

Expand Down
4 changes: 2 additions & 2 deletions components/dash-table/src/dash-table/dash/DataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ export const propTypes = {
/**
* Denotes the format of the headers in the export data file.
* If `'none'`, there will be no header. If `'display'`, then the header
* of the data file will be be how it is currently displayed. Note that
* of the data file will be how it is currently displayed. Note that
* `'display'` is only supported for `'xlsx'` export_format and will behave
* like `'names'` for `'csv'` export format. If `'ids'` or `'names'`,
* then the headers of data file will be the column id or the column
Expand Down Expand Up @@ -802,7 +802,7 @@ export const propTypes = {
* If `'native'`, then the sorting UI is displayed and the sorting
* logic is handled by the table. That is, it is performed on the data
* that exists in the `data` property.
* If `'custom'`, the the sorting UI is displayed but it is the
* If `'custom'`, the sorting UI is displayed but it is the
* responsibility of the developer to program the sorting
* through a callback (where `sort_by` would be the input and `data`
* would be the output).
Expand Down
2 changes: 2 additions & 0 deletions dash/_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ def register_clientside_callback(
**kwargs,
):
output, inputs, state, prevent_initial_call = handle_callback_args(args, kwargs)
no_output = isinstance(output, (list,)) and len(output) == 0
insert_callback(
callback_list,
callback_map,
Expand All @@ -559,6 +560,7 @@ def register_clientside_callback(
state,
None,
prevent_initial_call,
no_output=no_output,
)

# If JS source is explicitly given, create a namespace and function
Expand Down
6 changes: 5 additions & 1 deletion dash/_callback_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,11 @@ def timing_information(self):
def set_props(self, component_id: typing.Union[str, dict], props: dict):
ctx_value = _get_context_value()
_id = stringify_id(component_id)
ctx_value.updated_props[_id] = props
existing = ctx_value.updated_props.get(_id)
if existing is not None:
ctx_value.updated_props[_id] = {**existing, **props}
else:
ctx_value.updated_props[_id] = props


callback_context = CallbackContext()
Expand Down
4 changes: 2 additions & 2 deletions dash/_dash_renderer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

__version__ = "1.20.0"
__version__ = "1.20.1"

_available_react_versions = {"16.14.0", "18.2.0"}
_available_reactdom_versions = {"16.14.0", "18.2.0"}
Expand Down Expand Up @@ -64,7 +64,7 @@ def _set_react_version(v_react, v_reactdom=None):
{
"relative_package_path": "dash-renderer/build/dash_renderer.min.js",
"dev_package_path": "dash-renderer/build/dash_renderer.dev.js",
"external_url": "https://unpkg.com/[email protected].0"
"external_url": "https://unpkg.com/[email protected].1"
"/build/dash_renderer.min.js",
"namespace": "dash",
},
Expand Down
Loading

0 comments on commit 791c1eb

Please sign in to comment.