Skip to content

Commit 3a8942e

Browse files
committed
Merge branch 'v4' into feature/dcc-redesign-dropdown-sorting
2 parents 47da621 + 391f0c8 commit 3a8942e

26 files changed

+240
-133
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
88

99
- Dropdown API changes
1010
* 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 `localizations` prop to customize strings used within the component
11+
* new `labels` prop to customize strings used within the component
1212
* default value for closeOnSelect is now `True` for single-select dropdowns and `False` for multi-select
1313

1414
- Slider API changes

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import dropdown from '../utils/LazyLoader/dropdown';
44

55
const RealDropdown = lazy(dropdown);
66

7-
const defaultLocalizations: DropdownProps['localizations'] = {
7+
const defaultLabels: DropdownProps['labels'] = {
88
select_all: 'Select All',
99
deselect_all: 'Deselect All',
1010
selected_count: '{num_selected} selected',
@@ -29,7 +29,7 @@ export default function Dropdown({
2929
disabled = false,
3030
multi = false,
3131
searchable = true,
32-
localizations = defaultLocalizations,
32+
labels = defaultLabels,
3333
optionHeight = 'auto',
3434
// eslint-disable-next-line no-magic-numbers
3535
maxHeight = 200,
@@ -40,17 +40,17 @@ export default function Dropdown({
4040
persistence_type = PersistenceTypes.local,
4141
...props
4242
}: DropdownProps) {
43-
localizations = {
44-
...defaultLocalizations,
45-
...localizations,
43+
labels = {
44+
...defaultLabels,
45+
...labels,
4646
};
4747

4848
return (
4949
<Suspense fallback={null}>
5050
<RealDropdown
5151
clearable={clearable}
5252
disabled={disabled}
53-
localizations={localizations}
53+
labels={labels}
5454
multi={multi}
5555
searchable={searchable}
5656
optionHeight={optionHeight}

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: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
cursor: pointer;
1111
font-size: inherit;
1212
overflow: hidden;
13+
accent-color: var(--Dash-Fill-Interactive-Strong);
14+
outline-color: var(--Dash-Fill-Interactive-Strong);
1315
}
1416

1517
.dash-dropdown-grid-container {
@@ -67,11 +69,11 @@
6769
background: var(--Dash-Fill-Inverse-Strong);
6870
width: fit-content;
6971
min-width: var(--radix-popover-trigger-width);
70-
max-width: 100vw;
72+
max-width: 98vw;
7173
overflow-y: auto;
72-
z-index: 50;
73-
box-shadow: 0px 10px 38px -10px rgba(22, 23, 24, 0.35),
74-
0px 10px 20px -15px rgba(22, 23, 24, 0.2);
74+
z-index: 500;
75+
box-shadow: 0px 10px 38px -10px var(--Dash-Shading-Strong),
76+
0px 10px 20px -15px var(--Dash-Shading-Weak);
7577
}
7678

7779
.dash-dropdown-value-count,
@@ -182,6 +184,8 @@
182184
text-decoration: none;
183185
color: var(--Dash-Text-Disabled);
184186
white-space: nowrap;
187+
accent-color: var(--Dash-Fill-Interactive-Strong);
188+
outline-color: var(--Dash-Fill-Interactive-Strong);
185189
}
186190

187191
.dash-dropdown-action-button:hover {

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
}
1717

1818
.dash-input-container:focus-within {
19-
outline: 2px solid var(--Dash-Fill-Interactive-Strong);
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;
2025
}
2126

2227
.dash-input-container input:focus {
@@ -40,6 +45,11 @@
4045
box-sizing: border-box;
4146
z-index: 1;
4247
order: 2;
48+
accent-color: var(--Dash-Fill-Interactive-Strong);
49+
}
50+
51+
.dash-input-element:disabled {
52+
cursor: not-allowed;
4353
}
4454

4555
/* Hide native steppers for number inputs */

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@
2929
margin: 0 calc(var(--Dash-Spacing) * 2) 0 0;
3030
box-sizing: border-box;
3131
border: 1px solid var(--Dash-Stroke-Strong);
32-
}
33-
34-
.dash-options-list-option-checkbox:hover,
35-
.dash-options-list-option-checkbox:focus,
36-
.dash-options-list-option-checkbox:checked {
3732
accent-color: var(--Dash-Fill-Interactive-Strong);
33+
outline-color: var(--Dash-Fill-Interactive-Strong);
3834
}

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@
77
touch-action: none;
88
width: 100%;
99
height: 14px;
10-
padding: 8px 0 28px 0;
10+
padding: 18px 0 18px 0;
1111
box-sizing: border-box;
1212
/* Override Radix's default margin/padding behavior */
1313
--radix-slider-thumb-width: 16px;
1414
}
1515

16+
.dash-slider-root.has-marks {
17+
padding: 8px 0 28px 0;
18+
}
19+
1620
.dash-slider-root[data-orientation='vertical'].has-marks {
1721
padding-bottom: 0px;
1822
}
@@ -58,7 +62,7 @@
5862
background-color: var(--Dash-Fill-Interactive-Strong);
5963
border: 2px solid var(--Dash-Fill-Inverse-Strong);
6064
border-radius: 50%;
61-
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
65+
box-shadow: 0 1px 3px 0 var(--Dash-Shading-Weak);
6266
cursor: pointer;
6367
outline: none;
6468
transition: all 0.15s ease-in-out;
@@ -67,7 +71,7 @@
6771
.dash-slider-thumb:focus,
6872
.dash-slider-thumb:hover {
6973
transform: scale(1.125); /* Scale to make 16px thumb appear as 18px */
70-
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
74+
box-shadow: 0 4px 6px -1px var(--Dash-Shading-Weak);
7175
}
7276

7377
.dash-slider-thumb:focus .dash-slider-tooltip,
@@ -125,7 +129,7 @@
125129
padding: calc(var(--Dash-Spacing) * 3);
126130
font-size: 12px;
127131
line-height: 1;
128-
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
132+
box-shadow: 0 0 8px var(--Dash-Shading-Strong);
129133
background-color: var(--Dash-Fill-Inverse-Strong);
130134
user-select: none;
131135
z-index: 1000;
@@ -167,7 +171,7 @@
167171
.dash-slider-container {
168172
display: flex;
169173
align-items: center;
170-
gap: 12px;
174+
gap: 16px;
171175
width: 100%;
172176
}
173177

@@ -184,7 +188,7 @@
184188
}
185189

186190
.dash-range-slider-min-input {
187-
min-width: 64px;
191+
text-align: center;
188192
}
189193

190194
.dash-range-slider-max-input {
@@ -193,7 +197,7 @@
193197

194198
.dash-range-slider-input {
195199
width: 64px;
196-
margin-top: 8px;
200+
text-align: center;
197201
-webkit-appearance: textfield;
198202
-moz-appearance: textfield;
199203
appearance: textfield;

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

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import '../components/css/dropdown.css';
1919
import isEqual from 'react-fast-compare';
2020
import {DetailedOption, DropdownProps, OptionValue} from '../types';
2121
import {OptionsList, OptionLabel} from '../utils/optionRendering';
22+
import uuid from 'uniqid';
2223

2324
const Dropdown = (props: DropdownProps) => {
2425
const {
@@ -27,7 +28,7 @@ const Dropdown = (props: DropdownProps) => {
2728
closeOnSelect,
2829
clearable,
2930
disabled,
30-
localizations,
31+
labels,
3132
maxHeight,
3233
multi,
3334
options,
@@ -350,6 +351,8 @@ const Dropdown = (props: DropdownProps) => {
350351
[filteredOptions, sanitizedValues]
351352
);
352353

354+
const accessibleId = id ?? uuid();
355+
353356
return (
354357
<Popover.Root open={isOpen} onOpenChange={handleOpenChange}>
355358
<Popover.Trigger asChild>
@@ -365,25 +368,34 @@ const Dropdown = (props: DropdownProps) => {
365368
}}
366369
className={`dash-dropdown ${className ?? ''}`}
367370
style={style}
368-
aria-label={props.placeholder}
371+
aria-labelledby={`${accessibleId}-value-count ${accessibleId}-value`}
369372
aria-haspopup="listbox"
370373
aria-expanded={isOpen}
371374
data-dash-is-loading={loading || undefined}
372375
>
373376
<span className="dash-dropdown-grid-container dash-dropdown-trigger">
374377
{displayValue.length > 0 && (
375-
<span className="dash-dropdown-value">
378+
<span
379+
id={accessibleId + '-value'}
380+
className="dash-dropdown-value"
381+
>
376382
{displayValue}
377383
</span>
378384
)}
379385
{displayValue.length === 0 && (
380-
<span className="dash-dropdown-value dash-dropdown-placeholder">
386+
<span
387+
id={accessibleId + '-value'}
388+
className="dash-dropdown-value dash-dropdown-placeholder"
389+
>
381390
{props.placeholder}
382391
</span>
383392
)}
384393
{sanitizedValues.length > 1 && (
385-
<span className="dash-dropdown-value-count">
386-
{localizations?.selected_count?.replace(
394+
<span
395+
id={accessibleId + '-value-count'}
396+
className="dash-dropdown-value-count"
397+
>
398+
{labels?.selected_count?.replace(
387399
'{num_selected}',
388400
`${sanitizedValues.length}`
389401
)}
@@ -396,8 +408,8 @@ const Dropdown = (props: DropdownProps) => {
396408
e.preventDefault();
397409
handleClear();
398410
}}
399-
title={localizations?.clear_selection}
400-
aria-label={localizations?.clear_selection}
411+
title={labels?.clear_selection}
412+
aria-label={labels?.clear_selection}
401413
>
402414
<Cross1Icon />
403415
</a>
@@ -408,7 +420,7 @@ const Dropdown = (props: DropdownProps) => {
408420
</button>
409421
</Popover.Trigger>
410422

411-
<Popover.Portal container={dropdownContainerRef.current}>
423+
<Popover.Portal>
412424
<Popover.Content
413425
ref={dropdownContentRef}
414426
className="dash-dropdown-content"
@@ -426,7 +438,7 @@ const Dropdown = (props: DropdownProps) => {
426438
<input
427439
type="search"
428440
className="dash-dropdown-search"
429-
placeholder={localizations?.search}
441+
placeholder={labels?.search}
430442
value={search_value || ''}
431443
autoComplete="off"
432444
onChange={e => onInputChange(e.target.value)}
@@ -437,7 +449,7 @@ const Dropdown = (props: DropdownProps) => {
437449
type="button"
438450
className="dash-dropdown-clear"
439451
onClick={handleClearSearch}
440-
aria-label={localizations?.clear_search}
452+
aria-label={labels?.clear_search}
441453
>
442454
<Cross1Icon />
443455
</button>
@@ -451,15 +463,15 @@ const Dropdown = (props: DropdownProps) => {
451463
className="dash-dropdown-action-button"
452464
onClick={handleSelectAll}
453465
>
454-
{localizations?.select_all}
466+
{labels?.select_all}
455467
</button>
456468
{canDeselectAll && (
457469
<button
458470
type="button"
459471
className="dash-dropdown-action-button"
460472
onClick={handleDeselectAll}
461473
>
462-
{localizations?.deselect_all}
474+
{labels?.deselect_all}
463475
</button>
464476
)}
465477
</div>
@@ -483,7 +495,7 @@ const Dropdown = (props: DropdownProps) => {
483495
{isOpen && search_value && !displayOptions.length && (
484496
<div className="dash-dropdown-options">
485497
<span className="dash-dropdown-option">
486-
{localizations?.no_options_found}
498+
{labels?.no_options_found}
487499
</span>
488500
</div>
489501
)}

0 commit comments

Comments
 (0)