diff --git a/.changeset/wicked-yaks-applaud.md b/.changeset/wicked-yaks-applaud.md new file mode 100644 index 00000000000..6d1cf38e547 --- /dev/null +++ b/.changeset/wicked-yaks-applaud.md @@ -0,0 +1,9 @@ +--- +"@kaizen/components": minor +--- + +Add internal translation support for FilterDateRangePicker. + +This change allows internal strings in FilterDateRangePicker to be translated when +consuming app has set up an IntlProvider through `@cultureamp/i18n-react-intl`. +For info regarding the set up process for Intl in Kaizen, see [here](https://cultureamp.design/storybook/?path=/docs/components-kaizen-provider-internationalization-in-kaizen--docs). diff --git a/packages/components/jest.config.ts b/packages/components/jest.config.ts index 60d31778b4c..20de3a4025b 100644 --- a/packages/components/jest.config.ts +++ b/packages/components/jest.config.ts @@ -13,6 +13,7 @@ const jestConfig: JestConfigWithTsJest = { "~utils/(.*)$": "/src/utils/$1", "~components/(.*)$": "/src/$1", "~icons/(.*)$": "/src/SVG/icons/$1", + "^__@cultureamp/i18n-react-intl/locales/(.*)": "/locales/$1", }, } diff --git a/packages/components/package.json b/packages/components/package.json index b0970d2ffd1..8f70c04b7a9 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -15,7 +15,8 @@ "files": [ "future", "dist", - "icons" + "icons", + "locales" ], "main": "dist/cjs/index.js", "module": "dist/esm/index.js", @@ -37,7 +38,7 @@ "ci:test:react-17": "USE_REACT_17=true yarn test:ci" }, "dependencies": { - "@cultureamp/i18n-react-intl": "^1.3.0", + "@cultureamp/i18n-react-intl": "^1.4.2", "@kaizen/a11y": "^1.7.11", "@kaizen/brand": "^1.5.8", "@kaizen/button": "^3.0.3", diff --git a/packages/components/src/FilterDatePicker/_docs/FilterDatePicker.stickersheet.stories.tsx b/packages/components/src/FilterDatePicker/_docs/FilterDatePicker.stickersheet.stories.tsx index 1d226c0b026..e4b8a601249 100644 --- a/packages/components/src/FilterDatePicker/_docs/FilterDatePicker.stickersheet.stories.tsx +++ b/packages/components/src/FilterDatePicker/_docs/FilterDatePicker.stickersheet.stories.tsx @@ -1,4 +1,5 @@ import React, { useState } from "react" +import { StaticIntlProvider } from "@cultureamp/i18n-react-intl" import { action } from "@storybook/addon-actions" import { Meta, StoryFn } from "@storybook/react" import isChromatic from "chromatic" @@ -33,7 +34,7 @@ const StickerSheetTemplate: StoryFn<{ textDirection: "ltr" | "rtl" }> = ({ ) return ( - <> + = ({ - + ) } diff --git a/packages/components/src/FilterDateRangePicker/_docs/FilterDateRangePicker.stickersheet.stories.tsx b/packages/components/src/FilterDateRangePicker/_docs/FilterDateRangePicker.stickersheet.stories.tsx index b7f1964732e..b1216108de6 100644 --- a/packages/components/src/FilterDateRangePicker/_docs/FilterDateRangePicker.stickersheet.stories.tsx +++ b/packages/components/src/FilterDateRangePicker/_docs/FilterDateRangePicker.stickersheet.stories.tsx @@ -1,4 +1,5 @@ import React, { useState } from "react" +import { StaticIntlProvider } from "@cultureamp/i18n-react-intl" import { action } from "@storybook/addon-actions" import { Meta, StoryFn } from "@storybook/react" import { within, userEvent } from "@storybook/testing-library" @@ -48,7 +49,7 @@ const StickerSheetTemplate: StoryFn<{ textDirection: "ltr" | "rtl" }> = ({ }) return ( - <> + = ({ - + + + + + + + + + + + ) } diff --git a/packages/components/src/FilterDateRangePicker/subcomponents/DateInputDescription/DateInputDescription.tsx b/packages/components/src/FilterDateRangePicker/subcomponents/DateInputDescription/DateInputDescription.tsx index 80f36ec39cd..148eab5f268 100644 --- a/packages/components/src/FilterDateRangePicker/subcomponents/DateInputDescription/DateInputDescription.tsx +++ b/packages/components/src/FilterDateRangePicker/subcomponents/DateInputDescription/DateInputDescription.tsx @@ -1,4 +1,5 @@ import React from "react" +import { useIntl } from "@cultureamp/i18n-react-intl" import { LabelledMessage } from "~components/LabelledMessage" import { formatDescriptionInputFormat } from "./utils/formatDescriptionInputFormat" import styles from "./DateInputDescription.module.scss" @@ -12,10 +13,17 @@ export const DateInputDescription = ({ description, locale, }: DateInputDescriptionProps): JSX.Element => { + const { formatMessage } = useIntl() const hasCustomDescription = (typeof description === "string" && description !== "") || React.isValidElement(description) + const translatedInputFormatMessage = formatMessage({ + id: "filterDateRangePicker.inputFormat", + defaultMessage: "Input format", + description: "Label for the 'Input format' field", + }) + if (hasCustomDescription) { return ( @@ -23,7 +31,7 @@ export const DateInputDescription = ({ ( ) @@ -34,7 +42,7 @@ export const DateInputDescription = ({ return ( ) diff --git a/packages/components/src/FilterDateRangePicker/subcomponents/FilterDateRangePickerField/FilterDateRangePickerField.tsx b/packages/components/src/FilterDateRangePicker/subcomponents/FilterDateRangePickerField/FilterDateRangePickerField.tsx index 032942579e1..90726c0ecc3 100644 --- a/packages/components/src/FilterDateRangePicker/subcomponents/FilterDateRangePickerField/FilterDateRangePickerField.tsx +++ b/packages/components/src/FilterDateRangePicker/subcomponents/FilterDateRangePickerField/FilterDateRangePickerField.tsx @@ -1,4 +1,5 @@ import React, { useEffect, HTMLAttributes, useState } from "react" +import { useIntl } from "@cultureamp/i18n-react-intl" import classnames from "classnames" import { CalendarRange, @@ -86,9 +87,22 @@ export const FilterDateRangePickerField = ({ classNameOverride, ...restProps }: FilterDateRangePickerFieldProps): JSX.Element => { + const { formatMessage } = useIntl() const locale = getLocale(propsLocale) - const inputStartDateLabel = inputStartDateProps?.labelText || "Date from" - const inputEndDateLabel = inputEndDateProps?.labelText || "Date to" + + const translatedDateFrom = formatMessage({ + id: "filterDateRangePicker.dateFrom", + defaultMessage: "Date from", + description: "Label for the 'Date from' field", + }) + const translatedDateTo = formatMessage({ + id: "filterDateRangePicker.dateTo", + defaultMessage: "Date to", + description: "Label for the 'date to' field", + }) + const inputStartDateLabel = + inputStartDateProps?.labelText || translatedDateFrom + const inputEndDateLabel = inputEndDateProps?.labelText || translatedDateTo const transformDateToInputValue = (date: Date | undefined): string => date ? formatDateAsText(date, disabledDays, locale) : "" diff --git a/setupTests.ts b/setupTests.ts index 634c184bfdc..a4d46703d11 100644 --- a/setupTests.ts +++ b/setupTests.ts @@ -2,3 +2,12 @@ import "@testing-library/jest-dom/extend-expect" /** @ts-ignore */ global.IS_REACT_ACT_ENVIRONMENT = true + +// This avoids errors related to our jest environment not having an Intl +// object present in the app's context +jest.mock("@cultureamp/i18n-react-intl", () => ({ + useIntl: () => ({ + formatMessage: (options: { defaultMessage: string }) => + options.defaultMessage, + }), +})) diff --git a/yarn.lock b/yarn.lock index c5def285c87..d2d69cae362 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1929,10 +1929,10 @@ dependencies: chromatic "^6.14.0" -"@cultureamp/i18n-react-intl@^1.3.0": - version "1.3.0" - resolved "https://npm.pkg.github.com/download/@cultureamp/i18n-react-intl/1.3.0/fe2641d81cbf5591a93da88715a508a66980fb8f#fe2641d81cbf5591a93da88715a508a66980fb8f" - integrity sha512-D4JcwQkOVLEh4c1RKYmsORixKe/cUjhKE3jr6/z12uBqKhWuYxVTpOAndcOZE6MfjP3bFigyyrF3+XQODVRVcw== +"@cultureamp/i18n-react-intl@^1.4.2": + version "1.4.2" + resolved "https://npm.pkg.github.com/download/@cultureamp/i18n-react-intl/1.4.2/960f80dd066ae76ae65ce9ec2f059158953ae62c#960f80dd066ae76ae65ce9ec2f059158953ae62c" + integrity sha512-2jPmlIzkQvc4l4jT+eQFTH3vxIICXJaMbCG7nrLx+Dzixx4XRIrCBoJQl7gdAwAmW0rrPwq0dPhAueJt7e9MtQ== dependencies: "@calm/eslint-plugin-react-intl" "^1.4.1" "@cultureamp/frontend-apis" "*" @@ -1943,7 +1943,7 @@ babel-plugin-formatjs "^10.5.3" date-fns "^2.29.3" eslint-plugin-formatjs "^4.10.3" - fast-glob "^3.2.11" + fast-glob "^3.2.12" form-data "^4.0.0" intl-messageformat "^10.5.0" json-stable-stringify "^1.0.2" @@ -2801,9 +2801,9 @@ integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA== "@lingui/detect-locale@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@lingui/detect-locale/-/detect-locale-4.2.1.tgz#08fe1b731f744c7f4ad26eb0ab4c22fe39ab3a79" - integrity sha512-YdBdWZy3lp4NWOY7TdQHCewKQl6tZAuchfDbw7TI411u+4176mUMxBUNIexDONH1Atzbtqi7R9v/sAQfKOvEKQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/@lingui/detect-locale/-/detect-locale-4.3.0.tgz#bf8009ee31ac6fe667ca2994f51569ce1c4037f6" + integrity sha512-BNTdfabfvETdmhOljJ9jL+wHczrz6KJdEdpm+zqPMbvMA06UqBA7bTk8igW79Z3hN4F+WV7Mro0bDrm8sol0qA== "@manypkg/find-root@^1.1.0": version "1.1.0"