From 284afe446aa3fb6f2ec6bf4d9f05f5392fc63c92 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Sat, 14 Sep 2024 05:03:59 -0700 Subject: [PATCH 1/5] enable value parser --- src/ts/components/dates/DateInput.tsx | 3 +++ src/ts/components/dates/DatesProvider.tsx | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) 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..3583ae98 100644 --- a/src/ts/components/dates/DatesProvider.tsx +++ b/src/ts/components/dates/DatesProvider.tsx @@ -4,6 +4,7 @@ import { } from "@mantine/dates"; import dayjs from "dayjs"; import React, { useEffect } from "react"; +import customParseFormat from 'dayjs/plugin/customParseFormat'; interface Props extends DatesProviderProps { /** Unique ID to identify this component in Dash callbacks. */ @@ -17,12 +18,11 @@ const DatesProvider = (props: Props) => { const { settings, children, setProps, ...others } = props; const { locale } = settings; - useEffect(() => { - const localeObject = window[`dayjs_locale_${locale}`]; - if (localeObject) { - dayjs.locale(locale, localeObject); - } - }, [locale]); + const localeObject = window[`dayjs_locale_${locale}`]; + if (localeObject) { + dayjs.locale(locale, localeObject); + dayjs.extend(customParseFormat); + } return ( @@ -33,4 +33,4 @@ const DatesProvider = (props: Props) => { DatesProvider.defaultProps = {}; -export default DatesProvider; +export default DatesProvider; \ No newline at end of file From bfe0fe79e84ac289644289427cde054180dc756e Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Sat, 14 Sep 2024 05:04:45 -0700 Subject: [PATCH 2/5] sample apps for testing --- usage-265/dateparser.py | 40 +++++++++++++++++++++++++++++++++ usage-265/locale-date-names.py | 31 +++++++++++++++++++++++++ usage-265/locale-persistence.py | 31 +++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 usage-265/dateparser.py create mode 100644 usage-265/locale-date-names.py create mode 100644 usage-265/locale-persistence.py diff --git a/usage-265/dateparser.py b/usage-265/dateparser.py new file mode 100644 index 00000000..dca42a78 --- /dev/null +++ b/usage-265/dateparser.py @@ -0,0 +1,40 @@ + +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" +) + +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 +],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-persistence.py b/usage-265/locale-persistence.py new file mode 100644 index 00000000..da4d0027 --- /dev/null +++ b/usage-265/locale-persistence.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", + clearable=True, + valueFormat="YYYY-MM-DD", + label = "Date input YYYY-MM-DD", + placeholder = "Date input YYYY-MM-DD", + persistence=True +) + +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) + From 906da1e6b39a4d7790fd451dc1f1c481f3209a09 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Sun, 15 Sep 2024 07:45:56 -0700 Subject: [PATCH 3/5] changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd835b2a..5339fdfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ # 0.14.5 UNRELEASED +### 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 + ### Added - New components From 641db67c2764adca34e1c0e38985b47e9a6a4e52 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Thu, 26 Sep 2024 09:24:02 -0700 Subject: [PATCH 4/5] update after review --- src/ts/components/dates/DatesProvider.tsx | 12 ++++++++---- usage-265/dateparser.py | 10 +++++++++- usage-265/locale-persistence.py | 3 ++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/ts/components/dates/DatesProvider.tsx b/src/ts/components/dates/DatesProvider.tsx index 3583ae98..e5e03611 100644 --- a/src/ts/components/dates/DatesProvider.tsx +++ b/src/ts/components/dates/DatesProvider.tsx @@ -6,6 +6,8 @@ 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. */ id?: string; @@ -18,10 +20,12 @@ const DatesProvider = (props: Props) => { const { settings, children, setProps, ...others } = props; const { locale } = settings; - const localeObject = window[`dayjs_locale_${locale}`]; - if (localeObject) { - dayjs.locale(locale, localeObject); - dayjs.extend(customParseFormat); + if (!REGISTERED[locale]) { + REGISTERED[locale] = true; + const localeObject = window[`dayjs_locale_${locale}`]; + if (localeObject) { + dayjs.locale(locale, localeObject); + } } return ( diff --git a/usage-265/dateparser.py b/usage-265/dateparser.py index dca42a78..5451202d 100644 --- a/usage-265/dateparser.py +++ b/usage-265/dateparser.py @@ -27,12 +27,20 @@ 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_picker2, + date_picker3 ],p=20)) if __name__ == "__main__": diff --git a/usage-265/locale-persistence.py b/usage-265/locale-persistence.py index da4d0027..f9b12a67 100644 --- a/usage-265/locale-persistence.py +++ b/usage-265/locale-persistence.py @@ -17,7 +17,8 @@ valueFormat="YYYY-MM-DD", label = "Date input YYYY-MM-DD", placeholder = "Date input YYYY-MM-DD", - persistence=True + persistence=True, + value="2022-01-01" ) app.layout = dmc.MantineProvider([ From 068aae053c661d2e285129e0f2cb4fae765b462a Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Thu, 26 Sep 2024 10:43:07 -0700 Subject: [PATCH 5/5] added more use-cases --- usage-265/locale-multiple-updateable.py | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 usage-265/locale-multiple-updateable.py 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) +