A React-based design system built for consistency and flexibility, utilizing Tailwind CSS and utility-first styling.
Unit is a flexible and scalable design system developed with React and Tailwind CSS. It provides a set of reusable UI components, hooks, and utility classes to help build responsive, consistent, and maintainable web applications. This project follows utility-first principles to offer maximum customization with minimal configuration.
- βοΈ React Components: Custom components designed for reusability and easy integration.
- π¨ Tailwind CSS Integration: Built-in support for Tailwind CSS, allowing quick styling with utility classes.
- π TypeScript: Full TypeScript support for better type safety and developer experience.
- βοΈ Utility-first Styling: Offers a range of configurable design tokens for spacing, typography, colors, and more.
- π Translation Hook: Provides an easy-to-use translation hook (
useTranslation
) for multilingual support, with support for dynamic language loading.
Install Unit via your preferred package manager:
# npm
npm install @ktranish/unit
# yarn
yarn add @ktranish/unit
# pnpm
pnpm add @ktranish/unit
- Import the desired component(s) into your React project.
- Use the
cn
utility to merge class names where needed (useful for custom styling with Tailwind classes).
Example usage:
import React from "react";
import { Button } from "@ktranish/unit";
import { cn } from "@ktranish/unit/utils/cn";
function App() {
return (
<div className={cn("p-4")}>
<Button label="Click Me" />
</div>
);
}
Unit includes a custom Tailwind configuration file (tailwind.config.js
) that consumers can extend in their own projects. This allows your projectβs Tailwind setup to seamlessly inherit Unitβs custom themes, spacing, colors, and other configurations.
To use Unitβs configuration, import it in your own tailwind.config.js
file and extend it as shown below.
// tailwind.config.js in the consumer project
const designSystemConfig = require("@ktranish/unit/tailwind.config");
module.exports = {
content: [
"./src/**/*.{js,ts,jsx,tsx}",
"./node_modules/@ktranish/unit/dist/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
...designSystemConfig.theme,
},
},
plugins: [...designSystemConfig.plugins],
};
Unit includes a getServerSideTranslations
utility function and TranslationProvider
to support multilingual content. This feature works seamlessly with or without namespaces.
For projects that use namespaces (e.g., modular translations for common
, home
, etc.), you can specify the namespaces to load:
locales/
βββ en/
β βββ common.json
β βββ home.json
βββ es/
β βββ common.json
β βββ home.json
import { getServerSideTranslations } from "@ktranish/unit/utils/getServerSideTranslations";
export async function getServerSideProps(context) {
const { locale = "en" } = context;
// Load specific namespaces for the locale
const translations = await getServerSideTranslations(locale, [
"common",
"home",
]);
return {
props: {
locale,
translations,
},
};
}
export default function HomePage({ translations }: { translations: any }) {
return (
<TranslationProvider translations={translations}>
<Main />
</TranslationProvider>
);
}
For projects that donβt use namespaces, the utility will automatically load all translation files in the specified locale directory.
locales/
βββ en.json
βββ es.json
import { getServerSideTranslations } from "@ktranish/unit/utils/getServerSideTranslations";
export async function getServerSideProps(context) {
const { locale = "en" } = context;
// Load all translations for the locale
const translations = await getServerSideTranslations(locale);
return {
props: {
locale,
translations,
},
};
}
export default function HomePage({ translations }: { translations: any }) {
return (
<TranslationProvider translations={translations}>
<Main />
</TranslationProvider>
);
}
If your translations are stored in a non-standard directory, you can use the basePath
parameter to specify the root directory of your translations.
translations/
βββ en/
β βββ common.json
β βββ home.json
βββ es/
β βββ common.json
β βββ home.json
import { getServerSideTranslations } from "@ktranish/unit/utils/getServerSideTranslations";
import path from "path";
export async function getServerSideProps(context) {
const { locale = "en" } = context;
// Specify a custom basePath for translations
const translations = await getServerSideTranslations(
locale,
["common", "home"],
path.resolve(process.cwd(), "translations"),
);
return {
props: {
locale,
translations,
},
};
}
export default function HomePage({ translations }: { translations: any }) {
return (
<TranslationProvider translations={translations}>
<Main />
</TranslationProvider>
);
}
For larger applications, translations can be loaded dynamically based on the selected language. Consumers can store each language in a separate JSON file and load it as needed.
Organize translations in locales
directory as follows:
src/
βββ locales/
β βββ en.json
β βββ es.json
β βββ fr.json
βββ App.tsx
Each JSON file contains translations for one language. For example, en.json
:
{
"welcome": "Welcome",
"goodbye": "Goodbye"
}
Then, in App.tsx
, dynamically load translations based on the selected language:
import React, { useState, useEffect } from "react";
import { Button } from "@ktranish/unit";
import {
TranslationProvider,
useTranslation,
} from "@ktranish/unit/hooks/useTranslation";
const App = () => {
const [language, setLanguage] = useState("en");
const [translations, setTranslations] = useState({});
const loadTranslations = async (lang: string) => {
const translations = await import(`./locales/${lang}.json`);
setTranslations(translations);
};
useEffect(() => {
loadTranslations(language);
}, [language]);
const switchLanguage = () => {
setLanguage((prev) => (prev === "en" ? "es" : "en"));
};
return (
<TranslationProvider translations={translations}>
<Welcome />
<button onClick={switchLanguage}>
Switch to {language === "en" ? "Spanish" : "English"}
</button>
</TranslationProvider>
);
};
const Welcome = () => {
const { t } = useTranslation();
return (
<div>
<h1>{t("welcome")}</h1>
<Button label={t("goodbye", "Click here")} />
</div>
);
};
This setup allows you to load only the necessary translations, keeping the app lightweight and efficient.
To build the project, ensure you have all dependencies installed. Then run:
pnpm build
This project uses ESLint for linting and Prettier for code formatting.
- Lint: Run
pnpm run lint
to check for linting errors. - Format: Run
pnpm run prettier:format
to auto-format your code.
List of core components available in Unit (update with actual components as theyβre added):
Each component supports Tailwind utility classes, making it easy to customize and extend.
Unit includes several utility hooks to facilitate common patterns and functionality:
Each hook provides functionality designed to integrate smoothly with Unitβs components, enhancing the developer experience and making complex functionality easy to manage.
Contributions are welcome! To contribute:
- Fork the repository.
- Create a feature branch (
git checkout -b feature-name
). - Commit your changes (
git commit -m 'Add new feature'
). - Push to the branch (
git push origin feature-name
). - Open a Pull Request.
This project is licensed under the MIT License.