Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XS-30 | Multi language support - Xola app content #334

Merged
merged 40 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ac5d031
XS-25 feat(purchase-guests): adds `CircleCheckFilledIcon` and `Warnin…
kirtesh-xola Feb 29, 2024
685dadc
Merge branch 'xola:master' into master
kirtesh-xola Mar 7, 2024
cf3146d
Merge branch 'xola:master' into master
kirtesh-xola Mar 10, 2024
89cd677
Merge branch 'xola:master' into master
kirtesh-xola Mar 20, 2024
d88bf01
Merge branch 'xola:master' into master
kirtesh-xola Mar 21, 2024
63ceaa3
Merge branch 'xola:master' into master
kirtesh-xola Apr 1, 2024
4f95451
feat: adds localization support for DatePicker
kirtesh-xola Apr 3, 2024
1607d45
XS-30: adds translation-blacklist tag for DatePicker and Key
kirtesh-xola Apr 12, 2024
97ec259
Merge branch 'xola:master' into master
kirtesh-xola Jun 17, 2024
6405076
fix: updates sidebar component to support `className` and `align` props
kirtesh-xola Jul 12, 2024
f7e2c5e
Merge branch 'master' of github.com:xola/ui-kit
kirtesh-xola Jul 12, 2024
e0e182f
Merge branch 'master' into XS-30
kirtesh-xola Jul 12, 2024
ebc760d
XS-30 fixed date picker locale issues
manojx031 Jul 31, 2024
1291542
XS-30 fixed locale in month year selector
manojx031 Jul 31, 2024
3ff0046
XS-30 refactor
manojx031 Jul 31, 2024
a34cf45
XS-30 fixed currency
manojx031 Jul 31, 2024
7dfad0c
Merge branch 'master' into XS-30
rushi Aug 2, 2024
fae85b7
XS-30 Added short months
manojx031 Aug 20, 2024
098c620
XS-30 added console.logs
manojx031 Aug 20, 2024
ef5e531
Moved locale files to import block
manojx031 Aug 21, 2024
309155e
XS-30 changed lot messge
manojx031 Aug 21, 2024
426a279
Merge branch 'master' into XS-30
manojx031 Aug 22, 2024
ec7be94
XS-30 fixed es-MX issue
manojx031 Aug 22, 2024
50d8d07
XS-30 Added Support for classnames to sidemenubar text
manojx031 Aug 22, 2024
1b12417
Merge branch 'master' into XS-30
rushi Aug 28, 2024
9ea1467
XS-30 added condition for ignoring locale when its not there
manojx031 Sep 1, 2024
fd7c6c5
XS-30 removed console.logs, lint fix
manojx031 Sep 5, 2024
ab9be5e
Merge branch 'master' into XS-30
manojx031 Sep 5, 2024
d7403d8
XS-30 Added XO config
manojx031 Sep 5, 2024
509998d
XS-30 Dummy commit
manojx031 Sep 6, 2024
4854c98
Fix unicorn/no-console-spaces param
rushi Sep 6, 2024
b688ad7
Merge branch 'master' into XS-30
rushi Sep 6, 2024
49b9d1e
Update eslint.yml to use `ES_LINT_TOKEN`
rushi Sep 6, 2024
e0fe070
Merge branch 'master' into XS-30
rushi Sep 6, 2024
8ba5496
Merge branch 'master' into XS-30
rushi Sep 6, 2024
763eb30
Merge branch 'XS-30' of github.com:kirtesh-xola/ui-kit into XS-30
rushi Sep 6, 2024
b2c31b1
Merge branch 'master' into XS-30
rushi Sep 9, 2024
293c48a
Merge branch 'master' of github.com:xola/ui-kit into XS-30
rushi Sep 9, 2024
ee23bbc
Merge branch 'master' into XS-30
rushi Sep 9, 2024
e4f3eca
npm audit fix by rushi
rushi Sep 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .xo-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"complexity": ["warn", { "max": 25 }]
}
}
50 changes: 26 additions & 24 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 49 additions & 0 deletions src/components/DatePicker/DatePicker.helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as de from "dayjs/locale/de";
import * as en from "dayjs/locale/en";
import * as enGB from "dayjs/locale/en-gb";
import * as es from "dayjs/locale/es";
import * as esMX from "dayjs/locale/es-mx";
import * as fr from "dayjs/locale/fr";
import type { DayPickerProps } from "react-day-picker";

export type LocaleCode = keyof typeof locales;

interface ExtendedDayPickerProps extends DayPickerProps {
monthsShort?: string;
}

export type LocalizationProps = Pick<
ExtendedDayPickerProps,
"locale" | "months" | "monthsShort" | "weekdaysLong" | "weekdaysShort" | "firstDayOfWeek"
>;

const locales = {
en: en,
en_US: en,
en_GB: enGB,

es: es,
es_ES: es,
es_MX: esMX,

fr: fr,
de: de,
};

export const getLocalizationProps = async (localeCode: LocaleCode): Promise<Partial<LocalizationProps>> => {
try {
const locale = await locales[localeCode];

return {
locale: localeCode,
weekdaysLong: locale.weekdays,
weekdaysShort: locale.weekdaysShort,
months: locale.months,
monthsShort: locale.monthsShort,
firstDayOfWeek: locale.weekStart,
};
} catch (error) {
console.error("Error: React Day Picker localization error", error);
throw error;
}
};
21 changes: 17 additions & 4 deletions src/components/DatePicker/DatePicker.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import clsx from "clsx";
import dayjs from "dayjs";
import PropTypes from "prop-types";
import React, { useEffect, useMemo, useState } from "react";
import DayPicker, { DateUtils } from "react-day-picker";
import React, { useContext, useEffect, useMemo, useState } from "react";
import { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";
import "./DatePicker.css";
import { isArray, isFunction } from "lodash";
import { Tooltip } from "../..";
import { isSame, isValidTimeZoneName, now, toDate } from "../../helpers/date";
import { Context } from "../Provider";
import { Day } from "./Day";
import { LocalizedDayPicker } from "./LocalizedDayPicker";
import { MonthYearSelector } from "./MonthYearSelector";
import { NavbarElement } from "./NavbarElement";
import RangeDatePicker from "./RangeDatePicker";
Expand Down Expand Up @@ -38,9 +40,11 @@ export const DatePicker = ({
components = {},
getTooltip,
upcomingDates,
locale,
timezoneName = null, // seller timezone (e.g. "America/Los_Angeles") to return correct today date
...rest
}) => {
const { locale: contextLocale } = useContext(Context);
const initialValue = value ? (variant === variants.single ? value : value.from) : null;
const [currentMonth, setCurrentMonth] = useState(initialValue ?? now(null, timezoneName).toDate());
const [startMonth, setStartMonth] = useState(() => {
Expand Down Expand Up @@ -183,7 +187,14 @@ export const DatePicker = ({
// TODO: Should be outside this component because this returns JSX
const CaptionElement = useMemo(() => {
return shouldShowYearPicker && currentMonth
? ({ date }) => <MonthYearSelector date={date} currentMonth={currentMonth} onChange={handleMonthChange} />
? ({ date }) => (
<MonthYearSelector
date={date}
currentMonth={currentMonth}
locale={locale ?? contextLocale}
onChange={handleMonthChange}
/>
)
: undefined;
// Adding `handleMonthChange` causes a lot of re-renders, and closes drop-down.
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -250,11 +261,12 @@ export const DatePicker = ({
handleEndMonthChange={handleEndMonthChange}
handleTodayClick={handleTodayClick}
selectedDays={selectedDays}
locale={locale ?? contextLocale}
timezoneName={timezoneName}
{...rest}
/>
) : (
<DayPicker
<LocalizedDayPicker
className={clsx(
"ui-date-picker rounded-lg pt-3",
useDateRangeStyle ? "date-range-picker" : null,
Expand Down Expand Up @@ -312,5 +324,6 @@ DatePicker.propTypes = {
shouldShowRelativeRanges: PropTypes.bool,
components: PropTypes.shape({ Footer: PropTypes.oneOfType([PropTypes.node, PropTypes.func]) }),
getTooltip: PropTypes.func,
locale: PropTypes.string,
timezoneName: PropTypes.string,
};
2 changes: 1 addition & 1 deletion src/components/DatePicker/DatePickerPopover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ const DefaultInput = forwardRef(({ className, ...rest }, reference) => {
<CalendarIcon className="z-10 inline-block" />
</div>

<Input className={clsx("cursor-pointer px-8", className)} {...rest} />
<Input className={clsx("no-translate cursor-pointer px-8", className)} {...rest} />

<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
<DownArrowIcon className="inline-block" />
Expand Down
22 changes: 22 additions & 0 deletions src/components/DatePicker/LocalizedDayPicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import clsx from "clsx";
import React, { forwardRef, useContext, useEffect, useState } from "react";
import DayPicker, { DayPickerProps } from "react-day-picker";
import { Context } from "../Provider";
import { getLocalizationProps, LocaleCode, LocalizationProps } from "./DatePicker.helpers";

export const LocalizedDayPicker = forwardRef<any, DayPickerProps>(({ className, ...rest }, ref) => {
const { locale } = useContext(Context);
const [localizationProps, setLocalizationProps] = useState<Partial<LocalizationProps>>({});
console.log("Locale", locale);

useEffect(() => {
setLocalizationProps({});

/** We don't want any localization-related props for "English" */
if (!locale || locale === "en" || locale === "en_US") return;

getLocalizationProps(locale as LocaleCode).then(setLocalizationProps);
}, [locale]);

return <DayPicker ref={ref} className={clsx(className)} {...localizationProps} {...rest} />;
});
9 changes: 6 additions & 3 deletions src/components/DatePicker/MonthYearSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ const getDiffInMonths = (to, from) => {
return 12 * (to.getFullYear() - from.getFullYear()) + (to.getMonth() - from.getMonth());
};

export const MonthYearSelector = ({ date, onChange, currentMonth }) => {
const months = [...Array.from({ length: 12 }).keys()].map((m) => today.month(m).format("MMM"));
export const MonthYearSelector = ({ date, locale, onChange, currentMonth }) => {
const months = [...Array.from({ length: 12 }).keys()].map((m) => today.locale(locale).month(m).format("MMM"));
// 2012 as baseline + 5 years in future
const years = [...Array.from({ length: today.year() - 2012 + 5 + 1 }).keys()].map((y) =>
today.year(2012 + y).format("YYYY"),
today
.locale(locale)
.year(2012 + y)
.format("YYYY"),
);

/**
Expand Down
11 changes: 7 additions & 4 deletions src/components/DatePicker/RangeDatePicker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import clsx from "clsx";
import { isArray, isFunction } from "lodash";
import PropTypes from "prop-types";
import React from "react";
import DayPicker from "react-day-picker";
import { now } from "../../helpers/date";
import { Tooltip } from "../Tooltip";
import { Day } from "./Day";
import { LocalizedDayPicker } from "./LocalizedDayPicker";
import { MonthYearSelector } from "./MonthYearSelector";
import { NavbarElement } from "./NavbarElement";

Expand All @@ -24,6 +24,7 @@ const RangeDatePicker = ({
handleStartMonthChange,
handleEndMonthChange,
handleTodayClick,
locale,
timezoneName,
...rest
}) => {
Expand All @@ -32,7 +33,9 @@ const RangeDatePicker = ({

const createCaptionElement = (currentMonth, handleChange) =>
shouldShowYearPicker && currentMonth
? ({ date }) => <MonthYearSelector date={date} currentMonth={currentMonth} onChange={handleChange} />
? ({ date }) => (
<MonthYearSelector date={date} currentMonth={currentMonth} locale={locale} onChange={handleChange} />
)
: undefined;

const CaptionStartElement = createCaptionElement(startMonth, handleStartMonthChange);
Expand Down Expand Up @@ -90,7 +93,7 @@ const RangeDatePicker = ({

return (
<div className="flex gap-4">
<DayPicker
<LocalizedDayPicker
className={clsx(
"ui-date-picker max-w-[400px] rounded-lg pt-3",
isDateRangeStyle ? "date-range-picker" : null,
Expand All @@ -110,7 +113,7 @@ const RangeDatePicker = ({
onTodayButtonClick={handleTodayClick}
{...rest}
/>
<DayPicker
<LocalizedDayPicker
className={clsx(
"ui-date-picker max-w-[400px] rounded-lg pt-3",
isDateRangeStyle ? "date-range-picker" : null,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Drawer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Dialog, Transition } from "@headlessui/react";
import clsx from "clsx";
import PropTypes from "prop-types";
import React, { forwardRef, Fragment } from "react";
import { CloseIcon } from "../icons";
import { isIosBrowser } from "../helpers/browser";
import { useViewportHeight } from "../hooks/useViewportHeight";
import { CloseIcon } from "../icons";
import { Button } from "./Buttons/Button";

const sizes = {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Key.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const Key = ({ char, className, ...rest }) => {
<div
className={clsx(
"ui-key",
"inline-flex h-5 items-center justify-center rounded bg-gray-lighter py-1 px-2 text-xs font-semibold text-gray",
"no-translate inline-flex h-5 items-center justify-center rounded bg-gray-lighter py-1 px-2 text-xs font-semibold text-gray",
key.length === 1 && "w-5",
className,
)}
Expand Down
8 changes: 6 additions & 2 deletions src/components/Provider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,25 @@ export const Context = createContext({

return fallbackIdCounter++;
},

localize: true,

locale: "en_US",
});

/**
* UI Kit's default provider.
* Must be used from now on in order to generate correct component IDs.
* Also a good place to implement any global state required for the UI Kit in the future.
*/
export const Provider = ({ children }) => {
export const Provider = ({ children, localize = true, locale = "en_US" }) => {
const idCounterRef = useRef(1);

const generateId = useCallback(() => {
return idCounterRef.current++;
}, [idCounterRef]);

const value = useMemo(() => ({ generateId }), [generateId]);
const value = useMemo(() => ({ generateId, localize, locale }), [generateId, localize, locale]);

return <Context.Provider value={value}>{children}</Context.Provider>;
};
8 changes: 6 additions & 2 deletions src/components/Sidebar/Sidebar.Button.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import clsx from "clsx";
import PropTypes from "prop-types";
import React from "react";

export const SidebarButton = ({ icon: Icon, label, ...rest }) => {
export const SidebarButton = ({ icon: Icon, label, className, ...rest }) => {
return (
<button
type="button"
className="ui-sidebar-button flex w-full cursor-pointer items-center rounded py-2 px-4 hover:bg-gray-darker"
className={clsx(
"ui-sidebar-button flex w-full cursor-pointer items-center rounded py-2 px-4 hover:bg-gray-darker",
className,
)}
{...rest}
>
<div className="p-1.5">
Expand Down
Loading
Loading