react-language-selector-lite
Version:
A lightweight language selector for React applications.
322 lines (223 loc) β’ 13.7 kB
Markdown
# react-language-selector-lite
**react-language-selector-lite** is a lightweight and customizable React component for selecting languages, featuring ISO 639 macrolanguage support, and TypeScript compatibility. It offers search functionality, themes (light and dark), and flexible configurations. This package is built using styled-components for seamless integration into any React projectπ.
---
## β¨ Features
- ποΈ Select from a comprehensive list of over 184 languages
- π Search functionality to quickly find languages
- π Supports light and dark themes
- π¨ Fully customizable labels, placeholders & appearance
- π Supports ISO 639 macrolanguages
- π Option to include detailed language information
- π Flexible sorting and filtering of languages
- π¦ Lightweight and easy to integrate
- π± Responsive design
- π― TypeScript support
- π Licensed under MIT
---
### About ISO 639 Macrolanguage
**ISO 639** is a set of international standards that lists short codes for language names. The ISO 639-1 and ISO 639-2 codes are primarily used, and these codes cover the majority of languages in the world. This package uses ISO 639 macrolanguages to ensure comprehensive and accurate representation of languages.
For more information about ISO 639 macrolanguage, visit the [Wikipedia page](https://en.wikipedia.org/wiki/ISO_639_macrolanguage).
---
## π¦ Installation
Install the package via npm or yarn:
```bash
npm install react-language-selector-lite
```
or
```bash
yarn add react-language-selector-lite
```
---
## π Quick Start
### Basic Usage | [Props Table](#props-table)
```jsx
import React from 'react';
import LanguageSelector from 'react-language-selector-lite';
const App = () => {
const handleLanguageSelect = (language) => {
console.log('Selected language:', language);
// Returns the code of the selected language. (e.g., 'es')
// To access language details, pass prop `includeDetails={true}`. Will return:
// {1: 'es', 2: 'spa', 3: 'spa', name: 'Spanish', local: 'EspaΓ±ol', 2T: 'spa', 2B: 'spa'}
};
return (
<div>
<LanguageSelector onSelect={handleLanguageSelect} />
</div>
);
};
export default App;
```
### Preview in Action
<div style="display: flex; align-items: center; gap: 10px;">
<img src="https://raw.githubusercontent.com/JamiuShaibu/react-language-selector-lite/refs/heads/main/src/images/npm-install-react-language-selector-lite-Img.png" alt="react-language-selector-lite-theme-light" width="300" />
<img src="https://raw.githubusercontent.com/JamiuShaibu/react-language-selector-lite/refs/heads/main/src/images/npm-install-react-language-selector-lite.gif" alt="React Language Selector Lite Gif Example" width="300" />
</div>
## π¨ Advanced Usage
### Using custom toggle button
You can use your own custom toggle button for rendering the select container. Just pass your custom button reference to the `buttonRef` prop. This will override the default toggle button. Here's an example: **Easy peasy!**
```jsx
import React, { useRef } from 'react';
import { RiTranslateAi2 } from "react-icons/ri";
import LanguageSelector from 'react-language-selector-lite';
const App = () => {
const customButtonRef = useRef(null);
const handleLanguageSelect = (language) => {
console.log('Selected language:', language);
// {1: 'de', 2: 'deu', 3: 'deu', name: 'German', local: 'Deutsch', 2T: 'deu', 2B: 'ger'}
};
return (
<div className="relative w-full">
<button ref={customButtonRef}>
<RiTranslateAi2 className="size-6" />
</button>
<LanguageSelector
onSelect={handleLanguageSelect}
theme="dark"
includeDetails={true}
buttonRef={customButtonRef}
/>
</div>
);
};
export default App;
```
<img src="https://raw.githubusercontent.com/JamiuShaibu/react-language-selector-lite/refs/heads/main/src/images/npm-install-react-language-selector-lite-darkImg.png" alt="react-language-selector-lite-theme-dark" width="300" />
### Limiting Language Options
You can limit the available options by passing an array of language codes to the `options` prop:
```jsx
<LanguageSelector
onSelect={handleLanguageSelect}
options={['en', 'es', 'fr']}
/>
```
### `useSate` Hook
Using the `useState` hook to select a language:
```jsx
import React, { useState } from 'react';
const [selectedLanguage, setSelectedLanguage] = useState(null);
<LanguageSelector
onSelect={(lang) => setSelectedLanguage(lang)}
/>
```
---
### π Useful Links
- [NPM Official Package Page](https://www.npmjs.com/package/react-language-selector-lite?activeTab=readme) - For more information
- [Issue Tracker](https://github.com/JamiuShaibu/react-language-selector-lite/issues) - Report any issues or feature requests
---
<div id="props-table"></div>
## βοΈ Props Reference
| Prop Name | Type | Default Value | Description |
|-----------------|--------------------------------|----------------------|-------------------------------------------------------------|
| `onSelect` | `(language: any) => void` | **Required** | Callback function triggered when a language is selected. |
| `defaultLang` | `string` / `null` | `"browser"` | Default language code to pre-select. Set preferred language code (e.g., `"en"`) to override the browser's default language. Set to`null` to disable pre-selection. |
| `includeDetails`| `boolean` | `false` | Whether to include detailed language info in `onSelect`. |
| `geoCoverage` | `string`: `"local"` / `"international"` / `"both"` | `"both"` | Display local names or international names of languages. |
| `reverseNames` | `boolean` | `false` | Reverse the order of the language names when `geoCoverage` is set to `both`. |
| `enableSearch` | `boolean` | `true` | Enable search functionality. |
| `options` | `string[]` | `[]` | Array of language codes to limit available options. |
| `sortOptions` | `boolean` | `true` | Whether to sort the list of languages alphabetically. |
| `buttonLabel` | `string`: `"local"` / `"international"` / `"both"` | `"Select language"` | Label for the toggle button, if set to `"local"` / `"international"` / `"both"`, the label will be dynamic based on the selected language, you can also set it to a custom label. When set to an empty string `""` the label will not show up. |
| `placeholder` | `string` | `"Search language..."` | Placeholder text for the search input. |
| `notFoundLabel` | `string` | `"Language not found"` | Label for the not found message. When set to an empty string `""` the message will not show up. |
| `width` | `string` | `"20rem"` | Adjust the width of the selector container. |
| `className` | `string` | `""` | Custom CSS class for styling the selector container. |
| `toggleBtnClass` | `string` | `""` | Custom CSS class for styling the default toggle button. |
| `btnLabelClass` | `string` | `""` | Custom CSS class for styling the label of the toggle button. |
| `searchClass` | `string` | `""` | Custom CSS class for styling the search input container. |
| `optionClass` | `string` | `""` | Custom CSS class for styling each option. |
| `toggleBtnIcon` | `React.ReactNode` / `string` | `"π"` | Customizes the icon displayed on the toggle button. You can use an emoji (e.g., `"π"`), a React component (e.g., `<FaGlobe />`), or a custom SVG. |
| `searchIcon` | `React.ReactNode` / `string` | `"π"` | Customizes the icon displayed inside the search input. You can use an emoji (e.g., `"π¦"`), a React component (e.g., `<FaSearch />`), or a custom SVG. |
| `buttonRef` | `React.RefObject< HTMLButtonElement>` | `null` | A reference to a custom button that toggles the visibility of the language selector container, if not provided, the default toggle button will be rendered. |
| `render` | `string`: `"onClick"` / `"onHover"` | `"onClick"` | To render / display the language selector container **onclick** or **onhover** event of the toggle button. |
| `theme` | `"light"` / `"dark"` | `"light"` | Theme of the component. |
---
## π¨ Styling / Customization
You can add custom styling by utilizing the following props; `className` for the selector container, `toggleBtnClass` for the default toggle button, `searchClass` for the search container, and `optionClass` for each option. Supports both traditional CSS classes and utility classes from UI libraries like Tailwind CSS, Bootstrap, etc. (e.g., `toggleBtnClass="bg-sky-600 rounded-full"`).
---
### Default Toggle Button Label
You can dynamically label the `buttonLabel` based on the selected language by setting the prop to `"local"`, `"international"` or `"both"`. Alternatively, you can provide a custom string for a personalized label. Setting it to an empty string `""` will hide the label.
```jsx
<LanguageSelector
onSelect={handleLanguageSelect}
buttonLabel="local" // "international", "both", a custom string or an empty string ""
/>
```
### Dark Theme
To use the dark theme, simply set the `theme` prop to `"dark"`:
```jsx
<LanguageSelector onSelect={handleLanguageSelect} theme="dark" />
```
### Advanced Theming
You can take the theme to another level beyond the simple default theme, in this case your main focus should be on 3 key classes, `className`, `searchClass`, and `optionClass`. The following example shows how to customize the dark theme using Tailwind CSS:
```jsx
<LanguageSelector
onSelect={handleLanguageSelect}
// Main classes for theming
className="dark:bg-[#0b191c]"
searchClass="dark:bg-gray-800"
optionClass="dark:hover:bg-[#222729] dark:text-gray-400 dark:hover:text-white"
/>
```
### Customizable Icons
You can customize the default toggle button icon and search icon by passing either strings (like emojis) or React nodes (like components from react-icons or custom SVGs).
#### Using Emojis
```jsx
<LanguageSelector
onSelect={handleLanguageSelect}
toggleBtnIcon="π"
searchIcon="π¦"
/>
```
#### Using React Components
```jsx
import { FaGlobe, FaSearch } from "react-icons/fa";
<LanguageSelector
onSelect={handleLanguageSelect}
toggleBtnIcon={<FaGlobe />}
searchIcon={<FaSearch />}
/>
```
#### Using Custom SVGs
```jsx
import GlobeIcon from "./your-path-to-svgs/GlobeIcon.svg";
import SearchIcon from "./your-path-to-svgs/SearchIcon.svg";
<LanguageSelector
onSelect={handleLanguageSelect}
toggleBtnIcon={<img src={GlobeIcon} alt="Globe" />}
searchIcon={<img src={SearchIcon} alt="Search" />}
/>
```
#### Fully Customized Preview
<img src="https://raw.githubusercontent.com/JamiuShaibu/react-language-selector-lite/refs/heads/main/src/images/npm-install-react-language-selector-lite-theme-dark-light.png" alt="react-language-selector-lite-theme-dark-light" width="auto" />
---
## π License
This project is licensed under the [MIT License](LICENSE) by [Jamiu Shaibu](https://github.com/JamiuShaibu)
---
## π€ Contributing
Contributions are welcome! Please fork the repository and submit a pull request for review.
### Steps to Contribute
1. Fork the repository: [GitHub repository](https://github.com/JamiuShaibu/react-language-selector-lite)
2. Create a new branch: `git checkout -b feature-branch-name`.
3. Make your changes and commit: `git commit -m 'Add some feature'`.
4. Push to the branch: `git push origin feature-branch-name`.
5. Open a pull request.
---
### π¬ Support
If you encounter any issues or have questions:
- Check the [existing issues](https://github.com/JamiuShaibu/react-language-selector-lite/issues)
- Create a [new issue](https://github.com/JamiuShaibu/react-language-selector-lite/issues/new)
---
### Acknowledgments
- [langs](https://www.npmjs.com/package/langs) - For language data.
---
### β Support the Developer
If you find this package useful:
1. StarβοΈ the repository on [GitHub](https://github.com/JamiuShaibu/react-language-selector-lite) and share it with other developers!
2. Consider buying me a coffee to support development!
<a href="https://www.buymeacoffee.com/jamiushaib5" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>
---
### π¨βπ» Author
- **Jamiu Shaibu** - [GitHub](https://github.com/JamiuShaibu) | [LinkedIn](https://www.linkedin.com/in/jamiu-shaibu-9037ba195/)
---
Happy coding! π