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

@scalably/ui

v0.9.8

Published

Scalably Design System - Shared UI Components

Downloads

1,970

Readme

Scalably UI Component Library

license npm version npm downloads npm bundle size TypeScript Node React Coverage

A modern, accessible, and fully isolated React component library built with TypeScript and Tailwind CSS. Designed to work seamlessly across multiple projects without style conflicts.

🚀 Features

  • Style Isolation: All components use prefixed Tailwind classes (sui-*) to prevent conflicts
  • TypeScript First: Full type safety with comprehensive prop interfaces
  • Accessible: Built with accessibility best practices and WCAG compliance
  • Modern: Uses latest React patterns and modern build tools (tsup, Vite, Storybook)
  • Rich Text Editing: TipTap-based editor with character counting, media embeds, and formatting toolbar
  • Customizable: Flexible variant system with class-variance-authority
  • Comprehensive: 20+ production-ready components with full documentation
  • Production Ready: Complete build pipeline with CommonJS and ES modules
  • Icons & Assets: First-class icon set, avatar placeholders, and logo assets
  • Utilities & Helpers: Shared date helpers, form helpers, and utility functions (cn, debounce, throttle, scopeClass)

📦 Installation

npm install @scalably/ui

🎨 Usage

1. Use Components (Styles Auto-Injected)

The ScalablyUIProvider automatically injects styles into document.head, so you don't need to manually import CSS. This ensures styles work correctly in portals (modals, tooltips, etc.). No wrapper or scope class is required—just wrap your app once.

import { ScalablyUIProvider, Form, FormField, Input, Button, ToastContainer, Toast } from "@scalably/ui";

export default function App() {
  return (
    <ScalablyUIProvider>
      <main>
        <Form onSubmit={(e) => e.preventDefault()}>
          <FormField label="Email" htmlFor="email">
            <Input id="email" type="email" placeholder="Enter your email" />
          </FormField>
          <Button className="sui-mt-4" type="submit">Submit</Button>
        </Form>

        {/* Toasts */}
        <ToastContainer />
        <Toast status="success" title="Welcome" description="You're all set." />
      </main>
    </ScalablyUIProvider>
  );
}

2. Optional: Manual CSS Import

If you prefer to import CSS manually (e.g., for better control or SSR optimization), you can disable automatic injection:

// In your main.tsx, App.tsx, or index.tsx
import "@scalably/ui/styles";
import { ScalablyUIProvider } from "@scalably/ui";

export default function App() {
  return (
    <ScalablyUIProvider injectStyles={false}>
      {/* your app */}
    </ScalablyUIProvider>
  );
}

3. Portal Support

Styles automatically work in portaled components (modals, tooltips, popovers, etc.) because:

  • Styles are injected globally into document.head
  • CSS variables propagate to all elements
  • No parent selector dependencies
// Tooltips, modals, and other portaled components work automatically
<Tooltip content="This works in portals!" portal>
  <Button>Hover me</Button>
</Tooltip>

Note: Toasts in this library are intentionally declarative. Render a Toast inside a ToastContainer when you want it visible (e.g., based on component state). This avoids hidden globals and keeps UI state predictable. If you prefer an imperative API, you can wrap your own tiny helper around local state to toggle a Toast component.

4. React import guidance

If you reference the React namespace (e.g., React.useState, React.forwardRef, React.SVGProps) add an explicit import to avoid UMD global errors:

import * as React from "react";

Alternatively, import only what you use with the automatic JSX runtime:

import { useState, forwardRef } from "react";
import type { SVGProps } from "react";

Helper Functions

  • Date helpers: addMonths, clampDate, daysGrid, endOfMonth, formatDateLocalized, isSameDay, monthsForLocale, startOfMonth, toDateKey, weekdaysForLocale
  • Form helpers: fieldErrorToProps, zodErrorsToSummary and type FieldErrorLike
  • Utilities: cn (Tailwind-aware className helper), debounce, throttle, scopeClass for safely building sui-* class strings

Example Usage

import {
  AuthPrompt,
  BackToTop,
  Button,
  CheckboxGroup,
  DatePicker,
  FileUpload,
  Input,
  Pagination,
  RichTextEditor,
  Select,
  Toast,
  ToastContainer,
  ViewToggle,
} from '@scalably/ui';

// Button with variants
<Button variant="destructive">Delete</Button>;
<Button variant="outline">Cancel</Button>;
<Button loading>Loading...</Button>;

// Input with validation
<Input
  label="Email Address"
  type="email"
  placeholder="Enter your email"
  error="Please enter a valid email"
/>;

// Date picker
<DatePicker
  mode="single"
  placeholder="Select a date"
  onChange={(date) => console.log(date)}
/>;

// Toast notifications (declarative)
<ToastContainer>
  <Toast
    status="success"
    title="Success!"
    description="Your changes have been saved."
  />
</ToastContainer>;

// Rich text editor
<RichTextEditor
  value="<p>Start writing...</p>"
  onChange={(value) => console.log(value)}
  maxCharacters={5000}
/>;

// Marketing-style auth prompt card
<AuthPrompt
  title="Welcome back"
  description="Log in to manage your campaigns."
  primaryActionLabel="Log in"
  onPrimaryAction={() => console.log('login')}
/>;

// Toggle between list and grid views
<ViewToggle view="list" onViewChange={(v) => console.log(v)} />;

// Scroll-to-top helper
<BackToTop />;

🧩 Components & APIs Overview

This library exposes a set of composable, production-ready primitives. The full list of exports is available in src/index.ts, but the main groups are:

  • Form primitives: Form, FormField, FormErrorSummary, Input, SearchInput, QuantityInput, CheckBox, CheckBoxGroup, Radio, RadioGroup, Select, Switch, FileUpload, DateInput, DatePicker, TimePicker
  • Feedback & status: StatusBadge, Toast, ToastContainer, Skeleton, SkeletonText, Countdown
  • Layout & navigation: Tabs, TabsList, TabsTrigger, TabsContent, Pagination, BackToTop, ViewToggle, Divider
  • Content & rich text: RichTextEditor, RichTextViewer, Tooltip, AuthPrompt, LoadingScreen, WelcomeBackground
  • Media & brand: AvatarPlaceholder, Logo, logoAssets, defaultAssets, welcomeAssets (all inline React SVGs—no static paths required)
  • Icons: All icons from @/icons and @/icons/company are re-exported, e.g. SearchIcon, CalendarIcon, SuccessIcon, ErrorIcon, DiscordIcon, FacebookIcon, XIcon, YoutubeIcon, and more.

🖼️ Assets

All library assets are inline React SVG components (welcome background, logos, avatar placeholders). You can use them directly via the exported asset maps (welcomeAssets, logoAssets, defaultAssets) or override props (size, className, aria-label). If you prefer external URLs (e.g., CDN), pass your own backgroundImage, ellipsesData, or linesSrc to WelcomeBackground.

🎨 Styling

Style Isolation

All components use prefixed Tailwind classes (sui-*) to ensure complete style isolation:

// ✅ Correct - components are properly isolated
<Button>Isolated Button</Button>

// ✅ Your global styles won't break the components
<div className="p-4 bg-red-500">
  <Button>Isolated Button</Button>
</div>

Custom Styling

You can still customize components using the className prop:

<Button className="sui-w-full sui-mt-4">Full Width Button</Button>
<Card className="sui-max-w-md sui-mx-auto">Centered Card</Card>

🛠 Development

Prerequisites

  • Node.js 18+
  • npm or pnpm

Setup

# Clone the repository
git clone [email protected]:quangnle/scalably-components.git
cd scalably-components

# Install dependencies
npm install

# Start Storybook for development
npm run storybook

# Build the library
npm run build

# Run tests
npm test

Available Scripts

  • npm run dev - Start development build with watch mode
  • npm run build - Build the library for production
  • npm run build:css - Build CSS styles separately
  • npm run storybook - Start Storybook development server
  • npm run build-storybook - Build Storybook for production
  • npm run lint - Run ESLint
  • npm run lint:fix - Run ESLint with auto-fix
  • npm run type-check - Run TypeScript type checking
  • npm test - Run tests
  • npm run test:watch - Run tests in watch mode
  • npm run test:ci - Run tests with coverage
  • npm run verify - Run verification script
  • npm run clean - Clean build artifacts

📚 Documentation

Visit our Storybook documentation for:

  • Interactive component playground
  • Comprehensive prop documentation
  • Usage examples and best practices
  • Design system guidelines
  • Accessibility testing with axe-core
  • Design tokens and theming

You can access the latest published Storybook at: https://scalably.com/dev/storybook.

🎨 Design System

Colors

  • Primary: #36499B – Main brand color for primary actions (sui-bg-primary, sui-text-primary)
  • Secondary: #F2F6FC – Light background colors (sui-bg-secondary, sui-text-secondary)
  • Success: #22BC4D – Positive actions and success states (sui-bg-success, sui-text-success)
  • Warning: #FF7A00 – Caution and in-progress states (sui-bg-warning, sui-text-warning)
  • Info: #2772F0 – Informational content (sui-bg-info, sui-text-info)
  • Error: #EA3540 – Destructive actions and errors (sui-bg-error, sui-text-error)
  • Inactive: #777E90 – Inactive or completed states (sui-text-inactive, sui-border-inactive)
  • Disabled: #B2BBC7 – Disabled elements (sui-text-disabled, sui-border-disabled)

Typography

  • Font Family: Poppins (primary), Inter (fallback), system-ui
  • Font Sizes: 12px, 14px, 16px, 20px, 24px with 150% line-height and -2% letter-spacing
  • Font Weights: 400 (normal), 500 (medium), 600 (semibold), 700 (bold)

🔧 Configuration

Fonts

The library uses the Poppins font family (with Inter and system fonts as fallbacks) and loads Poppins via Google Fonts from within the bundled CSS. In most setups you do not need to add additional font imports, but if your build pipeline blocks remote @import rules, you can alternatively include Poppins yourself (e.g., via Google Fonts or @fontsource/poppins) to ensure consistent typography.

Tailwind Config

The library uses a custom Tailwind configuration with:

  • Prefix: sui- for all utility classes (provides style isolation)
  • Global Styles: Automatically injected via ScalablyUIProvider
  • CSS Variables: Design tokens available globally for theming
  • Custom Colors: Brand-specific color palette
  • Custom Shadows: Soft, medium, and strong shadow variants
  • Portal Support: Styles work in portaled components (modals, tooltips, etc.)

Build Configuration

  • Bundler: tsup for fast, modern builds
  • Formats: CommonJS and ES modules with proper exports
  • TypeScript: Full type definitions included
  • Tree Shaking: Optimized for minimal bundle size
  • CSS: Separate CSS build with Tailwind compilation
  • Source Maps: Generated for debugging
  • Minification: Production builds are minified

📦 Publishing

Version Management

We use semantic versioning (semver):

  • Major (1.0.0): Breaking changes
  • Minor (0.1.0): New features, backward compatible
  • Patch (0.0.1): Bug fixes, backward compatible

Publishing Process

# Build the library
npm run build

# Run tests
npm test

# Publish to registry
npm publish

Development Guidelines

  • Follow TypeScript best practices
  • Write comprehensive Storybook stories
  • Ensure accessibility compliance
  • Add tests for new components
  • Update documentation

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🆘 Support

  • Documentation: Storybook (run npm run storybook)
  • Issues: GitHub Issues
  • Discussions: GitHub Discussions

🧪 Testing

The library includes comprehensive testing setup:

  • Unit Tests: Vitest with React Testing Library
  • Accessibility: jest-axe for a11y testing
  • Coverage: Built-in coverage reporting
  • CI/CD: Automated testing pipeline

🔧 Dependencies

Peer Dependencies

  • React 18+
  • React DOM 18+

Key Dependencies

  • @floating-ui/react - Positioning for tooltips and popovers
  • class-variance-authority - Component variant management
  • date-fns - Date manipulation utilities
  • clsx - Conditional class names
  • tailwind-merge - Tailwind class merging
  • @tiptap/react & @tiptap/starter-kit - Rich text editor foundation
  • @tiptap/extension-* - Rich text extensions (character count, image, alignment, placeholder, YouTube, etc.)

Built with ❤️ by the Scalably team