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

reso-ui

v3.18.1

Published

Reusable React components in Typescript

Readme

Reso UI

A React component library built with TypeScript + SCSS. Ships as tree-shakeable ESM + CJS output via Rollup.

Storybook: reso-ui-storybook.s3-website-ap-southeast-1.amazonaws.com


Guiding Principles

  1. Customizability-first — Clients can and should be able to override most if not all units of a UI component. Override the entire palette via <ResoUiProvider theme={...}>, or override colours and behaviour directly on individual components via props. Clients should NOT override styles by hacky CSS means (e.g. directly overwriting compiled CSS class names in their projects).

  2. Clean and minimalistic — We eliminate clutter and prioritize ease of interaction for app users AND ease of component use for developers. Maximum configurability, yet minimal complication. Easy. Simple. Minimal.

  3. In-house solutions — We build everything ourselves (drag and drop, date selector calculations, etc). No dependencies on third-party component libraries unless absolutely necessary.

  4. Performant and zero runtime cost — Theming via CSS custom properties; no theme object traversal at render time.


Table of Contents


Using the Library (Client Setup)

Requirements

  • Node 18+
  • React ^18.2
  • React Dom ^18.2
  • classnames ^2.3 (peer dependency — install it if your project doesn't already have it)

Install

npm install reso-ui
# peer deps (if not already installed)
npm install classnames

For the latest alpha (v3 pre-release):

npm install reso-ui@alpha

For the latest stable v2 release:

npm install [email protected]

Client project files

custom.d.ts (project root)

Create this file so TypeScript knows how to handle style and reso-ui stylesheet imports:

// custom.d.ts
declare module "*.scss";
declare module "*.css";
declare module "reso-ui/styles";
declare module "*.ttf" {
  const content: string;
  export default content;
}

tsconfig.json

skipLibCheck: true is required. Reso UI's compiled type declarations reference SVG imports internally. Without this flag, TypeScript will try to resolve them in your project's module declaration context, causing type errors on icon components.

{
  "compilerOptions": {
    "skipLibCheck": true,
    ...
  },
  "include": ["src", "custom.d.ts"]
}

Bundler Setup

The library ships pre-compiled JS (ESM + CJS), a single CSS file, and the Poppins and DancingScript font files — all locally bundled with no external network dependency.

Pick the section that matches your bundler:


Vite

Tested with Vite 6.x (@vitejs/plugin-react 5.x).

Vite handles CSS imports and font asset resolution out of the box. No vite.config.ts changes are required for reso-ui to work.

Install the core Vite dependencies:

npm install -D vite@^6.4.2 @vitejs/plugin-react@^5.2.0

If your project uses its own SCSS files, install the sass package:

npm install -D sass@^1.87.0

If your project imports .svg files as React components, add vite-plugin-svgr:

npm install -D vite-plugin-svgr@^5.2.0
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgr from "vite-plugin-svgr";

export default defineConfig({
  plugins: [react(), svgr()],
});

That's it — import "reso-ui/styles" works immediately since Vite natively processes CSS from node_modules and resolves the relative url(fonts/...) paths in the stylesheet.


Webpack

Tested with Webpack 5.x (matches the Reso online-store and web-storefront projects).

Your webpack config needs:

  1. CSS loader — to handle import "reso-ui/styles"
  2. asset modules — to resolve the .ttf font files referenced in the library CSS

Install the required loaders:

npm install -D webpack@^5.99.6 webpack-cli@^6.0.1 webpack-dev-server@^5.2.1 \
  ts-loader@^9.5.2 style-loader@^4.0.0 css-loader@^7.1.2 \
  sass-loader@^16.0.5 sass@^1.87.0 \
  html-webpack-plugin@^5.6.3

Minimum webpack rules:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      // Handle CSS (from reso-ui and your own styles)
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      // Handle SCSS (your own styles only — reso-ui ships pre-compiled CSS)
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
      // Required: resolve font files bundled with reso-ui
      {
        test: /\.(ttf|woff|woff2|eot)$/,
        type: "asset/resource",
      },
      // TypeScript
      {
        test: /\.tsx?$/,
        loader: "ts-loader",
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
};

Fonts: Poppins (all weights) and DancingScript are bundled inside the npm package under dist/fonts/. The asset/resource webpack rule lets webpack resolve the font paths from dist/styles.css automatically — no CDN or manual font installation required.


Next.js

Tested with Next.js 15.x (App Router and Pages Router).

Next.js handles CSS imports, font asset resolution, and TypeScript out of the box. No next.config changes are required for reso-ui to work.

npm install next@^15.5.18 react@^18.2.0 react-dom@^18.2.0
npm install reso-ui classnames

If your project uses its own SCSS files:

npm install -D sass@^1.87.0

If your project imports .svg files as React components, configure @svgr/webpack in next.config:

// next.config.mjs
const nextConfig = {
  webpack(config) {
    config.module.rules.push({
      test: /\.svg$/,
      use: ["@svgr/webpack"],
    });
    return config;
  },
};

export default nextConfig;
npm install -D @svgr/webpack@^8.1.0
App Router setup

Reso UI components use React context and hooks internally, so they require a "use client" boundary. Create a client-side provider wrapper:

// src/providers/ResoUiClientProvider.tsx
"use client";

import { ResoUiProvider } from "reso-ui";

export const ResoUiClientProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => <ResoUiProvider mode="system">{children}</ResoUiProvider>;

Then import the styles and provider in your root layout:

// src/app/layout.tsx
import "reso-ui/styles";
import "./globals.css";
import { ResoUiClientProvider } from "@/providers/ResoUiClientProvider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <ResoUiClientProvider>{children}</ResoUiClientProvider>
      </body>
    </html>
  );
}

Use reso-ui components in any Client Component:

// src/app/dashboard/page.tsx
"use client";

import { Button, Text, View } from "reso-ui";

export default function DashboardPage() {
  return (
    <View pt={9} ph={4}>
      <Text Element="h1">Dashboard</Text>
      <Button text="Click me" onClick={() => alert("clicked")} />
    </View>
  );
}
Pages Router setup

Import styles and wrap with the provider in _app.tsx:

// pages/_app.tsx
import "reso-ui/styles";
import "../styles/globals.css";
import { ResoUiProvider } from "reso-ui";
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <ResoUiProvider mode="system">
      <Component {...pageProps} />
    </ResoUiProvider>
  );
}

Note: Reso UI does not ship "use client" directives. In the App Router, all pages and components that use reso-ui components must be Client Components (marked with "use client"), or the reso-ui components must be wrapped in a Client Component.


Create React App (CRA)

Tested with react-scripts 5.x.

CRA handles CSS imports, font asset resolution, and SVG imports out of the box. No configuration changes are required.

npx create-react-app my-app --template typescript
cd my-app
npm install reso-ui classnames

If your project uses its own SCSS files, install the sass package:

npm install -D sass@^1.87.0

Everything else works immediately — CRA's built-in webpack config already includes CSS loaders, asset modules for fonts, and @svgr/webpack for SVG imports.


Provider setup

Wrap your application root with ResoUiProvider. It provides theming and responsive context to all Reso UI components.

// index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import { ResoUiProvider } from "reso-ui";
import "reso-ui/styles";
import App from "./App";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <ResoUiProvider>
    <App />
  </ResoUiProvider>,
);

Import styles

Import the Reso UI stylesheet before your own application styles so your custom styles can override them:

// index.tsx (or index.ts / index.js)
import "reso-ui/styles"; // ← reso-ui first
import "./index.css"; // ← your app styles after

Basic usage

import { Button, Banner, Text } from "reso-ui";

export const MyPage = () => (
  <>
    <Banner type="info" text="Welcome to My App!" />
    <Text Element="h1">Hello World</Text>
    <Button text="Click me" onClick={() => alert("clicked")} />
  </>
);

All component props and usage examples are documented in the Storybook instance.


Theming & Dark Mode Setup

Reso UI supports light mode, dark mode, and system-preference-based theming out of the box. Theme switching is controlled via the mode prop on ResoUiProvider.

Quick setup

// App.tsx
import React, { useState } from "react";
import { ResoUiProvider, useTheme } from "reso-ui";
import "reso-ui/styles";

const ThemeToggle = () => {
  const { resolvedMode, setMode } = useTheme();
  return (
    <button
      onClick={() => setMode(resolvedMode === "light" ? "dark" : "light")}
    >
      Switch to {resolvedMode === "light" ? "dark" : "light"} mode
    </button>
  );
};

const App = () => (
  <ResoUiProvider mode="system">
    <ThemeToggle />
    {/* your app */}
  </ResoUiProvider>
);

Mode options

| Mode | Behaviour | | ------------------- | ------------------------------------------------------------------------------------------ | | "light" (default) | Light theme applied | | "dark" | Dark theme applied | | "system" | Follows the user's OS prefers-color-scheme preference and reacts to changes in real time |

How it works

ResoUiProvider wraps your app with a ThemeProvider that sets the data-resoui-theme attribute and CSS custom properties on your #root element. All Reso UI component styles scope their dark-mode overrides to [data-resoui-theme="dark"], so switching modes is instantaneous with zero re-renders of component trees.

Using useTheme in your own components

import { useTheme } from "reso-ui";

const MyComponent = () => {
  const { resolvedMode, setMode, theme } = useTheme();
  // resolvedMode is always "light" or "dark" (resolved from "system" if needed)
  // setMode("light" | "dark" | "system") to change the theme
  // theme contains the current color and token overrides
  return (
    <div className={resolvedMode === "dark" ? "my-dark-style" : ""}>
      {/* ... */}
    </div>
  );
};

Styling your own components for dark mode

Scope dark-mode overrides with the same attribute selector:

.my_component {
  background: white;
  color: #333;
}

[data-resoui-theme="dark"] .my_component {
  background: #1e1e1e;
  color: #e0e0e0;
}

Responsive Context

ResoUiProvider includes a ResponsiveContext that exposes viewport breakpoints to any component in your app.

Basic usage (viewport-only)

import { useContext } from "react";
import { ResponsiveContext } from "reso-ui";

const MyComponent = () => {
  const { isMobile, isTablet } = useContext(ResponsiveContext);
  return isMobile ? <MobileLayout /> : <DesktopLayout />;
};

Breakpoints

| Flag | Range | | -------------- | ---------------------- | | isMobile | width < 640 | | isTablet | 640 <= width < 768 | | isMdDesktop | 768 <= width < 1024 | | isLgDesktop | 1024 <= width < 1280 | | isXLgDesktop | width >= 1280 |

Container-aware breakpoints (optional)

By default, breakpoints are computed from the viewport width. If your app has sidebars, drawers, or panels that reduce the main content area, you can register a container element so breakpoints reflect the actual available space.

When a container is registered, breakpoints are computed from Math.min(viewportWidth, containerWidth). This means isMobile becomes true when either the viewport or the tracked container is narrow.

import { useContext, useEffect, useRef } from "react";
import { Flex, ResponsiveContext } from "reso-ui";

const App = () => {
  const mainRef = useRef<HTMLDivElement>(null);
  const { setContainerRef } = useContext(ResponsiveContext);

  useEffect(() => {
    if (mainRef.current) setContainerRef(mainRef.current);
    return () => setContainerRef(null);
  }, []);

  return (
    <Flex ref={mainRef} direction="column">
      {/* All child components get container-aware breakpoints */}
    </Flex>
  );
};

When no container is registered (the default), breakpoints work exactly as before — no changes needed in existing apps.

Available context values

Top-level (resolved) — breakpoints computed from Math.min(viewportWidth, containerWidth):

| Field | Type | Description | | ----------------- | ----------------------------------- | --------------------------------------- | | isMobile | boolean | Effective width < 640 | | isTablet | boolean | 640 <= effective width < 768 | | isMdDesktop | boolean | 768 <= effective width < 1024 | | isLgDesktop | boolean | 1024 <= effective width < 1280 | | isXLgDesktop | boolean | Effective width >= 1280 | | windowWidth | number | Actual viewport width | | windowHeight | number | Actual viewport height | | setContainerRef | (el: HTMLElement \| null) => void | Register/unregister a container element |

viewport — always based on the viewport, ignoring container. Use this for structural layout decisions (e.g., whether to show a sidebar):

| Field | Type | Description | | ----------------------- | --------- | ----------------------------- | | viewport.isMobile | boolean | Viewport width < 640 | | viewport.isTablet | boolean | 640 <= viewport width < 768 | | viewport.isMdDesktop | boolean | 768 <= viewport width < 1024 | | viewport.isLgDesktop | boolean | 1024 <= viewport width < 1280 | | viewport.isXLgDesktop | boolean | Viewport width >= 1280 | | viewport.width | number | Viewport width | | viewport.height | number | Viewport height |

container — breakpoints and dimensions of the tracked container element:

| Field | Type | Description | | ------------------------ | --------- | ------------------------------------------------- | | container.isMobile | boolean | Container width < 640 (true when none registered) | | container.isTablet | boolean | 640 <= container width < 768 | | container.isMdDesktop | boolean | 768 <= container width < 1024 | | container.isLgDesktop | boolean | 1024 <= container width < 1280 | | container.isXLgDesktop | boolean | Container width >= 1280 | | container.width | number | Container width (0 if none registered) | | container.height | number | Container height (0 if none registered) |

When to use which

// Page layout — use top-level (resolved)
const { isMobile } = useContext(ResponsiveContext);
return <View pt={isMobile ? 7 : 9}>{/* ... */}</View>;

// Structural decisions (show/hide panels) — use viewport
const { viewport } = useContext(ResponsiveContext);
const showSidebar = !viewport.isMobile && !viewport.isTablet;

Overriding the Color Palette

ResoUiProvider accepts optional theme and mode props for runtime theming with no build step required.

Light / dark mode

// Light (default)
<ResoUiProvider>…</ResoUiProvider>

// Dark
<ResoUiProvider mode="dark">…</ResoUiProvider>

// Follow OS preference (prefers-color-scheme)
<ResoUiProvider mode="system">…</ResoUiProvider>

Override palette semantics

Pass a partial theme.colors object to override semantic color roles. Keys map to CSS custom properties on --resoui-*.

<ResoUiProvider
  theme={{
    colors: {
      brandPrimary: "#1a365d", // primary brand (navy)
      brandSecondary: "#c53030", // secondary brand (coral/CTA)
      utilityError: "#e53e3e",
      utilitySuccess: "#276749",
    },
  }}
>
  <App />
</ResoUiProvider>

Full colors keys (ResoPaletteSemantics):

| Key | CSS variable | | ------------------------ | ----------------------------------- | | brandPrimaryGhost | --resoui-brand-primary-ghost | | brandPrimaryLight | --resoui-brand-primary-light | | brandPrimaryMedium | --resoui-brand-primary-medium | | brandPrimary | --resoui-brand-primary | | brandPrimaryDark | --resoui-brand-primary-dark | | brandPrimaryDarkest | --resoui-brand-primary-darkest | | brandSecondaryPale | --resoui-brand-secondary-pale | | brandSecondaryLight | --resoui-brand-secondary-light | | brandSecondary | --resoui-brand-secondary | | brandSecondaryDark | --resoui-brand-secondary-dark | | brandSecondaryDarker | --resoui-brand-secondary-darker | | brandSecondaryGradient | --resoui-brand-secondary-gradient | | brandTertiaryPale | --resoui-brand-tertiary-pale | | brandTertiaryLight | --resoui-brand-tertiary-light | | brandTertiary | --resoui-brand-tertiary | | brandTertiaryDark | --resoui-brand-tertiary-dark | | brandTertiaryDarker | --resoui-brand-tertiary-darker | | brandQuaternaryPale | --resoui-brand-quaternary-pale | | brandQuaternaryLight | --resoui-brand-quaternary-light | | brandQuaternary | --resoui-brand-quaternary | | brandQuaternaryDark | --resoui-brand-quaternary-dark | | brandQuaternaryDarker | --resoui-brand-quaternary-darker | | utilitySuccessBg | --resoui-utility-success-bg | | utilitySuccessLight | --resoui-utility-success-light | | utilitySuccess | --resoui-utility-success | | utilitySuccessDark | --resoui-utility-success-dark | | utilityWarningBg | --resoui-utility-warning-bg | | utilityWarningLight | --resoui-utility-warning-light | | utilityWarning | --resoui-utility-warning | | utilityWarningDark | --resoui-utility-warning-dark | | utilityErrorBg | --resoui-utility-error-bg | | utilityErrorLight | --resoui-utility-error-light | | utilityError | --resoui-utility-error | | utilityErrorDark | --resoui-utility-error-dark | | utilityInfoBg | --resoui-utility-info-bg | | utilityInfoLight | --resoui-utility-info-light | | utilityInfo | --resoui-utility-info | | utilityInfoDark | --resoui-utility-info-dark | | neutralLightest | --resoui-neutral-lightest | | neutralLight | --resoui-neutral-light | | neutralMedium | --resoui-neutral-medium | | neutralDark | --resoui-neutral-dark | | neutralDarker | --resoui-neutral-darker | | neutralOverlay | --resoui-neutral-overlay | | baseWhite | --resoui-base-white | | baseBlack | --resoui-base-black |

Override spacing, typography, and layout tokens

<ResoUiProvider
  theme={{
    tokens: {
      fontFamily: "'Inter', sans-serif",
      radiusDefault: "4px",
      radiusLg: "8px",
      spacing4: "20px",
    },
  }}
>
  <App />
</ResoUiProvider>

Full tokens keys (ResoTokens):

| Key | CSS variable | Default | | ------------------------- | ----------------------------------------------- | ----------------------------------- | | spacing0spacing9 | --resoui-spacing-0--resoui-spacing-9 | 0px96px | | fontFamily | --resoui-font-family | "Poppins", "Roboto", sans-serif | | fontSize1fontSize9 | --resoui-font-size-1--resoui-font-size-9 | 10px26px | | fontWeightNormal | --resoui-font-weight-normal | 400 | | fontWeightMedium | --resoui-font-weight-medium | 500 | | fontWeightSemibold | --resoui-font-weight-semibold | 600 | | fontWeightBold | --resoui-font-weight-bold | 700 | | radiusSm | --resoui-radius-sm | 4px | | radiusDefault | --resoui-radius-default | 8px | | radiusLg | --resoui-radius-lg | 16px | | radiusFull | --resoui-radius-full | 9999px | | shadowSm | --resoui-shadow-sm | 0 1px 3px rgba(0,0,0,0.1) | | shadowDefault | --resoui-shadow-default | 0px 2px 15px rgba(34,60,102,0.2) | | shadowLg | --resoui-shadow-lg | 0px 4px 25px rgba(34,60,102,0.15) | | transitionFast | --resoui-transition-fast | 0.125s | | transitionNormal | --resoui-transition-normal | 0.25s | | transitionSlow | --resoui-transition-slow | 0.5s |


Utility Classes

Reso UI ships utility CSS classes that consumer projects can apply directly via className or rootClassName. These are included in the reso-ui/styles stylesheet and support dark mode automatically where applicable.

Quick Reference

| Class | Category | Dark Mode | Description | | ------------------------------------------------------ | ---------- | --------- | ------------------------------------------------------ | | resoui_section_border | Layout | Yes | Bordered section container with default border-radius | | resoui_table_base | Tables | Yes | Base <table> styling (font, collapse, full width) | | resoui_th_base | Tables | Yes | Table header cell (padding, border, font-weight) | | resoui_tr_base | Tables | Yes | Table row (border, hover highlight) | | resoui_tr_base_selected | Tables | Yes | Selected table row highlight | | resoui_td_base | Tables | No | Table data cell (padding) | | resoui_navItem_base | Navigation | No | Nav item base layout for custom NavItem renders | | resoui_dropdown_option_base | Forms | Yes | Dropdown option base for custom DropdownSelect options | | resoui_no_select | General | No | Disable text selection | | resoui_component_disabled | General | No | Disabled overlay with pointer-events disabled | | resoui_background_image | General | No | Background image with cover | | resoui_truncate | Text | No | Truncate text with ellipsis | | resoui_text_no_block_margin | Text | No | Remove default block margins | | resoui_text_no_inline_margin | Text | No | Remove default inline margins |

Section Border

A bordered container for card-like content sections. Apply via rootClassName on Flex or View.

import { Flex, Text } from "reso-ui";

<Flex direction="column" rootClassName="resoui_section_border" pa={5}>
  <Text Element="h3">Section Title</Text>
  <Text>Section content goes here.</Text>
</Flex>;

Light mode: 1px solid neutral border + default border-radius. Dark mode: border color automatically darkens.

Tables

Base styles for native HTML <table> elements. Apply via the className attribute. Dark mode is handled automatically.

| Class | Apply to | What it does | | ------------------------- | --------- | ------------------------------------------------------ | | resoui_table_base | <table> | Font-family, border-collapse, full width, font size | | resoui_th_base | <th> | Padding, bottom border, font-weight 500, left-aligned | | resoui_tr_base | <tr> | Bottom border, hover background highlight | | resoui_tr_base_selected | <tr> | Selected row highlight (combine with resoui_tr_base) | | resoui_td_base | <td> | Cell padding |

<table className="resoui_table_base">
  <thead>
    <tr>
      <th className="resoui_th_base">Name</th>
      <th className="resoui_th_base">Email</th>
      <th className="resoui_th_base">Role</th>
    </tr>
  </thead>
  <tbody>
    <tr className="resoui_tr_base">
      <td className="resoui_td_base">John Doe</td>
      <td className="resoui_td_base">[email protected]</td>
      <td className="resoui_td_base">Admin</td>
    </tr>
  </tbody>
</table>

For selected rows, combine both classes:

<tr className={`resoui_tr_base ${selectedId === item.id ? "resoui_tr_base_selected" : ""}`}>

Add custom column-specific styles alongside the utility classes:

<th className="resoui_th_base myPage_th_right">Amount</th>
<td className="resoui_td_base myPage_td_mono">$120.00</td>
.myPage_th_right {
  text-align: right;
}
.myPage_td_mono {
  font-family: monospace;
  font-size: 12px;
}

Nav Item Base

Base layout class for custom nav items rendered inside NavItem via renderCustomNavItem. Provides standard sizing consistent with the Navbar.

import { NavItem } from "reso-ui";
import { Link, useLocation } from "react-router-dom";

const AppNavItem = ({ to, children }) => {
  const { pathname } = useLocation();

  return (
    <NavItem
      renderCustomNavItem={() => (
        <Link
          to={to}
          className={`navItem_base ${pathname === to ? "my_nav_active" : ""}`}
        >
          {children}
        </Link>
      )}
    >
      {children}
    </NavItem>
  );
};

Dropdown Option Base

Base class for custom dropdown options rendered inside DropdownSelect. Provides consistent sizing, padding, and dark mode text color.

import { DropdownSelect } from "reso-ui";
import { Link } from "react-router-dom";

<DropdownSelect label="Account">
  <Link to="/profile" className="resoui_dropdown_option_base">
    My Profile
  </Link>
  <Link to="/settings" className="resoui_dropdown_option_base">
    Settings
  </Link>
</DropdownSelect>;

General Utilities

| Class | What it does | | --------------------------- | ------------------------------------------------- | | resoui_no_select | Prevent text selection (all browser prefixes) | | resoui_component_disabled | Semi-transparent overlay + disable pointer events | | resoui_background_image | Background image: cover, centered, no-repeat |

<Flex rootClassName={isLocked ? "resoui_component_disabled" : ""}>
  <Text>This section is locked</Text>
</Flex>

Text Utilities

| Class | What it does | | ------------------------------ | ----------------------------------------------------------------------------------------- | | resoui_truncate | Truncate with ellipsis (overflow: hidden; text-overflow: ellipsis; white-space: nowrap) | | resoui_text_no_block_margin | Remove block margins from headings (margin-block-start: 0) | | resoui_text_no_inline_margin | Remove inline margins |

<Text rootClassName="resoui_truncate" rootStyles={{ maxWidth: "200px" }}>
  Very long product name that should be truncated
</Text>

Contributing

For developer setup, build commands, CI/CD pipeline, and publishing instructions, see docs/DEVNOTES.md.