omniconn-design-system
v1.13.1
Published
React + Tailwind design system: 24 accessible, RTL-aware components, design tokens and a Tailwind preset.
Maintainers
Readme
omniconn-design-system
A React + Tailwind design system: 24 components, a token palette, and a Tailwind
preset. Everything is built from scratch against the tokens — no Radix, no
headless-UI wrapper, no class-variance-authority. The only runtime peers are
React and Phosphor Icons.
Every component is RTL-aware (logical properties throughout, not left/right),
and every string it renders can be translated.
Install
npm install omniconn-design-systemPeer dependencies you also need:
npm install react react-dom @phosphor-icons/react tailwindcssSetup
Three steps: the preset, the stylesheet, and the content glob.
1. Extend your Tailwind config with the preset.
// tailwind.config.js
import preset from "omniconn-design-system/tailwind-preset";
export default {
presets: [preset],
content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"],
};The preset brings the color ramps, the type scale, the radius scale, focus-ring
shadows, brand gradients, screen widths, and the tailwindcss-rtl and
tailwind-scrollbar-hide plugins.
It also appends the package's own dist to content, so the classes the
components emit survive purging. If your install layout is unusual (pnpm without
hoisting, a monorepo with a shared root node_modules), add the real path
yourself:
content: [
"./src/**/*.{js,jsx,ts,tsx}",
"./node_modules/omniconn-design-system/dist/**/*.js",
],2. Import the stylesheet, above your Tailwind directives:
/* src/index.css */
@import "omniconn-design-system/styles.css";
@tailwind base;
@tailwind components;
@tailwind utilities;This carries the :root semantic role variables (--color-primary,
--color-surface, --color-content, …) that the preset's color roles point at,
plus the transition classes Modal and Drawer animate with. Without it,
overlays still work but pop in with no animation.
3. Use the components.
import { Button, Card, Table } from "omniconn-design-system";
import { Gauge } from "@phosphor-icons/react";
export default function Devices({ rows }) {
return (
<Card>
<Card.Header icon={Gauge} title="Devices" />
<Card.Body>
<Table
columns={[
{ key: "name", header: "Name", sortable: true },
{ key: "status", header: "Status", filter: "select" },
]}
data={rows}
rowKey="id"
searchable
/>
</Card.Body>
</Card>
);
}What's in it
| Group | Components |
| --- | --- |
| Actions | Button, Menu, ActionMenu |
| Layout / chrome | Card, PageHeader, Modal, Drawer, Tabs |
| Form controls | Field, Input, Textarea, Select, Checkbox, RadioGroup, Radio, Switch, SegmentedToggle, DatePicker, SearchBar |
| Data display | Table, Pagination, Badge, Avatar |
Plus cn, the validators / useField form-validation kit, the PALETTE and
tone resolvers, the useBreakpointTier responsive primitives, and the
locale-formatting helpers.
Full prop reference: docs/DESIGN-SYSTEM.md.
Theming
The semantic roles are CSS variables, so rebranding is a stylesheet override — no Tailwind rebuild, no component changes:
:root {
--color-primary: #0f766e;
--color-primary-hover: #0d5f58;
--color-surface: #ffffff;
--color-content: #0d1013;
}The raw ramps (primary-50 … primary-950) live in JS, in src/lib/tone.js,
because some components resolve a color at runtime and set it as an inline
style — Tailwind can't generate a class from a runtime string. Both the preset
and the components read that same module, so they can't drift.
Translations
Components ship with English copy built in and work with no configuration. To supply your own, register a translator once at startup:
import { setTranslator, setLanguage } from "omniconn-design-system";
import i18n from "./i18n";
setTranslator((key, vars) => i18n.t(key, vars), { language: i18n.language });
i18n.on("languageChanged", setLanguage);Or wrap your tree, if you'd rather keep it declarative:
import { useTranslation } from "react-i18next";
import { DesignSystemProvider } from "omniconn-design-system";
const { t, i18n } = useTranslation();
<DesignSystemProvider t={t} language={i18n.language}>
<App />
</DesignSystemProvider>;Keys are namespaced under common.* (common.table.noData,
common.pagination.showing, …) and use i18next-style {{name}} placeholders,
so an existing i18next bundle works as-is. The full key list is in
src/i18n/strings.en.js; an Arabic bundle ships
alongside it and can be passed as resources or merged into your own.
language drives more than copy — it selects the numeral system, so Arabic
renders Arabic-Indic digits in tables, pagination and the date picker.
Development
npm install
npm run build # dist/ (JS + sourcemaps) and dist/styles.css
npm run lint
npm run typecheck # validates types/index.d.tsThe build preserves the module graph rather than producing one bundle, so deep
imports resolve and consumers tree-shake down to what they actually use. The
type definitions are hand-maintained — update types/index.d.ts in the same
change as any prop addition.
License
MIT
