npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-lsm

v1.2.7

Published

A lightweight react hook for managing localization languages. LSM stands for Localization Storage Manager.

Downloads

85

Readme

React Localization Storage Manager / react-lsm

react-jumbo

Package

react - lsm;

A simple library to manage localization storage in React applications. This does not require any additional dependencies. Simpler, smaller, and easier to use than other libraries.

Prerequisites

  • React 18.3.1 or later
  • React-DOM 18.3.1 or later

License

MIT :copyright:

Author

Lewis S. Matos

Getting Started

Installation

To install the package, run the following command:

$ npm install react-lsm

Usage

import React from "react";
import { initLsm, useLsmTranslation } from "react-lsm";

/**
 * This is the LSM Provider component
 * It should be placed at the root of your application
 * first argument is the default language / fallback language
 * second argument is the translations object
 * @comment We recommend to have a separated file for the translations object
 */

const LsmConfiguredProvider = initLsm("en-US", {
	"en-US": {
		greeting: "Hello",
		farewell: "Goodbye",
		navbar: {
			home: "Home",
			about: "About",
			contact: "Contact",
		},
		activeNotifications: "You have {value} notifications",
		info: "information",
		submit: "Submit",
		loading: "Loading",
		orderStatus: "Your order is {status}",
		orderStatuses: {
			pending: "pending",
			processing: "processing",
			shipped: "shipped",
			delivered: "delivered",
		},
		userProfile: "User Profile",
	},
	"es-MX": {
		greeting: "Hola",
		farewell: "Adiós",
		navbar: {
			home: "Inicio",
			about: "Acerca",
			contact: "Contacto",
		},
		activeNotifications: "Tienes {value} notificaciones",
		info: "información",
		submit: "Enviar",
		loading: "Cargando",
		orderStatus: "Su orden está {status}",
		orderStatuses: {
			pending: "pendiente",
			processing: "procesando",
			shipped: "enviada",
			delivered: "entregada",
		},
		userProfile: "Perfil de Usuario",
	},
});

// App.jsx

const App = () => {
	return (
		<LsmConfiguredProvider>
			<Example />
		</LsmConfiguredProvider>;
	);
};

Example.jsx

import { useLsmTranslation } from "react-lsm";
const Example = () => {
	const { translate, language, setLanguage } = useLsmTranslation();
	return (
		<div>
			<h1>{translate("greeting")}</h1>
			<button onClick={() => setLanguage("es-MX")}>Español</button> {/* This will change the language */}
			<button onClick={() => setLanguage("en-US")}>English</button>{" "}
			{/* This will change the language */}
			<p>{language}</p> {/* This will show the current language */}
			<h1>{translate("farewell")}</h1>
		</div>
	);
	// Output: Hello
	// Output: Hola
};

Examples

For convenience, the following examples are provided. We are going to use English and Spanish as the languages for the examples.

Important! :warning:

If you are using the useLsmTranslation hook in a component that implements React.useEffect() or React.useLayoutEffect(), that mutates a React.useState o React.useRef in the component, you will need to wrap the component that uses the state in a React.memo() hook. This is to prevent the component from re-rendering or having layout issues.

Example (Wrong Approach) :warning:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	const fetchUserData = async () => {
		const response = await fetch("https://api.example.com/user");
		const data = await response.json();
		return data;
	};

	const [userData, setUserData] = useState(null);

	useEffect(() => {
		fetchUserData().then((data) => setUserData(data)); 	<- This is the important part
	}, []);

	return (
		<div>
			<h1>{translate("userProfile")}</h1>
			{/* Wrong Approach - Output: User Profile */ }
			<p>{userData.name}</p>
			<p>{userData.email}</p>
		</div>
	);
};

Example (Correct Approach) :white_check_mark:

import React from "react";
import { useLsmTranslation } from "react-lsm";

// This is the correct approach
const UserProfileData = React.memo(({userData}: {userData: any}) => {
	return (
		<div>
			<p>{userData.name}</p>
			<p>{userData.email}</p>
		</div>
	);
});

const Example = () => {
	const { translate } = useLsmTranslation();

	const fetchUserData = async () => {
		const response = await fetch("https://api.example.com/user");
		const data = await response.json();
		return data;
	};

	const [userData, setUserData] = useState(null);

	useEffect(() => {
		fetchUserData().then((data) => setUserData(data)); 	<- This is the important part
	}, []);

	return (
		<div>
			<h1>{translate("userProfile")}</h1>
			{/* Correct Approach - Output: User Profile */ }
			<UserProfileData userData={userData} />
		</div>
	);
};

You should use React.memo to wrap the component that uses the state because that request does not depend on the language change.

Basic Usage

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	return <h1>{translate("greeting")}</h1>;
	// Output: Hello
	// Output: Hola
};

Options Usage

/**
 * The following options are available:
 * - capitalize: Capitalize the first letter of the value
 * - uppercase: Convert the value to uppercase
 * - lowercase: Convert the value to lowercase
 * - replace: Replace the value with the specified values
 * - mutate: Mutate the value based on the specified options
 */
type TranslationOptions = {
	capitalize?: boolean;
	uppercase?: boolean;
	lowercase?: boolean;
	replace?: {
		values: { [key: string]: string | number };
		withTranslation?: boolean;
	};
	mutate?: {
		when: boolean;
		value: string;
		withTranslation?: boolean;
	};
	prefixContent?: string;
	suffixContent?: string;
};

Capitalize :a:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	return <h1>{translate("info", { capitalize: true })}</h1>;
	// Output: Information
	// Output: Información
};

Uppercase :capital_abcd:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	return <h1>{(translate("greeting"), { uppercase: true })}</h1>;
	// Output: HELLO
	// Output: HOLA
};

Lowercase :abcd:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	return <h1>{translate("greeting", { lowercase: true })}</h1>;
	// Output: hello
	// Output: hola
};

Replace :repeat:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	/*
	 * The key is the value to be replaced
	 * The value is the new value
	 */
	return (
		<h1>
			{translate("activeNotifications", {
				replace: { values: { value: 5 } },
			})}
		</h1>
	);
	// Output: You have 5 notifications
	// Output: Tienes 5 notificaciones
};

Replace, Without Translation

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
    const { translate } = useLsmTranslation();
    return (
        <h1>
            {
                translate("orderStatus", {
                    replace: {
                        values: {
                            status: "pending",
                        },
                    },
                }),
            }
        </h1>
    );
    // Output: Your order is pending
    // Output: Su orden está pending  (This is undesirable)
};

Replace, With Translation (Recommended) :white_check_mark:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	return (
		<h1>
			{translate("orderStatus", {
				replace: {
					values: { status: "orderStatuses.shipped" },
					withTranslation: true,
				},
			})}
		</h1>
	);
	// Output: Your order is shipped
	// Output: Su orden está enviada
};

Replace, Explicit translation (Manual translation) :arrows_clockwise:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();
	return (
		<h1>
			{translate("orderStatus", {
				replace: { values: { status: translate("shipped") } },
			})}
		</h1>
	);
	// Output: Your order is shipped
	// Output: Su orden está enviada
};

Mutate: Basic 🤔

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();

	const isLoading = true || false;
	return (
		<h1>
			{translate("submit", {
				mutate: { when: isLoading, value: "loading" },
			})}
		</h1>
	);
	/**
	 * @condition isLoading = false
	 * Output: Submit
	 * Output: Enviar
	 * @condition isLoading = true
	 * Output: loading
	 * Output: loading  (This is undesirable)
	 */
};

Mutate, With Translation (Recommended) :white_check_mark:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();

	const isLoading = true || false;
	return (
		<h1>
			{translate("submit", {
				mutate: { when: isLoading, value: "loading", withTranslation: true },
			})}
		</h1>
	);
	/**
	 * @condition isLoading = false
	 * Output: Submit
	 * Output: Enviar
	 * @condition isLoading = true
	 * Output: Loading
	 * Output: Cargando
	 */
};

Mutate, Explicit translation (Manual translation) 🤔

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();

	const isLoading = true || false;
	return (
		<h1>
			{translate("submit", {
				mutate: {
					when: isLoading,
					value: translate("loading"),
				},
			})}
		</h1>
	);
	/**
	 * @condition isLoading = false
	 * Output: Submit
	 * Output: Enviar
	 * @condition isLoading = true
	 * Output: Loading
	 * Output: Cargando
	 */
};

Start Adornment

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
const { translate } = useLsmTranslation();

const isLoading = true || false;
return (
    <h1>
        {translate("submit", {prefixContent: "🚀 "})})
    </h1>
    // Output: 🚀 Submit
    // Output: 🚀 Enviar
}

End Adornment

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
const { translate } = useLsmTranslation();

const isLoading = true || false;
return (
    <h1>
        {translate("greeting", {suffixContent: " 🇩🇴"})})
    </h1>
    // Output: Hello 🇩🇴
    // Output: Hola 🇩🇴
}

Mutate, With Translation + End Adornment :white_check_mark:

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();

	const isLoading = true || false;
	return (
		<h1>
			{translate("submit", {
				mutate: {
					when: isLoading,
					value: "loading",
					withTranslation: true,
				},
				suffixContent: "...",
			})}
		</h1>
	);
	/**
	 * @condition isLoading = false
	 * Output: Submit
	 * Output: Enviar
	 * @condition isLoading = true
	 * Output: Loading...
	 * Output: Cargando...
	 */
};

Override Language :arrows_counterclockwise:

It does not change the language of the application, it only changes the language of the translation.

import React from "react";
import { useLsmTranslation } from "react-lsm";

const Example = () => {
	const { translate } = useLsmTranslation();

	const isLoading = true || false;
	return (
		<h1>
				{translate("greeting", {overrideLanguage: "es-MX"})})
		</h1>
    // Output: Hola
}

CLI Commands

Generate Enum

$ npm install -g react-lsm
$ lsm-generate-enum <translationsPath> [enumName]
  • <translationsPath>: The path to the translations file (required). It could be any of the translation objects you're using, due to all the keys should be the same in all the translation objects

  • [enumName]: The name of the enum to be generated (optional, default: "LsmTranslationKeys").

Example

{
	"greeting": "Hello",
	"farewell": "Goodbye",
	"navbar": {
		"home": "Home",
		"about": "About",
		"contact": "Contact"
	}
}
$ lsm-generate-enum ./translations.json LsmTranslationKeys
enum LsmTranslationKeys {
	greeting = "Hello",
	farewell = "Goodbye",
	navbarHome = "Home",
	navbarAbout = "About",
	navbarContact = "Contact",
}