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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mainset/ui-core

v0.1.0

Published

Basic SCSS, TypeScript and JS configurations for mainset UI

Readme

UI Core Design Tokens & Theming

The best and most scalable strategy for handling color tokens in a modern UI kit is using a multi-tiered design token system (often referred to as an "Aliasing" or "Semantic" system).

Standardizing on just literal names (blue-500) or just context names (primary-500) both present problems at scale. Instead, the industry standard (used by Material Design, Atlassian, GitHub, and Figma) is to use both in a strict hierarchy.

The 3-Tier Strategy

Here is the 3-Tier strategy that will give you infinite flexibility and perfect multi-theme support:

Level 1: Primitive Tokens (The Palette)

These are your literal, literal base colors. They describe exactly what the color is, completely independent of how it is used. They should never change meaning.

  • Naming: color-[name]-[scale]
  • Examples: --blue-100, --blue-500, --gray-900, --red-500.
  • Rule: Never use these directly in your component CSS. If you put background: var(--blue-500) in a Button, it's impossible to switch that button to "Purple" in a new theme without overriding the button's internal CSS.

Level 2: Semantic Tokens (The Intent / Context)

This is the magic layer. Semantic tokens describe how or where the color is used, but not what the actual color is. They act as a bridge, pointing to your Primitive Tokens.

  • Naming: color-[category]-[variant/state]
  • Examples: --color-text-primary, --color-bg-surface, --color-border-subtle, --color-action-primary-hover, --color-feedback-danger.
  • Rule: This is what you use in your CSS Modules.

Level 3: Component Tokens (Optional, but great for UI Kits)

For ultimate flexibility in a commercial UI kit, you map Semantic Tokens to specific Component Tokens.

  • Naming: [component]-[element]-[state]
  • Examples: --button-bg-primary-hover

How this actually works for Multiple Themes

The beauty of this system is that when you switch themes (Light vs. Dark, or Brand A vs. Brand B), you only change the Level 2 (Semantic) pointers. Your components never change.

/* 1. Primitive Tokens (Never change) */
:root {
  --blue-500: #3b82f6;
  --blue-600: #2563eb;
  --gray-50: #f9fafb;
  --gray-900: #111827;
  --red-500: #ef4444;
}

/* 2. Semantic Tokens - DEFAULT (Light Theme) */
:root,
[data-theme='light'] {
  --color-bg-base: var(--gray-50);
  --color-text-primary: var(--gray-900);

  --color-action-primary: var(--blue-500);
  --color-action-primary-hover: var(--blue-600);

  --color-feedback-error: var(--red-500);
}

/* 2. Semantic Tokens - DARK THEME */
[data-theme='dark'] {
  /* We flip the background and text... */
  --color-bg-base: var(--gray-900);
  --color-text-primary: var(--gray-50);

  /* Action colors might stay the same, or shift to a lighter blue */
  --color-action-primary: var(--blue-600);
}

/* 2. Semantic Tokens - "HALLOWEEN" THEME */
[data-theme='halloween'] {
  /* The layout remains identical, but the meaning of "primary" changes */
  --color-action-primary: var(--orange-500);
  --color-bg-base: var(--black);
}

Then, in your React CSS Module (Button.module.scss):

.button {
  background-color: var(--color-action-primary);
  color: var(--color-text-primary);
  /* The button doesn't know if it's blue, orange, light, or dark.
     It just knows it needs the "Primary Action" color. */
}

.button:hover {
  background-color: var(--color-action-primary-hover);
}

Why primary-500 is a trap

Many frameworks use primary-100 through primary-900. But what exactly is primary-100 used for? Is it a background for a badge? Is it text?

If primary-900 goes on primary-100 in light mode, does that invert in dark mode (where primary-100 text goes on a primary-900 background)? You end up writing crazy CSS rules trying to invert scales.

By using exact semantic intents (--color-text-primary-on-brand, --color-bg-surface), Dark Mode just means pointing that variable to a different Primitive Hex code.


Recommended Naming Taxonomy

A great format used by many enterprise teams is: [Category]-[Concept]-[Property]-[Variant]-[State]

  • Category: color, space, font
  • Concept: action, feedback, surface, text, border
  • Property/Context: primary, secondary, success, danger
  • State: default (implied), hover, active, disabled

Examples:

  • color-text-danger
  • color-bg-surface-hover
  • color-border-subtle

1. Category (The "What")

The foundational type of the design token.

  • color: Hex, RGB, or HSL values.
  • font: Typography properties (often split into font-size, font-weight, font-family, line-height).
  • space: Padding, margins, layout.
  • radius: Border-radius.
  • elevation: Box-shadows or z-index.
  • opacity: Alpha transparency.
  • duration: Animation or transition timings.

2. Concept (The "Where")

The structural UI element the category is applied to.

  • bg (or surface): Backgrounds of containers, cards, and pages.
  • text (or fg): Typography and text content.
  • border (or stroke): Outlines, dividers, and component borders.
  • icon: SVGs and glyphs.
  • action: Interactive elements like buttons, tabs, or links.
  • feedback: Alerts, toasts, and validation states.

3. Property / Context (The "Intent")

The semantic meaning or brand role of the element.

  • Brand Roles: primary, secondary, tertiary, brand.
  • Neutral Roles: neutral, base, inverse (e.g., white text on dark bg).
  • Feedback Roles: success (green), danger / error (red), warning (yellow), info (blue).

4. Variant (The "Scale or Prominence")

The magnitude, emphasis, or numeric scale of the token.

  • Emphasis: subtle, strong, muted, bold, heavy.
  • T-Shirt Sizes (for fonts, spacing, radius): xxs, xs, sm, md, lg, xl, xxl.
  • Numeric Scale (often for raw colors or weights): 100, 200, 300 ... 900.

5. State (The "Interaction")

The user pseudo-class. If it is the default state, this slot is completely omitted.

  • (default)
  • hover: Mouse over.
  • active: Mouse pressed down / tapping.
  • focus: Keyboard navigation focus.
  • disabled: Non-interactive state.
  • selected: Active tab or checked checkbox.