Skip to content

Commit 3d63e35

Browse files
authored
Merge pull request #3629 from AnnMarieW/fix-datepicker-input-size
Fix date pickers not showing date when initially rendered in a hidden container
2 parents 50cb3e4 + edb937d commit 3d63e35

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
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+
## Fixed
8+
- [#3629](https://github.com/plotly/dash/pull/3629) Fix date pickers not showing date when initially rendered in a hidden container.
9+
10+
511
## [4.0.0] - 2026-02-03
612

713
## Added

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
strAsDate,
2121
} from '../utils/calendar/helpers';
2222
import {captureCSSForPortal} from '../utils/calendar/cssVariables';
23+
import ResizeDetector from '../utils/ResizeDetector';
2324
import '../components/css/datepickers.css';
2425

2526
const DatePickerRange = ({
@@ -104,6 +105,8 @@ const DatePickerRange = ({
104105
const containerRef = useRef<HTMLDivElement>(null);
105106
const startInputRef = useRef<HTMLInputElement | null>(null);
106107
const endInputRef = useRef<HTMLInputElement | null>(null);
108+
const startAutosizeRef = useRef<any>(null);
109+
const endAutosizeRef = useRef<any>(null);
107110
const calendarRef = useRef<CalendarHandle>(null);
108111
const hasPortal = with_portal || with_full_screen_portal;
109112

@@ -128,6 +131,19 @@ const DatePickerRange = ({
128131
setEndInputValue(formatDate(internalEndDate, display_format));
129132
}, [internalEndDate, display_format]);
130133

134+
const handleResize = useCallback(() => {
135+
startAutosizeRef.current?.updateInputWidth?.();
136+
endAutosizeRef.current?.updateInputWidth?.();
137+
}, []);
138+
139+
useEffect(() => {
140+
startAutosizeRef.current?.updateInputWidth?.();
141+
}, [startInputValue]);
142+
143+
useEffect(() => {
144+
endAutosizeRef.current?.updateInputWidth?.();
145+
}, [endInputValue]);
146+
131147
useEffect(() => {
132148
// Controls when setProps is called. Basically, whenever internal state
133149
// diverges from props (i.e., user interaction)
@@ -313,6 +329,10 @@ const DatePickerRange = ({
313329
);
314330

315331
return (
332+
<ResizeDetector
333+
onResize={handleResize}
334+
targets={[containerRef]}
335+
>
316336
<div className="dash-datepicker" ref={containerRef}>
317337
<Popover.Root
318338
open={!disabled && isCalendarOpen}
@@ -335,6 +355,7 @@ const DatePickerRange = ({
335355
}}
336356
>
337357
<AutosizeInput
358+
ref={startAutosizeRef}
338359
inputRef={node => {
339360
startInputRef.current = node;
340361
}}
@@ -356,6 +377,7 @@ const DatePickerRange = ({
356377
/>
357378
<ArrowIcon className="dash-datepicker-range-arrow" />
358379
<AutosizeInput
380+
ref={endAutosizeRef}
359381
inputRef={node => {
360382
endInputRef.current = node;
361383
}}
@@ -458,6 +480,7 @@ const DatePickerRange = ({
458480
</Popover.Portal>
459481
</Popover.Root>
460482
</div>
483+
</ResizeDetector>
461484
);
462485
};
463486

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
strAsDate,
1515
} from '../utils/calendar/helpers';
1616
import {captureCSSForPortal} from '../utils/calendar/cssVariables';
17+
import ResizeDetector from '../utils/ResizeDetector';
1718
import '../components/css/datepickers.css';
1819

1920
const DatePickerSingle = ({
@@ -63,6 +64,7 @@ const DatePickerSingle = ({
6364

6465
const containerRef = useRef<HTMLDivElement>(null);
6566
const inputRef = useRef<HTMLInputElement | null>(null);
67+
const autosizeRef = useRef<any>(null);
6668
const calendarRef = useRef<CalendarHandle>(null);
6769
const hasPortal = with_portal || with_full_screen_portal;
6870

@@ -87,6 +89,15 @@ const DatePickerSingle = ({
8789
}
8890
}, [internalDate]);
8991

92+
const handleResize = useCallback(() => {
93+
autosizeRef.current?.updateInputWidth?.();
94+
}, []);
95+
96+
97+
useEffect(() => {
98+
autosizeRef.current?.updateInputWidth?.();
99+
}, [inputValue]);
100+
90101
const parseUserInput = useCallback(
91102
(focusCalendar = false) => {
92103
if (inputValue === '') {
@@ -157,6 +168,7 @@ const DatePickerSingle = ({
157168
}
158169

159170
return (
171+
<ResizeDetector onResize={handleResize} targets={[containerRef]}>
160172
<div className="dash-datepicker" ref={containerRef}>
161173
<Popover.Root
162174
open={!disabled && isCalendarOpen}
@@ -179,6 +191,7 @@ const DatePickerSingle = ({
179191
}}
180192
>
181193
<AutosizeInput
194+
ref={autosizeRef}
182195
inputRef={node => {
183196
inputRef.current = node;
184197
}}
@@ -274,6 +287,7 @@ const DatePickerSingle = ({
274287
</Popover.Portal>
275288
</Popover.Root>
276289
</div>
290+
</ResizeDetector>
277291
);
278292
};
279293

components/dash-core-components/tests/integration/calendar/test_date_picker_single.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,3 +676,43 @@ def display_date(date):
676676
), "Input should display 2021-06-23"
677677

678678
assert dash_dcc.get_logs() == []
679+
680+
681+
def test_dtps031_resize_detector(dash_dcc):
682+
"""Test that DatePickerSingle displays date if initially rendered in hidden container"""
683+
app = Dash(__name__)
684+
app.layout = html.Div(
685+
[
686+
html.Button("Unhide", id="update-btn"),
687+
html.Div(
688+
id="hidden",
689+
style={"display": "none"},
690+
children=dcc.DatePickerSingle(date="2026-02-24", id="dps"),
691+
),
692+
]
693+
)
694+
695+
@app.callback(
696+
Output("hidden", "style"),
697+
Input("update-btn", "n_clicks"),
698+
prevent_initial_call=True,
699+
)
700+
def update_date(n_clicks):
701+
return {}
702+
703+
dash_dcc.start_server(app)
704+
705+
input_element = dash_dcc.find_element(".dash-datepicker-input")
706+
initial_style = input_element.get_attribute("style")
707+
assert "width: 2px;" in initial_style
708+
709+
# Click button to unhide
710+
btn = dash_dcc.find_element("#update-btn")
711+
btn.click()
712+
time.sleep(0.5)
713+
714+
updated_style = input_element.get_attribute("style")
715+
716+
assert "width: 77px;" in updated_style
717+
718+
assert dash_dcc.get_logs() == []

0 commit comments

Comments
 (0)