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

@tatumio/tatum-design-system

v1.27.2

Published

Tatum Design System — React components and Tailwind design tokens for building Tatum-styled UIs.

Readme

Tatum Design System

A modern, reusable React component library. Published to public npm as @tatumio/tatum-design-system under the MIT licence.

Using with Claude Code

The repo ships a Claude Code skill that teaches the assistant to reach for existing TDS components and semantic Tailwind tokens. It ships in this package under skills/tds/ and is published at /skill/ on the docs site.

Installation

yarn add @tatumio/tatum-design-system
# or
npm install @tatumio/tatum-design-system

No tokens, no .npmrc, no private registry — the package comes from registry.npmjs.org like any other public dependency.

react and react-dom are peer dependencies, and TDS requires ^19.0.0. React 18 is not supported: under @types/react@18 a ComponentType<IconProps> prop rejects lucide-react's icons, because React 18's propTypes typing makes size invariant. React 19 removed propTypes, so the problem disappears there.

Usage

// Import components
import {Button, Card} from '@tatumio/tatum-design-system';

// Import styles to get the fonts
import '@tatumio/tatum-design-system/styles.css';

function App() {
    return (
        <Card>
            <h2>Hello World</h2>
            <Button>Click me</Button>
        </Card>
    );
}

Alternative Import Methods

You can also import individual components:

import {Button} from '@tatumio/tatum-design-system/components/Button';

Icons

TDS does not ship an icon set. The icons its own components draw (close buttons, chevrons, checkmarks, toast status icons, …) default to lucide-react. To use a different set, wrap the app in TdsIconProvider and pass replacements by TDS name — any you leave out keep the Lucide default:

import {TdsIconProvider, type TdsIcons} from '@tatumio/tatum-design-system';
import {CloseIcon, SuccessIcon} from 'your-icon-set';

// Module-level, so the provider's value stays stable across renders.
const icons: Partial<TdsIcons> = {Close: CloseIcon, ToastSuccess: SuccessIcon};

<TdsIconProvider icons={icons}>
  <App/>  {/* include wherever <Toaster/> is rendered */}
</TdsIconProvider>

The names are the keys of defaultTdsIcons (typed TdsIconName). Most are shared by several components; the toast status icons (ToastSuccess, ToastError, ToastWarning, ToastInfo, ToastLoading) and AddressCopied have their own, so they can be styled differently from the same glyph elsewhere. Providers nest and merge. Your icon set stays in your own bundle; TDS never ships it.

Components that render a caller-supplied icon (FeaturedIcon, FileIcon, AddressHandle) take an icon prop typed React.ComponentType<IconProps>, so you pass a component from whichever icon library you use. IconProps is exported from the package root:

interface IconProps extends React.SVGProps<SVGSVGElement> {
  size?: number
}

Any icon component matching that shape works — lucide-react is what the Storybook stories use, and it is the same geometry TDS renders internally:

import {FeaturedIcon} from '@tatumio/tatum-design-system';
import {CircleAlert} from 'lucide-react';

<FeaturedIcon icon={CircleAlert} size="md" color="error"/>

Widget Integration

When using the design system in widget environments, portal-based components (like modals, tooltips...) are automatically handled for Shadow DOM environments. If you're using prefixed Tailwind CSS, you need to add the data-tds-root="true" attribute to your widget container to ensure proper styling:

function MyWidget() {
    return (
        <div data-tds-root="true">
            {/* Your widget content */}
            <Dialog>
                {/* The dialog renders inside the widget container with its styles */}
            </Dialog>
        </div>
    );
}

Without the data-tds-root attribute, portal components would render in document.body and lose access to your prefixed Tailwind styles.

Keyboard focus inside a shadow root

Radix UI, which TDS builds on, tracks focus with document.activeElement. Inside a shadow root that resolves to the host element, so keyboard navigation in Tabs, RadioGroup and Dropdown and focus trapping in Dialog and Popover break there. Until Radix fixes this upstream (radix-ui/primitives#3674), apps that render TDS in a shadow root patch @radix-ui/react-focus-scope and @radix-ui/react-roving-focus themselves with patch-package, applying that PR's change: route every document.activeElement read through a helper that descends into shadowRoot.activeElement.

Using the Tailwind Plugin

The Tatum Design System includes a custom Tailwind CSS plugin that provides predefined utilities, components, and theming capabilities for your projects.

Installation

Add the plugin to your Tailwind configuration:

// tailwind.config.js
import tdsPlugin from '@tatumio/tatum-design-system/tailwind-plugin';
import animate from 'tailwindcss-animate';

export default {
    content: [
        "./src/**/*.{js,jsx,ts,tsx}",
        "./node_modules/@tatumio/tatum-design-system/dist/**/*.{js,ts,jsx,tsx}",
    ],
    plugins: [tdsPlugin, animate],
}

In a CommonJS config, the plugin is the module's default export: require('@tatumio/tatum-design-system/tailwind-plugin').default.

TDS's overlays (dialogs, popovers, menus) use the enter/exit animation classes from tailwindcss-animate, so add it to your project (yarn add -D tailwindcss-animate) and register it next to the TDS plugin.

Features

The plugin includes:

  • Colors: Brand colors, accent colors, semantic colors
  • Typography: Text sizes, weights, line heights, font families
  • Borders: Border widths, radii, and styles
  • Shadows: Elevation levels and interactive states
  • Transitions: Animation timing, easing functions
  • Z-index: Layering system for consistent stacking

For comprehensive examples of all available design tokens and their usage, please refer to the Storybook documentation where you can find interactive examples for each feature.

Color Tokens: Primitives vs. Semantic

The plugin exposes two tiers of color tokens. Understanding the difference is important for building components that correctly support dark mode.

Primitive colors (tatum-*)

Static, hardcoded RGBA values. They never change between light and dark mode.

tatum-gray-100     → rgb(245 245 245)  — always this value
tatum-primary-500  → rgb(79 55 253)    — always this value

Use primitives when you need a specific color that must stay the same regardless of theme — e.g. a brand logo background, a fixed overlay, or an illustration fill.

<div className="bg-tatum-primary-500 text-tatum-white">Always purple</div>

Semantic tokens

CSS custom properties that resolve to different values in light and dark mode. The plugin defines the light values on :root / :host and overrides them inside .dark / :host(.dark).

Each token category has its own Tailwind utility — the class is {utility}-{token}:

text-primary       → var(--tds-text-primary)     light: tatum-gray-900 / dark: tatum-dark-gray-50
bg-primary         → var(--tds-bg-primary)        light: tatum-white    / dark: tatum-dark-gray-950
border-secondary   → var(--tds-border-secondary)  light: tatum-gray-200 / dark: tatum-dark-gray-700
text-fg-primary    → var(--tds-fg-primary)        icon / foreground color
bg-utility-brand-100                              status / palette color
ring-focus-ring    → var(--tds-focus-ring)        focus ring color
shadow-xs          → var(--tds-shadow-xs)         shadow color with baked-in opacity

Always prefer semantic tokens for component styling. They give you dark mode support for free.

<div className="bg-primary text-primary border border-secondary">
  <Icon className="text-fg-brand-primary" />
</div>

Dark Mode

Dark mode is activated by adding the .dark class or data-mode="dark" attribute to the root element:

<!-- class-based (Tailwind default) -->
<html class="dark">

<!-- attribute-based -->
<html data-mode="dark">

Both strategies are supported simultaneously.

Using tailwind-merge with TDS Tokens

TDS defines custom text-* utilities for both font sizes (text-tatum-heading-xs) and colors (text-tatum-primary-500). A vanilla tailwind-merge instance cannot tell them apart — both match the text- prefix, so tw-merge groups them together and the last class silently wins, stripping the other.

The design system ships a withTds tw-merge plugin that solves this. Any project that uses TDS tokens with tailwind-merge must apply it.

Setup

Plug withTds into your project's clsxm / cn helper:

import { type ClassValue, clsx } from 'clsx'
import { extendTailwindMerge } from 'tailwind-merge'
import { withTds } from '@tatumio/tatum-design-system/tw-merge'

const twMerge = extendTailwindMerge(withTds)

export function clsxm(...classes: ClassValue[]) {
  return twMerge(clsx(...classes))
}

If you have additional Tailwind extensions beyond TDS, compose them alongside the plugin:

const twMerge = extendTailwindMerge(
  { extend: { /* your own additional extensions */ } },
  withTds,
)

Note: tailwind-merge ≥ 2.x is required. If your project uses v1.x, upgrade first — the plugin API was introduced in v2.

Licence

MIT — see the LICENSE file in this package.

Dependencies are installed alongside TDS and ship under their own licences; none is bundled into dist.

External Resources

Some parts of TDS load resources from other hosts at runtime. Allow them in your Content Security Policy, and account for them in your privacy setup:

  • styles.css imports the Poppins font from Google Fonts (fonts.googleapis.com, fonts.gstatic.com).
  • CodeHighlight loads the Roboto Mono font from Google Fonts.
  • ChainIcon fetches the chain list from https://blockchains.tatum.io/blockchains2.json and renders each chain's logo from the URL listed there (currently also on blockchains.tatum.io). If the list can't be loaded, the icon stays a placeholder.

TypeScript Support

All components include TypeScript definitions. For proper module resolution in consuming projects, we recommend using TypeScript with "moduleResolution": "node16" or "bundler".

Contributing

TDS is developed by Tatum in a private repository and does not accept outside contributions. For questions or problems, contact Tatum.