feature/storybook #2

Merged
behnam merged 7 commits from feature/storybook into develop 2024-11-26 15:42:17 +00:00
6 changed files with 63 additions and 31 deletions
Showing only changes of commit d88c2ede9d - Show all commits

View File

@ -1,13 +1,13 @@
import type { Preview } from "@storybook/react"; import React, { useRef } from "react";
import React from "react";
import { themes } from '@storybook/theming'; import { themes } from '@storybook/theming';
import { ThemeProvider } from "../src/app/[lang]/dashboard/components/client/theme-provider/theme-provider"; import { ThemeProvider } from "../src/app/[lang]/dashboard/components/client/theme-provider/theme-provider";
import { DARK_MODE_EVENT_NAME, UPDATE_DARK_MODE_EVENT_NAME } from 'storybook-dark-mode'; import { DARK_MODE_EVENT_NAME, UPDATE_DARK_MODE_EVENT_NAME } from 'storybook-dark-mode';
import { initI18next, LANGS } from "../src/bootstrap/i18n/i18n"
import { addons } from '@storybook/preview-api'; import { addons } from '@storybook/preview-api';
import "../src/app/globals.css" import { i18n } from "i18next";
import { I18nextProvider } from "react-i18next";
const channel = addons.getChannel(); const channel = addons.getChannel();
import "../src/app/globals.css"
/** /**
* *
* This function will expand the object with nested properties * This function will expand the object with nested properties
@ -46,8 +46,9 @@ const preview = {
decorators: [ decorators: [
(Story, data) => { (Story, data) => {
const [isDark, setDark] = React.useState(true); const [isDark, setDark] = React.useState(true);
const [i18n, setI18n] = React.useState<i18n>()
const parsedProps = {} as Record<string, unknown>; const parsedProps = {} as Record<string, unknown>;
const { locale } = data.globals
const props = data.allArgs; const props = data.allArgs;
Object.entries(props).forEach((prop) => { Object.entries(props).forEach((prop) => {
const [key, value] = prop; const [key, value] = prop;
@ -66,6 +67,15 @@ const preview = {
return () => channel.removeListener(DARK_MODE_EVENT_NAME, setDark); return () => channel.removeListener(DARK_MODE_EVENT_NAME, setDark);
}, [channel, setDark]); }, [channel, setDark]);
React.useEffect(() => {
(async () => {
setI18n((await initI18next({ lng: locale })).i18n);
})()
}, [])
React.useEffect(() => {
i18n?.changeLanguage(locale);
}, [locale]);
return ( return (
<ThemeProvider <ThemeProvider
@ -73,8 +83,16 @@ const preview = {
forcedTheme={isDark ? "dark" : "light"} forcedTheme={isDark ? "dark" : "light"}
enableSystem enableSystem
disableTransitionOnChange disableTransitionOnChange
>
{
i18n && (
<I18nextProvider
i18n={i18n}
> >
<Story parsedProps={parsedProps} /> <Story parsedProps={parsedProps} />
</I18nextProvider>
)
}
</ThemeProvider> </ThemeProvider>
); );
}, },
@ -97,6 +115,20 @@ const preview = {
}, },
}, },
}, },
globalTypes: {
locale: {
name: 'Locale',
description: 'Internationalization locale',
toolbar: {
icon: 'globe',
items: [
{ value: LANGS.EN, title: 'English' },
{ value: LANGS.RU, title: 'Russian' },
],
showName: true,
},
},
}
}; };
export default preview; export default preview;

View File

@ -6,11 +6,11 @@ import CardWrapper from "@/app/[lang]/dashboard/components/server/cards/cards";
import LatestInvoices from "@/app/[lang]/dashboard/components/server/latest-invoices/latest-invoices"; import LatestInvoices from "@/app/[lang]/dashboard/components/server/latest-invoices/latest-invoices";
import RevenueChart from "@/app/[lang]/dashboard/components/server/revenue-chart/revenue-chart"; import RevenueChart from "@/app/[lang]/dashboard/components/server/revenue-chart/revenue-chart";
import { Suspense } from "react"; import { Suspense } from "react";
import { getServerTranslation } from "@/bootstrap/i18n/i18n"; import { getServerTranslation, LANGS } from "@/bootstrap/i18n/i18n";
import langKey from "@/bootstrap/i18n/dictionaries/lang-key"; import langKey from "@/bootstrap/i18n/dictionaries/lang-key";
export default async function Dashboard(props: { export default async function Dashboard(props: {
params: Promise<{ lang: string }>; params: Promise<{ lang: LANGS }>;
}) { }) {
const { params } = props; const { params } = props;
const { lang } = await params; const { lang } = await params;

View File

@ -1,5 +1,5 @@
import { ThemeProvider } from "@/app/[lang]/dashboard/components/client/theme-provider/theme-provider"; import { ThemeProvider } from "@/app/[lang]/dashboard/components/client/theme-provider/theme-provider";
import { initI18next } from "@/bootstrap/i18n/i18n"; import { initI18next, LANGS } from "@/bootstrap/i18n/i18n";
import TranslationsProvider from "@/bootstrap/i18n/i18n-provider"; import TranslationsProvider from "@/bootstrap/i18n/i18n-provider";
import localFont from "next/font/local"; import localFont from "next/font/local";
import { PropsWithChildren } from "react"; import { PropsWithChildren } from "react";
@ -16,7 +16,7 @@ const geistMono = localFont({
}); });
export default async function layout( export default async function layout(
props: PropsWithChildren & { params: Promise<{ lang: string }> }, props: PropsWithChildren & { params: Promise<{ lang: LANGS }> },
) { ) {
const { params, children } = props; const { params, children } = props;
const { lang } = await params; const { lang } = await params;

View File

@ -58,7 +58,6 @@ export interface ButtonProps
const ButtonUi = React.forwardRef<HTMLButtonElement, ButtonProps>( const ButtonUi = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => { ({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"; const Comp = asChild ? Slot : "button";
console.log('is disabled', props);
return ( return (
<Comp <Comp
className={cn(buttonVariants({ variant, size, className }))} className={cn(buttonVariants({ variant, size, className }))}

View File

@ -1,18 +1,17 @@
"use client"; "use client";
import { I18nextProvider } from "react-i18next"; import { I18nextProvider } from "react-i18next";
import { initI18next } from "@/bootstrap/i18n/i18n"; import { i18nInstance, initI18next, LANGS } from "@/bootstrap/i18n/i18n";
import { createInstance, Resource } from "i18next"; import { Resource } from "i18next";
import { PropsWithChildren } from "react"; import { PropsWithChildren } from "react";
export default function TranslationsProvider({ export default function TranslationsProvider({
children, children,
lng, lng,
resources, resources,
}: PropsWithChildren & { lng: string; resources: Resource }) { }: PropsWithChildren & { lng: LANGS; resources: Resource }) {
const i18n = createInstance(); if (!resources) return children;
initI18next({ lng, resources });
initI18next({ lng, i18n, resources }); return <I18nextProvider i18n={i18nInstance}>{children}</I18nextProvider>;
return <I18nextProvider i18n={i18n}>{children}</I18nextProvider>;
} }

View File

@ -1,23 +1,26 @@
import { getOptions, languages } from "@/bootstrap/i18n/settings"; import { getOptions, languages } from "@/bootstrap/i18n/settings";
import { createInstance, i18n, Resource } from "i18next"; import { createInstance, Resource } from "i18next";
import resourcesToBackend from "i18next-resources-to-backend"; import resourcesToBackend from "i18next-resources-to-backend";
import { initReactI18next } from "react-i18next/initReactI18next"; import { initReactI18next } from "react-i18next/initReactI18next";
const initI18nextInstance = createInstance(); export const i18nInstance = createInstance();
export enum LANGS {
EN = "en",
RU = "ru",
}
export const initI18next = async (params: { export const initI18next = async (params: {
lng: string; lng: LANGS;
i18n?: i18n;
resources?: Resource; resources?: Resource;
ns?: string; ns?: string;
}) => { }) => {
const { lng, i18n, ns, resources } = params; const { lng, ns, resources } = params;
const i18nInstance = i18n || initI18nextInstance;
await i18nInstance await i18nInstance
.use(initReactI18next) .use(initReactI18next)
.use( .use(
resourcesToBackend( resourcesToBackend(
(language: string) => import(`./dictionaries/${language}.ts`), (language: LANGS) => import(`./dictionaries/${language}.ts`),
), ),
) )
.init({ .init({
@ -36,18 +39,17 @@ export const initI18next = async (params: {
}; };
export async function getServerTranslation( export async function getServerTranslation(
lng: string, lng: LANGS,
ns?: string, ns?: string,
options: { keyPrefix?: string } = {}, options: { keyPrefix?: string } = {},
) { ) {
const i18nextInstance = (await initI18next({ lng, ns })).i18n; await initI18next({ lng });
return { return {
t: i18nextInstance.getFixedT( t: i18nInstance.getFixedT(
lng, lng,
Array.isArray(ns) ? ns[0] : ns, Array.isArray(ns) ? ns[0] : ns,
options?.keyPrefix, options?.keyPrefix,
), ),
i18n: i18nextInstance, i18n: i18nInstance,
}; };
} }