Skip to content

Commit 391f0c8

Browse files
authored
Merge pull request #3459 from plotly/bugfix/dcc-redesign-bugfixes
dcc redesign: accumulated bugfixes
2 parents bd7ab02 + afb1f5c commit 391f0c8

29 files changed

+646
-196
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22
All notable changes to `dash` will be documented in this file.
33
This project adheres to [Semantic Versioning](https://semver.org/).
44

5+
## UNRELEASED
6+
7+
## Changed
8+
9+
- Dropdown API changes
10+
* default value of optionHeight is now 'auto' which supports text wrapping of lengthy text on small screens; you can still specify a numeric pixel height if desired
11+
* new `labels` prop to customize strings used within the component
12+
* default value for closeOnSelect is now `True` for single-select dropdowns and `False` for multi-select
13+
14+
- Slider API changes
15+
* default value of `step` is now only set to `1` if the `min` and `max` props are both integers. Otherwise, it will be dynamically computed according to the available space for the slider
16+
517
## [4.0.0rc1] - 2025-09-22
618

719
## Added

components/dash-core-components/src/components/Dropdown.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
import React, {Component, lazy, Suspense} from 'react';
1+
import React, {lazy, Suspense} from 'react';
22
import {DropdownProps, PersistedProps, PersistenceTypes} from '../types';
33
import dropdown from '../utils/LazyLoader/dropdown';
44

55
const RealDropdown = lazy(dropdown);
66

7+
const defaultLabels: DropdownProps['labels'] = {
8+
select_all: 'Select All',
9+
deselect_all: 'Deselect All',
10+
selected_count: '{num_selected} selected',
11+
search: 'Search',
12+
clear_search: 'Clear search',
13+
clear_selection: 'Clear selection',
14+
no_options_found: 'No options found',
15+
};
16+
717
/**
818
* Dropdown is an interactive dropdown element for selecting one or more
919
* items.
@@ -19,8 +29,8 @@ export default function Dropdown({
1929
disabled = false,
2030
multi = false,
2131
searchable = true,
22-
// eslint-disable-next-line no-magic-numbers
23-
optionHeight = 36,
32+
labels = defaultLabels,
33+
optionHeight = 'auto',
2434
// eslint-disable-next-line no-magic-numbers
2535
maxHeight = 200,
2636
closeOnSelect = !multi,
@@ -30,11 +40,17 @@ export default function Dropdown({
3040
persistence_type = PersistenceTypes.local,
3141
...props
3242
}: DropdownProps) {
43+
labels = {
44+
...defaultLabels,
45+
...labels,
46+
};
47+
3348
return (
3449
<Suspense fallback={null}>
3550
<RealDropdown
3651
clearable={clearable}
3752
disabled={disabled}
53+
labels={labels}
3854
multi={multi}
3955
searchable={searchable}
4056
optionHeight={optionHeight}

components/dash-core-components/src/components/RangeSlider.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ export default function RangeSlider({
2424
// Some considerations for the default value of `step`:
2525
// If the range consists of integers, default to a value of `1`
2626
// Otherwise, leave it undefined
27-
if (Number.isInteger(props.min) && Number.isInteger(props.max)) {
27+
if (
28+
typeof step === 'undefined' &&
29+
Number.isInteger(props.min) &&
30+
Number.isInteger(props.max)
31+
) {
2832
step = 1;
2933
}
3034

components/dash-core-components/src/components/Slider.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default function Slider({
2222
persistence_type = PersistenceTypes.local,
2323
// eslint-disable-next-line no-magic-numbers
2424
verticalHeight = 400,
25-
step = 1,
25+
step = undefined,
2626
setProps,
2727
value,
2828
drag_value,
@@ -31,6 +31,17 @@ export default function Slider({
3131
// This is actually a wrapper around a RangeSlider.
3232
// We'll modify key `Slider` props to be compatible with a Range Slider.
3333

34+
// Some considerations for the default value of `step`:
35+
// If the range consists of integers, default to a value of `1`
36+
// Otherwise, leave it undefined
37+
if (
38+
typeof step === 'undefined' &&
39+
Number.isInteger(props.min) &&
40+
Number.isInteger(props.max)
41+
) {
42+
step = 1;
43+
}
44+
3445
const mappedValue: RangeSliderProps['value'] = useMemo(() => {
3546
return typeof value === 'number' ? [value] : value;
3647
}, [value]);

components/dash-core-components/src/components/css/Dropdown.css

Lines changed: 0 additions & 8 deletions
This file was deleted.

components/dash-core-components/src/components/css/dcc.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@
1111
--Dash-Fill-Primary-Hover: rgba(0, 18, 77, 0.04);
1212
--Dash-Fill-Primary-Active: rgba(0, 18, 77, 0.08);
1313
--Dash-Fill-Disabled: rgba(0, 24, 102, 0.1);
14+
--Dash-Shading-Strong: rgba(22, 23, 24, 0.35);
15+
--Dash-Shading-Weak: rgba(22, 23, 24, 0.2);
1416
}

components/dash-core-components/src/components/css/dropdown.css

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
.dash-dropdown {
2+
display: block;
23
box-sizing: border-box;
34
margin: calc(var(--Dash-Spacing) * 2) 0;
5+
padding: 0;
6+
background: inherit;
7+
border: none;
8+
width: 100%;
9+
cursor: pointer;
10+
font-size: inherit;
11+
overflow: hidden;
12+
accent-color: var(--Dash-Fill-Interactive-Strong);
13+
outline-color: var(--Dash-Fill-Interactive-Strong);
414
}
515

616
.dash-dropdown-grid-container {
@@ -19,7 +29,7 @@
1929
grid-template-columns: auto 1fr auto auto;
2030
}
2131

22-
.dash-dropdown-trigger,
32+
.dash-dropdown,
2333
.dash-dropdown-content {
2434
border-radius: var(--Dash-Spacing);
2535
border: 1px solid var(--Dash-Stroke-Strong);
@@ -28,17 +38,12 @@
2838
}
2939

3040
.dash-dropdown-trigger {
31-
background: inherit;
32-
padding: 6px 12px;
33-
width: 100%;
41+
padding: 0 12px;
3442
min-height: 32px;
3543
height: 100%;
36-
cursor: pointer;
37-
font-size: inherit;
38-
overflow: hidden;
3944
}
4045

41-
.dash-dropdown-trigger:disabled {
46+
.dash-dropdown:disabled {
4247
opacity: 0.6;
4348
cursor: not-allowed;
4449
}
@@ -61,12 +66,13 @@
6166

6267
.dash-dropdown-content {
6368
background: var(--Dash-Fill-Inverse-Strong);
64-
min-width: fit-content;
65-
width: var(--radix-popover-trigger-width);
69+
width: fit-content;
70+
min-width: var(--radix-popover-trigger-width);
71+
max-width: 98vw;
6672
overflow-y: auto;
67-
z-index: 50;
68-
box-shadow: 0px 10px 38px -10px rgba(22, 23, 24, 0.35),
69-
0px 10px 20px -15px rgba(22, 23, 24, 0.2);
73+
z-index: 500;
74+
box-shadow: 0px 10px 38px -10px var(--Dash-Shading-Strong),
75+
0px 10px 20px -15px var(--Dash-Shading-Weak);
7076
}
7177

7278
.dash-dropdown-value-count,
@@ -175,6 +181,8 @@
175181
text-decoration: none;
176182
color: var(--Dash-Text-Disabled);
177183
white-space: nowrap;
184+
accent-color: var(--Dash-Fill-Interactive-Strong);
185+
outline-color: var(--Dash-Fill-Interactive-Strong);
178186
}
179187

180188
.dash-dropdown-action-button:hover {
@@ -190,6 +198,6 @@
190198
}
191199

192200
.dash-dropdown-option {
193-
padding: var(--Dash-Spacing) calc(var(--Dash-Spacing) * 3);
201+
padding: calc(var(--Dash-Spacing) * 2) calc(var(--Dash-Spacing) * 3);
194202
box-shadow: 0 -1px 0 0 var(--Dash-Fill-Disabled) inset;
195203
}

components/dash-core-components/src/components/css/input.css

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@
1515
overflow: hidden;
1616
}
1717

18+
.dash-input-container:focus-within {
19+
outline: 1px solid var(--Dash-Fill-Interactive-Strong);
20+
}
21+
22+
.dash-input-container:has(.dash-input-element:disabled) {
23+
opacity: 0.6;
24+
cursor: not-allowed;
25+
}
26+
27+
.dash-input-container input:focus {
28+
outline: none;
29+
}
30+
1831
.dash-input-container:has(input[type='range']) {
1932
background: inherit;
2033
}
@@ -32,11 +45,17 @@
3245
box-sizing: border-box;
3346
z-index: 1;
3447
order: 2;
48+
accent-color: var(--Dash-Fill-Interactive-Strong);
49+
}
50+
51+
.dash-input-element:disabled {
52+
cursor: not-allowed;
3553
}
3654

3755
/* Hide native steppers for number inputs */
3856
.dash-input-element[type='number'] {
3957
-moz-appearance: textfield;
58+
border-radius: 0;
4059
}
4160

4261
.dash-input-element[type='number']::-webkit-outer-spin-button,
@@ -70,10 +89,11 @@
7089
cursor: pointer;
7190
font-size: 16px;
7291
font-weight: bold;
73-
color: var(--Dash-Text-Primary);
92+
color: var(--Dash -Text-Primary);
7493
}
7594

76-
.dash-input-stepper:hover {
95+
.dash-input-stepper:hover,
96+
.dash-input-stepper:focus {
7797
background: var(--Dash-Fill-Primary-Hover);
7898
}
7999

@@ -115,7 +135,3 @@
115135
input.dash-input-element:invalid {
116136
outline: solid red;
117137
}
118-
119-
input.dash-input-element:valid {
120-
outline: none black;
121-
}

components/dash-core-components/src/components/css/optionslist.css

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
}
2121

2222
.dash-options-list-option-text {
23-
white-space: pre;
2423
display: flex;
2524
align-items: center;
2625
}
@@ -30,10 +29,6 @@
3029
margin: 0 calc(var(--Dash-Spacing) * 2) 0 0;
3130
box-sizing: border-box;
3231
border: 1px solid var(--Dash-Stroke-Strong);
33-
}
34-
35-
.dash-options-list-option-checkbox:hover,
36-
.dash-options-list-option-checkbox:focus,
37-
.dash-options-list-option-checkbox:checked {
3832
accent-color: var(--Dash-Fill-Interactive-Strong);
33+
outline-color: var(--Dash-Fill-Interactive-Strong);
3934
}

components/dash-core-components/src/components/css/sliders.css

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
background-color: var(--Dash-Fill-Interactive-Strong);
6363
border: 2px solid var(--Dash-Fill-Inverse-Strong);
6464
border-radius: 50%;
65-
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
65+
box-shadow: 0 1px 3px 0 var(--Dash-Shading-Weak);
6666
cursor: pointer;
6767
outline: none;
6868
transition: all 0.15s ease-in-out;
@@ -71,7 +71,7 @@
7171
.dash-slider-thumb:focus,
7272
.dash-slider-thumb:hover {
7373
transform: scale(1.125); /* Scale to make 16px thumb appear as 18px */
74-
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
74+
box-shadow: 0 4px 6px -1px var(--Dash-Shading-Weak);
7575
}
7676

7777
.dash-slider-thumb:focus .dash-slider-tooltip,
@@ -129,7 +129,7 @@
129129
padding: calc(var(--Dash-Spacing) * 3);
130130
font-size: 12px;
131131
line-height: 1;
132-
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
132+
box-shadow: 0 0 8px var(--Dash-Shading-Strong);
133133
background-color: var(--Dash-Fill-Inverse-Strong);
134134
user-select: none;
135135
z-index: 1000;

0 commit comments

Comments
 (0)