Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 0 additions & 9 deletions apps/website/globals.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
declare module "*.md";
declare module "*.woff2" {
const content: string;
export default content;
}

declare module "*.woff" {
const content: string;
export default content;
}
20 changes: 18 additions & 2 deletions apps/website/screens/guidelines/localization/LocalizationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import PageHeading from "@/common/PageHeading";
import QuickNavContainer from "@/common/QuickNavContainer";
import { DxcHeading, DxcFlex, DxcTable, DxcParagraph, DxcLink } from "@dxc-technology/halstack-react";
import Link from "next/link";
import translations from "./examples/translations";
import translationsExample from "./examples/translations";
import localizationExample from "./examples/localization";

const sections = [
{
Expand All @@ -30,7 +31,7 @@ const sections = [
},
{
title: "Translation example",
content: <Example example={translations} defaultIsVisible />,
content: <Example example={translationsExample} defaultIsVisible />,
},
{
title: "Default labels",
Expand Down Expand Up @@ -760,6 +761,21 @@ const sections = [
},
],
},
{
title: "Localization",
content: (
<>
<DxcParagraph>
It is also possible to localize some components making use of <Code>localeTag</Code> to define the language
and region of the component.
</DxcParagraph>
</>
),
},
{
title: "Localization example",
content: <Example example={localizationExample} defaultIsVisible />,
},
];

const LocalizationPage = () => (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { DxcDateInput, HalstackProvider, DxcInset } from "@dxc-technology/halstack-react";

const code = `() => {

return (
<HalstackProvider localeTag="de-DE">
<DxcInset space="var(--spacing-padding-xl)">
<DxcDateInput
label="Date"
placeholder="Select a date"
optional
/>
</DxcInset>
</HalstackProvider>
);
}`;

const scope = {
DxcDateInput,
HalstackProvider,
DxcInset,
};

export default { code, scope };
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
import DocFooter from "@/common/DocFooter";
import Example from "@/common/example/Example";
import QuickNavContainer from "@/common/QuickNavContainer";
import customTranslations from "./examples/customTranslations";
import customThemes from "./examples/customThemes";
import {
DxcFlex,
DxcParagraph,
DxcTable,
DxcLink,
DxcAlert,
DxcTypography,
DxcBleed,
DxcHeading,
} from "@dxc-technology/halstack-react";
import { DxcFlex, DxcParagraph, DxcTable, DxcLink, DxcAlert, DxcHeading } from "@dxc-technology/halstack-react";
import Link from "next/link";
import PageHeading from "@/common/PageHeading";
import Code, { ExtendedTableCode, TableCode } from "@/common/Code";
import StatusBadge from "@/common/StatusBadge";
import customLocalization from "./examples/customLocalization";

const opinionatedThemeTypeString = `{
tokens?: Record<string, string | number>;
Expand Down Expand Up @@ -50,6 +41,17 @@ const sections = [
<td>Object with a given structure, specified below, for defining translations.</td>
<td>-</td>
</tr>
<tr>
<td>localeTag</td>
<td>
<TableCode>string</TableCode>
</td>
<td>
String representing the locale, such as "en-US" for English (United States) or "es-ES" for Spanish
(Spain).
</td>
<td>-</td>
</tr>
<tr>
<td>
<DxcFlex direction="column" gap="var(--spacing-gap-xs)" alignItems="baseline">
Expand All @@ -72,7 +74,12 @@ const sections = [
content: (
<>
<DxcParagraph>
Halstack Provider can be used to translate all the labels that cannot be changed by the component properties.
Using Halstack Provider localeTag property, we can set the locale for the components. The localeTag property
accepts a string that represents the locale, such as "en-US" for English (United States) or "es-ES" for
Spanish (Spain). By setting this property, some components like the DateInput component will automatically
format the date according to the specified locale. For example, if we set localeTag="de-DE", the DateInput
component will display the date in the German format (DD.MM.YYYY). Halstack Provider can also be used to
translate all the labels that cannot be changed by the component properties.
</DxcParagraph>
<DxcAlert
title="Localization"
Expand All @@ -91,17 +98,20 @@ const sections = [
closable={false}
/>
<DxcParagraph>
Let's imagine that we want to translate the '(Optional)' label of a <Code>DxcTextInput</Code>, as well as the
error messages of our <Code>DxcFileInput</Code> component. To do so, we need to create an object with the
translations. In this object, you will have as many objects as components you want to translate with the
respective translation for their labels.
Let's imagine that we want to translate the '(Optional)' label of a <Code>DxcTextInput</Code>. To do so, we
need to create an object with the translations. In this object, you will have as many objects as components
you want to translate with the respective translation for their labels.
</DxcParagraph>
<DxcParagraph>
To change the format in a <Code>DxcDateInput</Code> component, we can use the <Code>localeTag</Code> property
of the Halstack Provider or the <Code>format</Code> prop. The <Code>localeTag</Code> property accepts a string
that represents the locale, such as "en-US" for English (United States) or "es-ES" for Spanish (Spain). By
setting this property, the DateInput component will automatically format the date according to the specified
locale and also change the first day of the week. For example, if we set <Code>localeTag="fr-CH"</Code>, the{" "}
<Code>DxcDateInput</Code> component will display the date in the French but using Swiss format (DD.MM.YYYY)
and set Monday as the first day of the week.
</DxcParagraph>
<Example example={customTranslations} defaultIsVisible />
<DxcBleed top="var(--spacing-gap-xl)">
<DxcTypography fontSize="0.875rem">
*(to see the translated error message you should try to add any file on the <Code>DxcFileInput</Code>).
</DxcTypography>
</DxcBleed>
<Example example={customLocalization} defaultIsVisible />
</>
),
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { DxcTextInput, HalstackProvider, DxcDateInput, DxcInset, DxcFlex } from "@dxc-technology/halstack-react";

const code = `() => {
const labels = {
formFields: {
optionalLabel: "(Optionnel)",
},
};

return (
<HalstackProvider labels={labels} localeTag="fr-CH">
<DxcInset space="var(--spacing-padding-xl)">
<DxcFlex gap="var(--spacing-gap-xl)" direction="column">
<DxcTextInput
label="Input text"
defaultValue="Example text"
clearable
optional
/>
<DxcDateInput
label="Date"
placeholder="Select a date"
optional
/>
</DxcFlex>
</DxcInset>
</HalstackProvider>
);
}`;

const scope = {
DxcTextInput,
DxcDateInput,
HalstackProvider,
DxcInset,
DxcFlex,
};

export default { code, scope };

This file was deleted.

2 changes: 1 addition & 1 deletion apps/website/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"@/common/*": ["screens/common/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "next.config.ts"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "next.config.ts", "../../packages/lib/src/**/*.d.ts"],
"exclude": ["node_modules", "out", ".turbo", ".next"]
}
26 changes: 21 additions & 5 deletions packages/lib/src/HalstackContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { createContext, ReactNode, useMemo } from "react";
import styled from "@emotion/styled";
import { css } from "@emotion/react";
import { coreTokens, aliasTokens } from "./styles/tokens";
import { defaultThemedLogos, TranslatedLabels, defaultTranslatedComponentLabels } from "./common/variables";
import {
defaultThemedLogos,
TranslatedLabels,
defaultTranslatedComponentLabels,
LocalizedContext,
} from "./common/variables";

/**
* This type is used to allow labels objects to be passed to the HalstackProvider.
Expand All @@ -11,7 +16,7 @@ import { defaultThemedLogos, TranslatedLabels, defaultTranslatedComponentLabels
export type DeepPartial<T> = {
[P in keyof T]?: Partial<T[P]>;
};
const HalstackLanguageContext = createContext<TranslatedLabels>(defaultTranslatedComponentLabels);
const HalstackLanguageContext = createContext<LocalizedContext>({ labels: defaultTranslatedComponentLabels });
const HalstackLogosContext = createContext<Record<string, string | undefined>>(defaultThemedLogos);

const parseLabels = (labels: DeepPartial<TranslatedLabels>): TranslatedLabels => {
Expand All @@ -30,12 +35,14 @@ const parseLabels = (labels: DeepPartial<TranslatedLabels>): TranslatedLabels =>
});
return parsedLabels;
};

type ThemeType = { tokens?: Record<string, string | number>; logos?: Record<string, string | undefined> };

type HalstackProviderPropsType = {
labels?: DeepPartial<TranslatedLabels>;
children: ReactNode;
opinionatedTheme?: ThemeType;
localeTag?: string;
};

const HalstackThemed = styled.div<{ coreTheme?: ThemeType["tokens"] }>`
Expand Down Expand Up @@ -69,7 +76,12 @@ const createCoreTheme = (opinionatedTheme: ThemeType["tokens"] | undefined = {})
return newTheme;
};

const HalstackProvider = ({ labels, children, opinionatedTheme }: HalstackProviderPropsType): JSX.Element => {
const HalstackProvider = ({
labels,
children,
opinionatedTheme,
localeTag,
}: HalstackProviderPropsType): JSX.Element => {
const parsedLabels = useMemo(() => (labels ? parseLabels(labels) : null), [labels]);
const parsedCoreTheme = useMemo(() => {
const theme = createCoreTheme(opinionatedTheme?.tokens);
Expand All @@ -79,8 +91,12 @@ const HalstackProvider = ({ labels, children, opinionatedTheme }: HalstackProvid
return (
<HalstackThemed coreTheme={parsedCoreTheme}>
<HalstackLogosContext.Provider value={opinionatedTheme?.logos ?? defaultThemedLogos}>
{parsedLabels ? (
<HalstackLanguageContext.Provider value={parsedLabels}>{children}</HalstackLanguageContext.Provider>
{parsedLabels || localeTag ? (
<HalstackLanguageContext.Provider
value={{ labels: parsedLabels ?? defaultTranslatedComponentLabels, locale: localeTag }}
>
{children}
</HalstackLanguageContext.Provider>
) : (
children
)}
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/src/alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ const DxcAlert = ({
const [currentIndex, setCurrentIndex] = useState(0);

const id = useId();
const translatedLabels = useContext(HalstackLanguageContext);
const translatedLabels = useContext(HalstackLanguageContext).labels;

const handleNextOnClick = () => {
setCurrentIndex((prevIndex) => (prevIndex < messages.length ? prevIndex + 1 : prevIndex));
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/src/card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const DxcCard = forwardRef(
const [internalSelected, setInternalSelected] = useState(
selected !== undefined ? selected : defaultSelected || false
);
const translatedLabels = useContext(HalstackLanguageContext);
const translatedLabels = useContext(HalstackLanguageContext).labels;

useEffect(() => {
if (selected !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/src/checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const DxcCheckbox = forwardRef<RefType, CheckboxPropsType>(
const labelId = `label-checkbox-${useId()}`;
const [innerChecked, setInnerChecked] = useState(defaultChecked);
const checkboxRef = useRef<HTMLSpanElement | null>(null);
const translatedLabels = useContext(HalstackLanguageContext);
const translatedLabels = useContext(HalstackLanguageContext).labels;
const { partial } = useContext(CheckboxContext) ?? {};

const handleOnChange = () => {
Expand Down
5 changes: 5 additions & 0 deletions packages/lib/src/common/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,11 @@ export const defaultTranslatedComponentLabels = {

export type TranslatedLabels = typeof defaultTranslatedComponentLabels;

export type LocalizedContext = {
labels: TranslatedLabels;
locale?: string;
};

export const defaultThemedLogos = {
mainLogo: undefined,
footerLogo: undefined,
Expand Down
Loading
Loading