diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cb22d4d02..c46576d2c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to `dash` will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). +## [UNRELEASED] + +## Fixed +- [#3629](https://github.com/plotly/dash/pull/3629) Fix date pickers not showing date when initially rendered in a hidden container. + + ## [4.0.0] - 2026-02-03 ## Added diff --git a/components/dash-core-components/src/fragments/DatePickerRange.tsx b/components/dash-core-components/src/fragments/DatePickerRange.tsx index 1730314c8a..919c6b32b7 100644 --- a/components/dash-core-components/src/fragments/DatePickerRange.tsx +++ b/components/dash-core-components/src/fragments/DatePickerRange.tsx @@ -20,6 +20,7 @@ import { strAsDate, } from '../utils/calendar/helpers'; import {captureCSSForPortal} from '../utils/calendar/cssVariables'; +import ResizeDetector from '../utils/ResizeDetector'; import '../components/css/datepickers.css'; const DatePickerRange = ({ @@ -104,6 +105,8 @@ const DatePickerRange = ({ const containerRef = useRef(null); const startInputRef = useRef(null); const endInputRef = useRef(null); + const startAutosizeRef = useRef(null); + const endAutosizeRef = useRef(null); const calendarRef = useRef(null); const hasPortal = with_portal || with_full_screen_portal; @@ -128,6 +131,19 @@ const DatePickerRange = ({ setEndInputValue(formatDate(internalEndDate, display_format)); }, [internalEndDate, display_format]); + const handleResize = useCallback(() => { + startAutosizeRef.current?.updateInputWidth?.(); + endAutosizeRef.current?.updateInputWidth?.(); + }, []); + + useEffect(() => { + startAutosizeRef.current?.updateInputWidth?.(); + }, [startInputValue]); + + useEffect(() => { + endAutosizeRef.current?.updateInputWidth?.(); + }, [endInputValue]); + useEffect(() => { // Controls when setProps is called. Basically, whenever internal state // diverges from props (i.e., user interaction) @@ -313,6 +329,10 @@ const DatePickerRange = ({ ); return ( +
{ startInputRef.current = node; }} @@ -356,6 +377,7 @@ const DatePickerRange = ({ /> { endInputRef.current = node; }} @@ -458,6 +480,7 @@ const DatePickerRange = ({
+
); }; diff --git a/components/dash-core-components/src/fragments/DatePickerSingle.tsx b/components/dash-core-components/src/fragments/DatePickerSingle.tsx index 392ba17b6b..eff91e6515 100644 --- a/components/dash-core-components/src/fragments/DatePickerSingle.tsx +++ b/components/dash-core-components/src/fragments/DatePickerSingle.tsx @@ -14,6 +14,7 @@ import { strAsDate, } from '../utils/calendar/helpers'; import {captureCSSForPortal} from '../utils/calendar/cssVariables'; +import ResizeDetector from '../utils/ResizeDetector'; import '../components/css/datepickers.css'; const DatePickerSingle = ({ @@ -63,6 +64,7 @@ const DatePickerSingle = ({ const containerRef = useRef(null); const inputRef = useRef(null); + const autosizeRef = useRef(null); const calendarRef = useRef(null); const hasPortal = with_portal || with_full_screen_portal; @@ -87,6 +89,15 @@ const DatePickerSingle = ({ } }, [internalDate]); + const handleResize = useCallback(() => { + autosizeRef.current?.updateInputWidth?.(); + }, []); + + + useEffect(() => { + autosizeRef.current?.updateInputWidth?.(); + }, [inputValue]); + const parseUserInput = useCallback( (focusCalendar = false) => { if (inputValue === '') { @@ -157,6 +168,7 @@ const DatePickerSingle = ({ } return ( +
{ inputRef.current = node; }} @@ -274,6 +287,7 @@ const DatePickerSingle = ({
+
); }; diff --git a/components/dash-core-components/tests/integration/calendar/test_date_picker_single.py b/components/dash-core-components/tests/integration/calendar/test_date_picker_single.py index 2dfca110e9..67d68411ca 100644 --- a/components/dash-core-components/tests/integration/calendar/test_date_picker_single.py +++ b/components/dash-core-components/tests/integration/calendar/test_date_picker_single.py @@ -676,3 +676,43 @@ def display_date(date): ), "Input should display 2021-06-23" assert dash_dcc.get_logs() == [] + + +def test_dtps031_resize_detector(dash_dcc): + """Test that DatePickerSingle displays date if initially rendered in hidden container""" + app = Dash(__name__) + app.layout = html.Div( + [ + html.Button("Unhide", id="update-btn"), + html.Div( + id="hidden", + style={"display": "none"}, + children=dcc.DatePickerSingle(date="2026-02-24", id="dps"), + ), + ] + ) + + @app.callback( + Output("hidden", "style"), + Input("update-btn", "n_clicks"), + prevent_initial_call=True, + ) + def update_date(n_clicks): + return {} + + dash_dcc.start_server(app) + + input_element = dash_dcc.find_element(".dash-datepicker-input") + initial_style = input_element.get_attribute("style") + assert "width: 2px;" in initial_style + + # Click button to unhide + btn = dash_dcc.find_element("#update-btn") + btn.click() + time.sleep(0.5) + + updated_style = input_element.get_attribute("style") + + assert "width: 77px;" in updated_style + + assert dash_dcc.get_logs() == []