From 34cc0d3c4585f872f9dac806d15d2018537271cb Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Mon, 2 Sep 2024 15:14:04 +0200 Subject: [PATCH 1/4] - When travel calendar input is not in focus, show date description if a valid date has been entered. --- .../TravelDateCalendar.tsx | 1 + .../TravelDateRangeCalendar.tsx | 1 + .../travel-date-input/TravelDateInput.tsx | 1 + .../TravelDateRangeInput.tsx | 1 + .../TravelDateSingleTextInputField.tsx | 3 +++ .../components/TravelDateTextInput.tsx | 7 ++++++- .../components/TravelDateTextInputFields.tsx | 6 ++++++ .../hooks/UseTravelDateInput.ts | 10 ++++++++++ .../hooks/UseTravelDateRangeInput.ts | 19 +++++++++++++++++++ .../util/DateDescriptionFormatter.ts | 7 +++++++ packages/input-mask/src/hooks/UseInputMask.ts | 10 +++++++--- 11 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts diff --git a/packages/calendar/src/components/calendar-types/travel-date-calendar/TravelDateCalendar.tsx b/packages/calendar/src/components/calendar-types/travel-date-calendar/TravelDateCalendar.tsx index 127f4db27..353610bd2 100644 --- a/packages/calendar/src/components/calendar-types/travel-date-calendar/TravelDateCalendar.tsx +++ b/packages/calendar/src/components/calendar-types/travel-date-calendar/TravelDateCalendar.tsx @@ -71,6 +71,7 @@ export const TravelDateCalendar: React.FC = ({ )} )} = ({ zIndex={calendarInDom ? zIndex : zIndexWhenClosed} > = ({ zIndex={calendarInDom ? zIndex : zIndexWhenClosed} > void; calendarSize: TravelCalendarSizeVariant; placeholderWhenBlurred: string | undefined; + valueWhenBlurred: string | undefined; } export const TravelDateSingleTextInputField: React.FC< @@ -27,6 +28,7 @@ export const TravelDateSingleTextInputField: React.FC< onFocus, calendarSize, placeholderWhenBlurred, + valueWhenBlurred, }) => { const { mask, placeholder } = useMemo(() => { const dateFormatForLocaleCode = getDateFormatForLocaleCode(localeCode); @@ -53,6 +55,7 @@ export const TravelDateSingleTextInputField: React.FC< placeholder={placeholder} calendarSize={calendarSize} placeholderWhenBlurred={placeholderWhenBlurred} + valueWhenBlurred={valueWhenBlurred} /> ); diff --git a/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx b/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx index 389c8bccb..fe606dda9 100644 --- a/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx +++ b/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx @@ -22,6 +22,7 @@ export interface TravelDateTextInputProps extends LabelledTextInputProps { showMask?: boolean; calendarSize: TravelCalendarSizeVariant; placeholderWhenBlurred: string | undefined; + valueWhenBlurred: string | undefined; } export const TravelDateTextInput: React.FC = ({ @@ -39,6 +40,7 @@ export const TravelDateTextInput: React.FC = ({ onBlur, placeholderWhenBlurred, placeholder, + valueWhenBlurred, ...inputProps }) => { const inputRef = useRef(null); @@ -54,7 +56,8 @@ export const TravelDateTextInput: React.FC = ({ guide, keepCharPositions, placeholderChar, - showMask + showMask, + isFocused ); const onFocusHandler = useCallback>( @@ -80,6 +83,8 @@ export const TravelDateTextInput: React.FC = ({ return ( { const { mask, placeholder } = useMemo(() => { const dateFormatForLocaleCode = getDateFormatForLocaleCode(localeCode); @@ -65,6 +69,7 @@ export const TravelDateTextInputFields: React.FC< borderRadiusVariant={"onlyLeft"} placeholder={placeholder} placeholderWhenBlurred={placeholderWhenBlurredStartDate} + valueWhenBlurred={valueWhenBlurredStartDate} calendarSize={calendarSize} /> diff --git a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts index b4b491a88..18ee3f788 100644 --- a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts +++ b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts @@ -11,6 +11,7 @@ import { getMonthInYear } from "../../../util/calendar/CalendarDataFactory"; import { startCase } from "lodash-es"; import { formatLocalizedDate } from "../../localize-date-format/LocalizedDateFormatter"; import { VisiblePanel } from "../types"; +import { formatDateDescription } from "../util/DateDescriptionFormatter"; export const useTravelDateInput = ( value: string | undefined, @@ -39,6 +40,14 @@ export const useTravelDateInput = ( [dateFormat.length, localeCode, value] ); + const valueWhenBlurred = useMemo( + () => + selectedDate != null + ? formatDateDescription(selectedDate, locale) + : undefined, + [locale, selectedDate] + ); + const [visibleMonth, setVisibleMonth] = useState( initialMonthInFocus ?? selectedDate ?? new Date() ); @@ -124,5 +133,6 @@ export const useTravelDateInput = ( selectedDate, today, visibleMonth, + valueWhenBlurred, }; }; diff --git a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts index cc2cc587d..00053d01f 100644 --- a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts +++ b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts @@ -11,6 +11,7 @@ import { getMonthInYear } from "../../../util/calendar/CalendarDataFactory"; import { startCase } from "lodash-es"; import { formatLocalizedDate } from "../../localize-date-format/LocalizedDateFormatter"; import { TravelDateRangeInputValue, VisiblePanel } from "../types"; +import { formatDateDescription } from "../util/DateDescriptionFormatter"; export const useTravelDateRangeInput = ( value: TravelDateRangeInputValue | undefined, @@ -47,6 +48,22 @@ export const useTravelDateRangeInput = ( [dateFormat.length, localeCode, value?.endDate] ); + const valueWhenBlurredStartDate = useMemo( + () => + selectedStartDate != null + ? formatDateDescription(selectedStartDate, locale) + : undefined, + [locale, selectedStartDate] + ); + + const valueWhenBlurredEndDate = useMemo( + () => + selectedEndDate != null + ? formatDateDescription(selectedEndDate, locale) + : undefined, + [locale, selectedEndDate] + ); + const [visibleMonth, setVisibleMonth] = useState( initialMonthInFocus ?? selectedStartDate ?? new Date() ); @@ -185,5 +202,7 @@ export const useTravelDateRangeInput = ( selectedEndDate, today, visibleMonth, + valueWhenBlurredStartDate, + valueWhenBlurredEndDate, }; }; diff --git a/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts b/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts new file mode 100644 index 000000000..0e493e29b --- /dev/null +++ b/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts @@ -0,0 +1,7 @@ +import { format, Locale } from "date-fns"; + +export const formatDateDescription = (date: Date, locale: Locale) => + format(date, "eee MMM do", { locale }); + +export const formatDateDescriptionLong = (date: Date, locale: Locale) => + format(date, "eeee MMMM do", { locale }); diff --git a/packages/input-mask/src/hooks/UseInputMask.ts b/packages/input-mask/src/hooks/UseInputMask.ts index 11f108e75..b7e900e29 100644 --- a/packages/input-mask/src/hooks/UseInputMask.ts +++ b/packages/input-mask/src/hooks/UseInputMask.ts @@ -16,7 +16,8 @@ export const useMaskedInput = ( guide: boolean = false, keepCharPositions: boolean = false, placeholderChar: string = "\u2000", - showMask: boolean = true + showMask: boolean = true, + enabled: boolean = true ) => { const textMask = useRef(null); @@ -33,8 +34,10 @@ export const useMaskedInput = ( showMask, }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (textMask.current as any).update(initialValue); + if (enabled) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (textMask.current as any).update(initialValue); + } }, [ inputRef, guide, @@ -44,6 +47,7 @@ export const useMaskedInput = ( placeholderChar, showMask, initialValue, + enabled, ]); return { From 9f00e0a67ba550aa68a182a641d4959fd0980c34 Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Mon, 2 Sep 2024 15:28:39 +0200 Subject: [PATCH 2/4] - Update date description. --- .../util/DateDescriptionFormatter.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts b/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts index 0e493e29b..86a41ce68 100644 --- a/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts +++ b/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts @@ -1,7 +1,17 @@ import { format, Locale } from "date-fns"; -export const formatDateDescription = (date: Date, locale: Locale) => - format(date, "eee MMM do", { locale }); +export const formatDateDescription = (date: Date, locale: Locale) => { + if (locale.code.startsWith("en")) { + return format(date, "eee MMM d", { locale }); + } else { + return format(date, "eee d MMM", { locale }); + } +}; -export const formatDateDescriptionLong = (date: Date, locale: Locale) => - format(date, "eeee MMMM do", { locale }); +export const formatDateDescriptionLong = (date: Date, locale: Locale) => { + if (locale.code.startsWith("en")) { + return format(date, "eeee MMMM d", { locale }); + } else { + return format(date, "eeee d MMMM", { locale }); + } +}; From 6b892dcc4839b9e74b1633e3b0b48145cd3e8ce8 Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Tue, 3 Sep 2024 12:35:47 +0200 Subject: [PATCH 3/4] - Add year to date description when not current year. --- .../hooks/UseTravelDateInput.ts | 4 ++-- .../hooks/UseTravelDateRangeInput.ts | 4 ++-- .../util/DateDescriptionFormatter.ts | 24 +++++++++++++------ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts index 18ee3f788..59f9fca35 100644 --- a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts +++ b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateInput.ts @@ -43,9 +43,9 @@ export const useTravelDateInput = ( const valueWhenBlurred = useMemo( () => selectedDate != null - ? formatDateDescription(selectedDate, locale) + ? formatDateDescription(selectedDate, today, locale) : undefined, - [locale, selectedDate] + [locale, selectedDate, today] ); const [visibleMonth, setVisibleMonth] = useState( diff --git a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts index 00053d01f..ad739d6d3 100644 --- a/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts +++ b/packages/calendar/src/features/travel-calendar/hooks/UseTravelDateRangeInput.ts @@ -51,7 +51,7 @@ export const useTravelDateRangeInput = ( const valueWhenBlurredStartDate = useMemo( () => selectedStartDate != null - ? formatDateDescription(selectedStartDate, locale) + ? formatDateDescription(selectedStartDate, today, locale) : undefined, [locale, selectedStartDate] ); @@ -59,7 +59,7 @@ export const useTravelDateRangeInput = ( const valueWhenBlurredEndDate = useMemo( () => selectedEndDate != null - ? formatDateDescription(selectedEndDate, locale) + ? formatDateDescription(selectedEndDate, today, locale) : undefined, [locale, selectedEndDate] ); diff --git a/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts b/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts index 86a41ce68..631235c0d 100644 --- a/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts +++ b/packages/calendar/src/features/travel-calendar/util/DateDescriptionFormatter.ts @@ -1,17 +1,27 @@ -import { format, Locale } from "date-fns"; +import { format, isSameYear, Locale } from "date-fns"; -export const formatDateDescription = (date: Date, locale: Locale) => { +export const formatDateDescription = ( + date: Date, + today: Date, + locale: Locale +) => { + const year = isSameYear(date, today) ? "" : " y"; if (locale.code.startsWith("en")) { - return format(date, "eee MMM d", { locale }); + return format(date, "eee MMM d" + year, { locale }).replace(".", ""); } else { - return format(date, "eee d MMM", { locale }); + return format(date, "eee d MMM" + year, { locale }).replace(".", ""); } }; -export const formatDateDescriptionLong = (date: Date, locale: Locale) => { +export const formatDateDescriptionLong = ( + date: Date, + today: Date, + locale: Locale +) => { + const year = isSameYear(date, today) ? "" : " y"; if (locale.code.startsWith("en")) { - return format(date, "eeee MMMM d", { locale }); + return format(date, "eeee MMMM d" + year, { locale }); } else { - return format(date, "eeee d MMMM", { locale }); + return format(date, "eeee d MMMM" + year, { locale }); } }; From dd87ae49856859421ae1c5102eaa1a64b5474623 Mon Sep 17 00:00:00 2001 From: Mattias Andersson Date: Tue, 3 Sep 2024 13:03:58 +0200 Subject: [PATCH 4/4] - Fix bug where date description was cleared when the date value was cleared. --- .../travel-calendar/components/TravelDateTextInput.tsx | 4 ++-- .../features/travel-calendar/hooks/UseTravelDateRangeInput.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx b/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx index fe606dda9..9544fec22 100644 --- a/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx +++ b/packages/calendar/src/features/travel-calendar/components/TravelDateTextInput.tsx @@ -1,9 +1,9 @@ import * as React from "react"; +import { FocusEventHandler, useCallback, useRef, useState } from "react"; import { LabelledTextInput, LabelledTextInputProps, } from "@stenajs-webui/forms"; -import { FocusEventHandler, useCallback, useRef, useState } from "react"; import { InputMask, InputMaskPipe, @@ -84,7 +84,7 @@ export const TravelDateTextInput: React.FC = ({ (