From 1f4ac7bfdeb4969ac79e8abcc360c5f7c327b05a Mon Sep 17 00:00:00 2001 From: Halvor Haugan <83693529+HalvorHaugan@users.noreply.github.com> Date: Wed, 27 Nov 2024 12:29:56 +0100 Subject: [PATCH] DatePicker/MonthPicker: add support for translations provider (#3390) --- .changeset/moody-gorillas-try.md | 5 + .../react/src/date/datepicker/DatePicker.tsx | 9 +- .../date/datepicker/DatePickerStandalone.tsx | 9 +- .../src/date/datepicker/parts/Caption.tsx | 11 +- .../date/datepicker/parts/DropdownCaption.tsx | 19 +- .../src/date/datepicker/parts/WeekNumber.tsx | 47 +--- .../src/date/datepicker/parts/WeekRow.tsx | 13 +- .../react/src/date/hooks/useDatepicker.tsx | 6 +- .../react/src/date/hooks/useMonthPicker.tsx | 6 +- .../src/date/hooks/useRangeDatepicker.tsx | 6 +- .../src/date/monthpicker/MonthCaption.tsx | 19 +- .../src/date/monthpicker/MonthPicker.tsx | 8 +- .../core/react/src/date/parts/DateInput.tsx | 17 +- .../core/react/src/date/parts/DateWrapper.tsx | 18 +- @navikt/core/react/src/date/utils/index.ts | 9 +- @navikt/core/react/src/date/utils/labels.ts | 219 ------------------ @navikt/core/react/src/date/utils/locale.ts | 18 ++ .../core/react/src/util/i18n/locales/en.ts | 20 ++ .../core/react/src/util/i18n/locales/nb.ts | 20 ++ .../core/react/src/util/i18n/locales/nn.ts | 20 ++ 20 files changed, 172 insertions(+), 327 deletions(-) create mode 100644 .changeset/moody-gorillas-try.md delete mode 100644 @navikt/core/react/src/date/utils/labels.ts diff --git a/.changeset/moody-gorillas-try.md b/.changeset/moody-gorillas-try.md new file mode 100644 index 0000000000..1964d243f6 --- /dev/null +++ b/.changeset/moody-gorillas-try.md @@ -0,0 +1,5 @@ +--- +"@navikt/ds-react": patch +--- + +DatePicker/MonthPicker: Remove pointerEvents=none on CalendarIcon so that the title shows up as tooltip on hover diff --git a/@navikt/core/react/src/date/datepicker/DatePicker.tsx b/@navikt/core/react/src/date/datepicker/DatePicker.tsx index 64b9f65d33..7c150d62a4 100644 --- a/@navikt/core/react/src/date/datepicker/DatePicker.tsx +++ b/@navikt/core/react/src/date/datepicker/DatePicker.tsx @@ -5,10 +5,11 @@ import { DateRange, DayPicker, isMatch } from "react-day-picker"; import { omit } from "../../util"; import { useId } from "../../util/hooks"; import { useMergeRefs } from "../../util/hooks/useMergeRefs"; +import { useDateLocale } from "../../util/i18n/i18n.context"; import { DateContext } from "../context"; import { DatePickerInput } from "../parts/DateInput"; import { DateWrapper } from "../parts/DateWrapper"; -import { getLocaleFromString, labels } from "../utils"; +import { getLocaleFromString } from "../utils"; import DatePickerStandalone from "./DatePickerStandalone"; import Caption from "./parts/Caption"; import DropdownCaption from "./parts/DropdownCaption"; @@ -66,7 +67,7 @@ export const DatePicker = forwardRef( ( { children, - locale = "nb", + locale, dropdownCaption, disabled = [], disableWeekends = false, @@ -85,6 +86,7 @@ export const DatePicker = forwardRef( }, ref, ) => { + const langProviderLocale = useDateLocale(); const ariaId = useId(id); const [open, setOpen] = useState(_open ?? false); @@ -114,7 +116,7 @@ export const DatePicker = forwardRef( const DatePickerComponent = ( ( }} weekStartsOn={1} initialFocus={false} - labels={labels as any} modifiers={{ weekend: (day) => disableWeekends && isWeekend(day), }} diff --git a/@navikt/core/react/src/date/datepicker/DatePickerStandalone.tsx b/@navikt/core/react/src/date/datepicker/DatePickerStandalone.tsx index f4ed9d74e2..dcf132e60c 100644 --- a/@navikt/core/react/src/date/datepicker/DatePickerStandalone.tsx +++ b/@navikt/core/react/src/date/datepicker/DatePickerStandalone.tsx @@ -3,7 +3,8 @@ import { isWeekend } from "date-fns"; import React, { forwardRef } from "react"; import { DateRange, DayPicker, isMatch } from "react-day-picker"; import { omit } from "../../util"; -import { getLocaleFromString, labels } from "../utils"; +import { useDateLocale } from "../../util/i18n/i18n.context"; +import { getLocaleFromString } from "../utils"; import Caption from "./parts/Caption"; import DropdownCaption from "./parts/DropdownCaption"; import { HeadRow } from "./parts/HeadRow"; @@ -49,7 +50,7 @@ export const DatePickerStandalone: DatePickerStandaloneType = forwardRef< ( { className, - locale = "nb", + locale, dropdownCaption, disabled = [], disableWeekends = false, @@ -63,6 +64,7 @@ export const DatePickerStandalone: DatePickerStandaloneType = forwardRef< }, ref, ) => { + const langProviderLocale = useDateLocale(); const [selectedDates, setSelectedDates] = React.useState< Date | Date[] | DateRange | undefined >(defaultSelected); @@ -83,7 +85,7 @@ export const DatePickerStandalone: DatePickerStandaloneType = forwardRef< className={cl("navds-date__standalone-wrapper", className)} > disableWeekends && isWeekend(day), }} diff --git a/@navikt/core/react/src/date/datepicker/parts/Caption.tsx b/@navikt/core/react/src/date/datepicker/parts/Caption.tsx index 8df9eb357d..9d39a447ce 100644 --- a/@navikt/core/react/src/date/datepicker/parts/Caption.tsx +++ b/@navikt/core/react/src/date/datepicker/parts/Caption.tsx @@ -3,6 +3,8 @@ import { CaptionProps, useDayPicker, useNavigation } from "react-day-picker"; import { ArrowLeftIcon, ArrowRightIcon } from "@navikt/aksel-icons"; import { Button } from "../../../button"; import { Label } from "../../../typography"; +import { useI18n } from "../../../util/i18n/i18n.context"; +import { getTranslations } from "../../utils"; import WeekRow from "./WeekRow"; /** @@ -11,13 +13,10 @@ import WeekRow from "./WeekRow"; export const DatePickerCaption = ({ displayMonth, id }: CaptionProps) => { const { goToMonth, nextMonth, previousMonth } = useNavigation(); const { - labels: { labelPrevious, labelNext }, formatters: { formatCaption }, locale, } = useDayPicker(); - - const previousLabel = labelPrevious(previousMonth, { locale }); - const nextLabel = labelNext(nextMonth, { locale }); + const translate = useI18n("DatePicker", getTranslations(locale.code)); return ( <> @@ -26,7 +25,7 @@ export const DatePickerCaption = ({ displayMonth, id }: CaptionProps) => { variant="tertiary" disabled={!previousMonth} onClick={() => previousMonth && goToMonth(previousMonth)} - icon={} + icon={} className="navds-date__caption-button" type="button" /> @@ -40,7 +39,7 @@ export const DatePickerCaption = ({ displayMonth, id }: CaptionProps) => { {formatCaption(displayMonth, { locale })} diff --git a/@navikt/core/react/src/date/parts/DateWrapper.tsx b/@navikt/core/react/src/date/parts/DateWrapper.tsx index 965ed0c2e5..b20f9ad325 100644 --- a/@navikt/core/react/src/date/parts/DateWrapper.tsx +++ b/@navikt/core/react/src/date/parts/DateWrapper.tsx @@ -5,14 +5,23 @@ import { Modal } from "../../modal"; import { useModalContext } from "../../modal/Modal.context"; import { Popover } from "../../popover"; import { useMedia } from "../../util/hooks"; -import { modalCloseButtonLabel, modalLabel } from "../utils/labels"; +import { useI18n } from "../../util/i18n/i18n.context"; +import { getTranslations } from "../utils"; + +const variantToLabel = { + single: "chooseDate", + multiple: "chooseDates", + range: "chooseDateRange", + month: "chooseMonth", +} as const; type DateWrapperProps = { open: boolean; children: React.ReactNode; onClose: () => void; anchor: HTMLDivElement | null; - locale: "nb" | "nn" | "en"; + /** @deprecated Temporary to support locale prop */ + locale: "nb" | "nn" | "en" | undefined; variant: "single" | "multiple" | "range" | "month"; popoverProps: { id?: string; @@ -29,6 +38,7 @@ export const DateWrapper = ({ variant, popoverProps, }: DateWrapperProps) => { + const translate = useI18n("DatePicker", getTranslations(locale)); const modalRef = useRef(null); const isInModal = useModalContext(false) !== undefined; const hideModal = @@ -61,7 +71,7 @@ export const DateWrapper = ({ event.stopPropagation(); onClose(); }} - aria-label={modalLabel(locale, variant)} + aria-label={translate(variantToLabel[variant])} className={cl("navds-date__modal", { "navds-date__nested-modal": isInModal, "navds-date": variant === "month", @@ -76,7 +86,7 @@ export const DateWrapper = ({ size="small" type="button" > - {modalCloseButtonLabel(locale)} + {translate("close")} diff --git a/@navikt/core/react/src/date/utils/index.ts b/@navikt/core/react/src/date/utils/index.ts index dd415b2d3f..4e6db10410 100644 --- a/@navikt/core/react/src/date/utils/index.ts +++ b/@navikt/core/react/src/date/utils/index.ts @@ -1,18 +1,11 @@ export { formatDateForInput } from "./format-date"; export { getMonths, getYears } from "./get-dates"; -export { - labelMonthDropdown, - labelYearDropdown, - labels, - labelNextYear, - labelPrevYear, -} from "./labels"; export { INPUT_DATE_STRING_FORMAT_DATE, INPUT_DATE_STRING_FORMAT_MONTH, parseDate, } from "./parse-date"; -export { getLocaleFromString } from "./locale"; +export { getLocaleFromString, getTranslations } from "./locale"; export { disableDate } from "./dates-disabled"; export { dateIsInCurrentMonth, isValidDate } from "./check-dates"; diff --git a/@navikt/core/react/src/date/utils/labels.ts b/@navikt/core/react/src/date/utils/labels.ts deleted file mode 100644 index 0e6ec16491..0000000000 --- a/@navikt/core/react/src/date/utils/labels.ts +++ /dev/null @@ -1,219 +0,0 @@ -import { Locale } from "date-fns"; -import { Labels, NavButtonLabel } from "react-day-picker"; - -const labelNext: NavButtonLabel = (date, options) => { - switch (options?.locale?.code) { - case "nb": - return "Gå til neste måned"; - case "nn": - return "Gå til neste månad"; - case "en": - return "Go to next month"; - default: - return "Gå til neste måned"; - } -}; - -const labelPrevious: NavButtonLabel = (date, options) => { - switch (options?.locale?.code) { - case "nb": - return "Gå til forrige måned"; - case "nn": - return "Gå til førre månad"; - case "en": - return "Go to previous month"; - default: - return "Gå til forrige måned"; - } -}; - -export const labelYearDropdown = (locale: Locale) => { - switch (locale?.code) { - case "nb": - return "År"; - case "nn": - return "År"; - case "en": - return "Year"; - default: - return "År"; - } -}; - -export const labelMonthDropdown = (locale: Locale) => { - switch (locale?.code) { - case "nb": - return "Måned"; - case "nn": - return "Månad"; - case "en": - return "Month"; - default: - return "Måned"; - } -}; - -export const labelNextYear = (localeCode: string | undefined) => { - switch (localeCode) { - case "nb": - return "Gå til neste år"; - case "nn": - return "Gå til neste år"; - case "en-GB": - return "Go to next year"; - default: - return "Gå til neste måned"; - } -}; - -export const labelPrevYear = (localeCode: string | undefined): string => { - switch (localeCode) { - case "nb": - return "Gå til forrige år"; - case "nn": - return "Gå til førre år"; - case "en-GB": - return "Go to next year"; - default: - return "Gå til neste år"; - } -}; - -export const labels: Partial = { - labelNext, - labelPrevious, -}; - -export const labelWeekNumber = ({ - localeCode, - week, -}: { - localeCode?: string; - week: number; -}): string => { - switch (localeCode) { - case "nb": - return `Uke ${week}`; - case "nn": - return `Veke ${week}`; - case "en-GB": - return `Week ${week}`; - default: - return `Uke ${week}`; - } -}; - -export const labelWeekNumberButton = ({ - localeCode, - week, -}: { - localeCode?: string; - week: number; -}): string => { - switch (localeCode) { - case "nb": - return `Velg uke ${week}`; - case "nn": - return `Vel veke ${week}`; - case "en-GB": - return `Pick week ${week}`; - default: - return `Velg uke ${week}`; - } -}; - -export const labelWeek = (localeCode?: string): string => { - switch (localeCode) { - case "nb": - return `Uke:`; - case "nn": - return `Veke:`; - case "en-GB": - return `Week:`; - default: - return `Uke:`; - } -}; - -const modalLabelSingle = (localeCode?: string): string => { - switch (localeCode) { - case "nb": - return `Velg dato`; - case "nn": - return `Vel dato`; - case "en-GB": - return `Pick a date`; - default: - return `Velg dato`; - } -}; - -const modalLabelMultiple = (localeCode?: string): string => { - switch (localeCode) { - case "nb": - return `Velg datoer`; - case "nn": - return `Vel datoar`; - case "en-GB": - return `Pick dates`; - default: - return `Velg datoer`; - } -}; - -const modalLabelRanged = (localeCode?: string): string => { - switch (localeCode) { - case "nb": - return `Velg start- og sluttdato`; - case "nn": - return `Vel start- og sluttdato`; - case "en-GB": - return `Pick a start and end date`; - default: - return `Velg start- og sluttdato`; - } -}; - -const modalLabelMonth = (localeCode?: string): string => { - switch (localeCode) { - case "nb": - return `Velg måned`; - case "nn": - return `Vel månad`; - case "en-GB": - return `Pick a month`; - default: - return `Velg måned`; - } -}; - -export const modalLabel = ( - localeCode: string, - variant: "single" | "multiple" | "range" | "month", -) => { - switch (variant) { - case "single": - return modalLabelSingle(localeCode); - case "multiple": - return modalLabelMultiple(localeCode); - case "range": - return modalLabelRanged(localeCode); - case "month": - return modalLabelMonth(localeCode); - default: - return modalLabelSingle(localeCode); - } -}; - -export const modalCloseButtonLabel = (localeCode?: string): string => { - switch (localeCode) { - case "nb": - return `Lukk`; - case "nn": - return `Lukk`; - case "en-GB": - return `Close`; - default: - return `Lukk`; - } -}; diff --git a/@navikt/core/react/src/date/utils/locale.ts b/@navikt/core/react/src/date/utils/locale.ts index 5392bf159f..e9431b386a 100644 --- a/@navikt/core/react/src/date/utils/locale.ts +++ b/@navikt/core/react/src/date/utils/locale.ts @@ -1,4 +1,6 @@ import { enGB, nb, nn } from "date-fns/locale"; +import en_translations from "../../util/i18n/locales/en"; +import nn_translations from "../../util/i18n/locales/nn"; /** @private */ export const getLocaleFromString = (locale: "nb" | "nn" | "en" = "nb") => { @@ -11,3 +13,19 @@ export const getLocaleFromString = (locale: "nb" | "nn" | "en" = "nb") => { return nb; } }; + +/** + * @private + * Temporary for backwards compatibility with locale prop + */ +export const getTranslations = (locale: string | undefined) => { + switch (locale) { + case "nn": + return nn_translations.DatePicker; + case "en": + case "en-GB": + return en_translations.DatePicker; + default: + return undefined; + } +}; diff --git a/@navikt/core/react/src/util/i18n/locales/en.ts b/@navikt/core/react/src/util/i18n/locales/en.ts index 9a4aaa6f8f..02d44ef73a 100644 --- a/@navikt/core/react/src/util/i18n/locales/en.ts +++ b/@navikt/core/react/src/util/i18n/locales/en.ts @@ -97,4 +97,24 @@ export default { reset: "Reset zoom", }, }, + DatePicker: { + close: "Close", + chooseDate: "Choose date", + chooseDates: "Choose dates", + chooseDateRange: "Choose start and end date", + chooseMonth: "Choose month", + week: "Week", + weekNumber: "Week {week}", + selectWeekNumber: "Select week {week}", + month: "Month", + goToNextMonth: "Go to next month", + goToPreviousMonth: "Go to previous month", + year: "Year", + goToNextYear: "Go to next year", + goToPreviousYear: "Go to previous year", + openDatePicker: "Open date picker", + openMonthPicker: "Open month picker", + closeDatePicker: "Close date picker", + closeMonthPicker: "Close month picker", + }, } satisfies Translations; diff --git a/@navikt/core/react/src/util/i18n/locales/nb.ts b/@navikt/core/react/src/util/i18n/locales/nb.ts index 1ec694f440..38b2073d90 100644 --- a/@navikt/core/react/src/util/i18n/locales/nb.ts +++ b/@navikt/core/react/src/util/i18n/locales/nb.ts @@ -102,4 +102,24 @@ export default { reset: "Tilbakestill tidsperspektiv", }, }, + DatePicker: { + close: "Lukk", // TODO: Consider making global + chooseDate: "Velg dato", + chooseDates: "Velg datoer", + chooseDateRange: "Velg start- og sluttdato", + chooseMonth: "Velg måned", + week: "Uke", + weekNumber: "Uke {week}", + selectWeekNumber: "Velg uke {week}", + month: "Måned", + goToNextMonth: "Gå til neste måned", + goToPreviousMonth: "Gå til forrige måned", + year: "År", + goToNextYear: "Gå til neste år", + goToPreviousYear: "Gå til forrige år", + openDatePicker: "Åpne datovelger", + openMonthPicker: "Åpne månedsvelger", + closeDatePicker: "Lukk datovelger", + closeMonthPicker: "Lukk månedsvelger", + }, } satisfies TranslationMap; diff --git a/@navikt/core/react/src/util/i18n/locales/nn.ts b/@navikt/core/react/src/util/i18n/locales/nn.ts index 6c0bae318c..6f2f1dfbee 100644 --- a/@navikt/core/react/src/util/i18n/locales/nn.ts +++ b/@navikt/core/react/src/util/i18n/locales/nn.ts @@ -97,4 +97,24 @@ export default { reset: "Tilbakestill tidsperspektiv", }, }, + DatePicker: { + close: "Lukk", + chooseDate: "Vel dato", + chooseDates: "Vel datoar", + chooseDateRange: "Vel start- og sluttdato", + chooseMonth: "Vel månad", + week: "Veke", + weekNumber: "Veke {week}", + selectWeekNumber: "Vel veke {week}", + month: "Månad", + goToNextMonth: "Gå til neste månad", + goToPreviousMonth: "Gå til førre månad", + year: "År", + goToNextYear: "Gå til neste år", + goToPreviousYear: "Gå til førre år", + openDatePicker: "Opne datoveljar", + openMonthPicker: "Opne månadsveljar", + closeDatePicker: "Lukk datoveljar", + closeMonthPicker: "Lukk månadsveljar", + }, } satisfies Translations;