diff --git a/CHANGELOG.md b/CHANGELOG.md index 521f0fa7..153abc3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ ### Fixed +- for Date components: + - enable date parsing based on the valueFormat + - locale now works with persistence and on first render + - This PR #314 is based on #265 - Thanks for your contribution @albavilanova + - `boxWrapperProps` in the `MenuTarget` component #309 - Ensure that Mantine and stylesheet versions match to the exact version rather than the major version. #317 - Changed `in` prop name to `opened` in dmc.Collapse #311 diff --git a/src/ts/components/dates/DateInput.tsx b/src/ts/components/dates/DateInput.tsx index c77b4e20..7e6df364 100644 --- a/src/ts/components/dates/DateInput.tsx +++ b/src/ts/components/dates/DateInput.tsx @@ -13,6 +13,9 @@ import { PopoverProps } from "props/popover"; import { StylesApiProps } from "props/styles"; import React, { useState } from "react"; import { dateToString, isDisabled, stringToDate } from "../../utils/dates"; +import dayjs from "dayjs"; +import customParseFormat from 'dayjs/plugin/customParseFormat'; +dayjs.extend(customParseFormat); interface Props extends DashBaseProps, diff --git a/src/ts/components/dates/DatesProvider.tsx b/src/ts/components/dates/DatesProvider.tsx index 7742ae9a..e5e03611 100644 --- a/src/ts/components/dates/DatesProvider.tsx +++ b/src/ts/components/dates/DatesProvider.tsx @@ -4,6 +4,9 @@ import { } from "@mantine/dates"; import dayjs from "dayjs"; import React, { useEffect } from "react"; +import customParseFormat from 'dayjs/plugin/customParseFormat'; + +const REGISTERED = {} interface Props extends DatesProviderProps { /** Unique ID to identify this component in Dash callbacks. */ @@ -17,12 +20,13 @@ const DatesProvider = (props: Props) => { const { settings, children, setProps, ...others } = props; const { locale } = settings; - useEffect(() => { + if (!REGISTERED[locale]) { + REGISTERED[locale] = true; const localeObject = window[`dayjs_locale_${locale}`]; if (localeObject) { dayjs.locale(locale, localeObject); } - }, [locale]); + } return ( @@ -33,4 +37,4 @@ const DatesProvider = (props: Props) => { DatesProvider.defaultProps = {}; -export default DatesProvider; +export default DatesProvider; \ No newline at end of file diff --git a/usage-265/dateparser.py b/usage-265/dateparser.py new file mode 100644 index 00000000..5451202d --- /dev/null +++ b/usage-265/dateparser.py @@ -0,0 +1,48 @@ + +import dash_mantine_components as dmc +from dash import Dash, _dash_renderer + +_dash_renderer._set_react_version("18.2.0") + + +app = Dash(external_stylesheets=dmc.styles.ALL) + + +date_picker = dmc.DateInput( + id="date-input-308-2", + clearable=True, + valueFormat="DD/MM/YYYY", + value="2022-10=15", + label = "Date input format DD/MM/YYYY", + placeholder = "Date input DD/MM/YYYY" +) + + +date_picker2 = dmc.DateInput( + id="date-input-308", + clearable=False, + valueFormat="DD/MM/YYYY HH:mm:ss", + value="2022-10=15", + label = "Date input format DD/MM/YYYY HH:mm:ss", + placeholder = "Date input DD/MM/YYYY HH:mm:ss" +) + +date_picker3 = dmc.DateInput( + id="dateinput2", + label="Enter a date", + description="You can type a date or select from the calendar", + w=300, + ) + +app.layout = dmc.MantineProvider(dmc.Box([ + dmc.Text("Issue #308 and #249 - ability to enter date and time according to valueFormat"), + dmc.Text("Note - The entire date needs to be entered before the parser works correctly"), + dmc.Text("Note - the DateProvider is not necessary", pb=20), + date_picker, + date_picker2, + date_picker3 +],p=20)) + +if __name__ == "__main__": + app.run(debug=True) + diff --git a/usage-265/locale-date-names.py b/usage-265/locale-date-names.py new file mode 100644 index 00000000..b930a113 --- /dev/null +++ b/usage-265/locale-date-names.py @@ -0,0 +1,31 @@ + +import dash_mantine_components as dmc +from dash import Dash, _dash_renderer, Input, Output +_dash_renderer._set_react_version("18.2.0") + +scripts = [ + "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/dayjs.min.js", + "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/locale/fr.min.js", +] +app = Dash(external_scripts=scripts, external_stylesheets=dmc.styles.ALL) + + +date_picker = dmc.DateInput( + id="date-input-203=c", + clearable=True, + valueFormat="YYYY-MMMM-DD", + label = "Date input YYYY-MMMM-DD", + placeholder = "Date input", + value="2024-01-15", + pt=10 +) + +app.layout = dmc.MantineProvider(dmc.Box([ + dmc.Text("Localization (French) should appear at start - issue#203"), + dmc.Text("Try changing month in input to 'avril'. Should be able to type month in French, Note - it's necessary to include accents. issue#264"), + dmc.DatesProvider(date_picker, settings={"locale": "fr"}) +], p=20)) + +if __name__ == "__main__": + app.run(debug=True) + diff --git a/usage-265/locale-multiple-updateable.py b/usage-265/locale-multiple-updateable.py new file mode 100644 index 00000000..e22478bc --- /dev/null +++ b/usage-265/locale-multiple-updateable.py @@ -0,0 +1,46 @@ +import dash_mantine_components as dmc +from dash import Dash, _dash_renderer, Input, Output +_dash_renderer._set_react_version("18.2.0") + +scripts = [ + "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/dayjs.min.js", + "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/locale/fr.min.js", + "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/locale/de.min.js", +] +app = Dash(external_scripts=scripts, external_stylesheets=dmc.styles.ALL) + + +def make_date_picker(id): + return dmc.DateInput( + id=id, + clearable=True, + valueFormat="YYYY-MMMM-DD", + label = "Date input YYYY-MMMM-DD", + placeholder = "Date input", + value="2024-01-15", + pt=10 +) + +app.layout = dmc.MantineProvider(dmc.Box([ + dmc.Text("Demos multiple locales in one layout plus updating locale in a callback", py=10), + + dmc.DatesProvider(make_date_picker("fr"), settings={"locale": "fr"}), + dmc.DatesProvider(make_date_picker("de"), settings={"locale": "de"}), + + dmc.Button("change language", id="btn", n_clicks=0, mt=20), + dmc.DatesProvider(make_date_picker("de"), settings={"locale": "de"}, id="dates-provider"), + +], p=20)) + +@app.callback( + Output("dates-provider", "settings"), + Input("btn", "n_clicks") +) +def update(n): + if n % 2 == 0: + return {"locale": "de"} + return {"locale": "fr"} + +if __name__ == "__main__": + app.run(debug=True) + diff --git a/usage-265/locale-persistence.py b/usage-265/locale-persistence.py new file mode 100644 index 00000000..f9b12a67 --- /dev/null +++ b/usage-265/locale-persistence.py @@ -0,0 +1,32 @@ + +import dash_mantine_components as dmc +from dash import Dash, _dash_renderer, Input, Output +_dash_renderer._set_react_version("18.2.0") + + +scripts = [ + "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/dayjs.min.js", + "https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.10.8/locale/fr.min.js", +] +app = Dash(external_scripts=scripts, external_stylesheets=dmc.styles.ALL) + + +date_picker = dmc.DateInput( + id="date-input-203", + clearable=True, + valueFormat="YYYY-MM-DD", + label = "Date input YYYY-MM-DD", + placeholder = "Date input YYYY-MM-DD", + persistence=True, + value="2022-01-01" +) + +app.layout = dmc.MantineProvider([ + dmc.Text("Select a date, refresh page. Localization should persist - issue#203"), + dmc.Text("Localization (French) should appear at start - issue#203"), + dmc.DatesProvider(date_picker, settings={"locale": "fr"}) +]) + +if __name__ == "__main__": + app.run(debug=True) +