Skip to content

comake/standard-ui

Repository files navigation

standard-ui

A small, opinionated React component library by CoMake, built around a CSS-variable-driven design-token system and Tailwind CSS.

Components are thin React wrappers that emit semantic class names; the visual layer lives in a set of theme assets (themeProperties.css, twConfig.json, twComponentsConfig.json) that consumers wire into their own Tailwind configuration. Overlay primitives (popover, tooltip, context menu) are powered by Radix UI.

  • Package: standard-ui
  • License: MIT
  • React: 18.3+
  • Output: dual ESM + CJS bundle with bundled .d.ts types

Table of contents


Installation

npm install standard-ui
# or
yarn add standard-ui

You also need the peer dependencies:

npm install react react-dom tailwindcss tailwind-merge

Setup

standard-ui does not ship a precompiled stylesheet; it relies on Tailwind in the consuming app and on a set of theme assets distributed alongside the bundle.

1. Import the stylesheet

Import the library's CSS once at the entry of your application (e.g. index.tsx / _app.tsx):

import "standard-ui/dist/esm/bundle.js";   // bundle import is automatic via package.json
// The CSS is bundled into the package and injected at the top of the document by Rollup's postcss inject.

If you want to ship the design tokens explicitly, import the theme stylesheet:

import "standard-ui/dist/esm/assets/themeProperties.css";

This file declares the --core-color-*, --brand-*, --system-*, --text-*, etc. CSS variables that components reference.

2. Wire the design tokens into Tailwind

The token-to-Tailwind mapping ships as JSON. In your tailwind.config.js:

const twConfig = require("standard-ui/dist/esm/assets/twConfig.json");

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{html,js,ts,jsx,tsx}",
    "./node_modules/standard-ui/dist/**/*.js",
  ],
  theme: {
    extend: {
      colors: twConfig.colors,
      spacing: twConfig.spacing,
      borderRadius: twConfig.borderRadius,
      boxShadow: twConfig.boxShadow,
      fontSize: twConfig.fontSize,
      // ...spread the rest of twConfig as appropriate for your project
    },
  },
  plugins: [],
};

3. Load the component class definitions

Component-level classes (.button.primary, .tabs.selected, .input.primary, etc.) live in twComponentsConfig.json. Register them with Tailwind via the addComponents plugin API:

const components = require("standard-ui/dist/esm/assets/twComponentsConfig.json");
const plugin = require("tailwindcss/plugin");

module.exports = {
  // ...
  plugins: [
    plugin(({ addComponents }) => {
      addComponents(components);
    }),
  ],
};

Usage

import {
  Button,
  TextInput,
  Select,
  Typography,
  Tooltip,
  Switch,
  SvgIcon,
} from "standard-ui";

export function Example() {
  return (
    <div className="flex flex-col gap-4">
      <Typography variant="h2">Hello, standard-ui</Typography>

      <Button variant="primary" startIcon="plus" onClick={() => console.log("clicked")}>
        Create
      </Button>

      <TextInput
        placeholder="Search"
        endIcon="search"
        onChange={(e) => console.log(e.target.value)}
      />

      <Select
        options={[
          { label: "One", value: "1" },
          { label: "Two", value: "2" },
        ]}
        onChange={(v) => console.log(v)}
      />

      <Tooltip content="Helpful hint">
        <SvgIcon icon="help" />
      </Tooltip>
    </div>
  );
}

Components

Component Description
Avatar Circular image; single size variant (s).
AvatarList Row of avatars with an optional overflow count + label.
Button Primary / secondary / link variants, optional start/end icons, color variants, anchor mode (link), badge, custom LinkComponent (e.g. Next.js Link).
ButtonsSet Horizontal group of Buttons with shared rounded corners.
CardContent Card body with title/subtitle/description/icon and several layout variants, including a loading skeleton.
Checkbox Controlled checkbox with label.
CircularProgress Spinner SVG.
ClickAwayListener Wrapper that fires onClickAway when a click lands outside its child.
HorizontalSpacer / VerticalSpacer Token-sized spacing elements (xxxxsxxxxl).
NavigationBarHeader Section header with left/right content and optional icons.
NavigationBarItem List/link row with icons, active state, automatic overflow tooltip, and accessible keyboard handling.
NavigationBarItemWithDropdown NavigationBarItem plus a right-click context popover backed by SearchableOptionsList.
Select Single or multi-select built on Radix Popover + SearchableOptionsList.
Switch Segmented switch (icon + label per option), horizontal or vertical.
TabButton Tab as either a button (with useTransition pending state) or a link.
Tag Small labeled pill with optional icon.
TextInput TextInputBase + ExpandableTextInput (collapses to its icon until clicked).
Tooltip Radix tooltip with primary / secondary variants.
Typography Headings (h1h6), body (b1, b2), captions, and display sizes.
SvgIcon Registry of ~63 inline SVG icons (search, chevronDown, plus, trash, …) plus an ExternalIcon escape hatch for custom components.
SearchList SearchListLocal, SearchListLocalPopup, SearchListNetwork, and SearchableOptionsList for filterable lists with optional "create new" flow.

Icon names

SvgIcon accepts either a known icon key or an ExternalIcon component:

<SvgIcon icon="chevronDown" />
<SvgIcon ExternalIcon={MyCustomIcon} />

The full key list is defined in IconMap in src/components/SvgIcon/index.tsx.

Theming

The design system is layered:

  1. CSS variables (assets/themeProperties.css) — the single source of truth for color ramps, spacing, radii, typography, and shadows.
  2. Tailwind theme (assets/twConfig.json) — exposes those variables to Tailwind utility classes (bg-brand-base-colors-primary-500, w-system-horizontal-spacers-m, etc.).
  3. Component classes (assets/twComponentsConfig.json) — semantic component styles (.button.primary, .tabs.selected, .tooltip.primary) registered through addComponents.

To rebrand, override the relevant --core-color-* / --brand-* variables in your own stylesheet after importing themeProperties.css. To replace component styles wholesale, swap the twComponentsConfig.json payload before passing it to addComponents.

Project structure

src/
├── index.ts                    # Library entry; imports CSS and re-exports components
├── assets/
│   ├── themeProperties.css     # CSS variable design tokens
│   ├── twConfig.json           # Tailwind theme mapping
│   └── twComponentsConfig.json # Per-component class definitions
└── components/
    ├── index.ts                # Public component exports
    ├── index.css               # @tailwind base/components/utilities
    ├── Button/                 # Compound components live in folders
    ├── SearchList/
    ├── TextInput/
    ├── SvgIcon/                # Icon registry + individual icon components
    └── *.tsx                   # Single-file components

Development

nvm use            # see .nvmrc
npm install
npm run dev        # rollup -c -w
npm run lint

Build

npm run build

This runs eslint --fix, clears dist/, and produces:

  • dist/cjs/bundle.js — CommonJS bundle
  • dist/esm/bundle.js — ES module bundle
  • dist/index.d.ts — bundled type declarations
  • dist/{cjs,esm}/assets/ — copied themeProperties.css, twConfig.json, twComponentsConfig.json

Peer dependencies

{
  "react": ">=18.3.1",
  "react-dom": ">=18.3.1",
  "tailwindcss": "^3.4.4",
  "tailwind-merge": "^2.3.0"
}

Internal dependencies bundled with the library: @radix-ui/react-popover, @radix-ui/react-tooltip, @radix-ui/react-context-menu, lodash.

Contributing

  1. Fork and create a feature branch.
  2. Make changes under src/.
  3. Run npm run lint and npm run build.
  4. Open a pull request against main.

License

MIT © CoMake

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors