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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@pmgpathum/sampui

v0.1.6

Published

Production-ready UI component library for Next.js applications

Readme

SampUI Design System

A comprehensive, production-ready UI component library for Next.js applications, built with Subframe, React, TypeScript, and Tailwind CSS.

🚀 Features

  • 50+ Pre-built Components: Accessible, customizable React components synced from Subframe
  • Design Tokens: Centralized design tokens for colors, typography, spacing, shadows, and animations
  • Tailwind Integration: Full Tailwind CSS support with custom configuration
  • TypeScript: Complete type safety across all components and tokens
  • Tree-shakeable: Optimized bundle sizes with ESM and CJS support
  • Next.js Ready: Built for Next.js 14+ (supports Next.js 14, 15, and 16) with App Router support
  • Server Components: Proper separation of server-safe tokens and client components

📦 Installation

Private Registry Setup

SampUI is published to a private npm registry. To install, you need to configure npm authentication:

  1. Set up .npmrc in your project root:
@pmgpathum:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
  1. Set your NPM_TOKEN environment variable:
export NPM_TOKEN=your_npm_token_here

Or add it to your .env file (make sure .env is in .gitignore).

  1. Install the package:
npm install @pmgpathum/sampui
# or
yarn add @pmgpathum/sampui
# or
pnpm add @pmgpathum/sampui

Requirements

  • Node.js >= 18.0.0
  • npm >= 9.0.0
  • React >= 18.0.0
  • Next.js >= 14.0.0 (supports 14.x, 15.x, and 16.x)
  • Tailwind CSS >= 3.4.0

🎯 Quick Start

1. Install Dependencies

npm install @pmgpathum/sampui

2. Load Public Sans Font

SampUI components use the Public Sans font family. You need to load it in your application:

Option A: Using Next.js Font Optimization (Recommended)

// app/layout.tsx (App Router)
import { Public_Sans } from 'next/font/google';
import '@pmgpathum/sampui/styles';

const publicSans = Public_Sans({
  subsets: ['latin'],
  variable: '--font-public-sans',
  display: 'swap',
});

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

Option B: Using HTML Link Tag

Add this to your app/layout.tsx or pages/_app.tsx:

// app/layout.tsx (App Router)
import '@pmgpathum/sampui/styles';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <link
          href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
          rel="stylesheet"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Or for Pages Router:

// pages/_app.tsx
import '@pmgpathum/sampui/styles';
import Head from 'next/head';

export default function App({ Component, pageProps }) {
  return (
    <>
      <Head>
        <link
          href="https://fonts.googleapis.com/css2?family=Public+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
          rel="stylesheet"
        />
      </Head>
      <Component {...pageProps} />
    </>
  );
}

Important: Without loading Public Sans font, components will fall back to system fonts and typography weights may appear incorrect.

3. Configure Tailwind CSS

Extend your tailwind.config.js with the SampUI Tailwind configuration:

// tailwind.config.js
import sampuiConfig from '@pmgpathum/sampui/tailwind-config';

export default {
  ...sampuiConfig,
  content: [
    ...sampuiConfig.content,
    './src/**/*.{js,ts,jsx,tsx,mdx}',
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
  ],
};

Or using CommonJS:

// tailwind.config.js
const sampuiConfig = require('@pmgpathum/sampui/tailwind-config');

module.exports = {
  ...sampuiConfig,
  content: [
    ...sampuiConfig.content,
    './src/**/*.{js,ts,jsx,tsx,mdx}',
    './app/**/*.{js,ts,jsx,tsx,mdx}',
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
  ],
};

Important: The SampUI Tailwind config includes all design tokens (colors including brand colors, typography, spacing, shadows, etc.) needed for components to render correctly.

4. Use Components

Server Components (Recommended)

// app/page.tsx
import { Button, Card, TextField } from '@pmgpathum/sampui/client';

export default function HomePage() {
  return (
    <Card>
      <TextField placeholder="Enter your name" />
      <Button variant="brand-primary">Submit</Button>
    </Card>
  );
}

Client Components

// components/MyComponent.tsx
'use client';

import { Button, Dialog, Toast } from '@pmgpathum/sampui/client';

export function MyComponent() {
  return (
    <>
      <Button onClick={() => alert('Clicked!')}>Click me</Button>
      <Dialog>...</Dialog>
    </>
  );
}

📚 Component Usage Examples

Buttons

import { Button, IconButton, LinkButton } from '@pmgpathum/sampui/client';

// Primary button
<Button variant="brand-primary" size="large">
  Primary Action
</Button>

// Button with icon
<Button 
  variant="brand-secondary" 
  icon={<Icon name="Plus" />}
  iconRight={<Icon name="ArrowRight" />}
>
  Add Item
</Button>

// Loading state
<Button loading={isLoading}>Submit</Button>

// Icon button
<IconButton icon={<Icon name="Settings" />} />

Form Inputs

import { TextField, TextArea, Select, Checkbox, Switch } from '@pmgpathum/sampui/client';

// Text field
<TextField
  label="Email Address"
  placeholder="Enter your email"
  helpText="We'll never share your email"
  error={hasError}
  icon={<Icon name="Mail" />}
/>

// Text area
<TextArea
  label="Description"
  placeholder="Enter description"
  rows={4}
/>

// Select dropdown
<Select
  label="Country"
  options={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
  ]}
/>

// Checkbox
<Checkbox label="I agree to the terms" />

// Switch
<Switch label="Enable notifications" />

Feedback Components

import { Alert, Toast, Loader, Progress } from '@pmgpathum/sampui/client';

// Alert
<Alert variant="success" title="Success!">
  Your changes have been saved.
</Alert>

// Toast (requires ToastProvider)
<Toast.Provider>
  <Toast.Trigger>Show Toast</Toast.Trigger>
</Toast.Provider>

// Loader
<Loader size="large" />

// Progress bar
<Progress value={60} max={100} />

Overlays & Modals

import { Dialog, Drawer, Tooltip, DropdownMenu } from '@pmgpathum/sampui/client';

// Dialog
<Dialog.Root>
  <Dialog.Trigger>Open Dialog</Dialog.Trigger>
  <Dialog.Content>
    <Dialog.Title>Confirm Action</Dialog.Title>
    <Dialog.Description>Are you sure?</Dialog.Description>
    <Dialog.Footer>
      <Button variant="neutral-secondary">Cancel</Button>
      <Button variant="brand-primary">Confirm</Button>
    </Dialog.Footer>
  </Dialog.Content>
</Dialog.Root>

// Drawer
<Drawer.Root>
  <Drawer.Trigger>Open Drawer</Drawer.Trigger>
  <Drawer.Content>...</Drawer.Content>
</Drawer.Root>

// Tooltip
<Tooltip content="This is a tooltip">
  <Button>Hover me</Button>
</Tooltip>

Data Display

import { Table, Avatar, Badge, Card } from '@pmgpathum/sampui/client';

// Table
<Table.Root>
  <Table.Header>
    <Table.Row>
      <Table.HeaderCell>Name</Table.HeaderCell>
      <Table.HeaderCell>Status</Table.HeaderCell>
    </Table.Row>
  </Table.Header>
  <Table.Body>
    <Table.Row>
      <Table.Cell>John Doe</Table.Cell>
      <Table.Cell>
        <Badge variant="success">Active</Badge>
      </Table.Cell>
    </Table.Row>
  </Table.Body>
</Table.Root>

// Avatar
<Avatar src="/avatar.jpg" alt="User" size="large" />

// Badge
<Badge variant="success">Success</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="destructive">Error</Badge>

Navigation

import { Tabs, Breadcrumbs, Stepper } from '@pmgpathum/sampui/client';

// Tabs
<Tabs.Root defaultValue="tab1">
  <Tabs.List>
    <Tabs.Trigger value="tab1">Tab 1</Tabs.Trigger>
    <Tabs.Trigger value="tab2">Tab 2</Tabs.Trigger>
  </Tabs.List>
  <Tabs.Content value="tab1">Content 1</Tabs.Content>
  <Tabs.Content value="tab2">Content 2</Tabs.Content>
</Tabs.Root>

// Breadcrumbs
<Breadcrumbs>
  <Breadcrumbs.Item href="/">Home</Breadcrumbs.Item>
  <Breadcrumbs.Item href="/products">Products</Breadcrumbs.Item>
  <Breadcrumbs.Item>Current Page</Breadcrumbs.Item>
</Breadcrumbs>

// Stepper
<Stepper.Root currentStep={2}>
  <Stepper.Step>Step 1</Stepper.Step>
  <Stepper.Step>Step 2</Stepper.Step>
  <Stepper.Step>Step 3</Stepper.Step>
</Stepper.Root>

🎨 Theming & Customization

Design Tokens

SampUI provides a comprehensive set of design tokens that you can use directly:

import { colors, typography, spacing, shadows, tokens } from '@pmgpathum/sampui';

// Use tokens programmatically
const primaryColor = colors.primary[500];
const fontSize = typography.fontSize.lg;
const padding = spacing[4];

// Or use the unified tokens object
const { colors, typography, spacing } = tokens;

Customizing Colors

Extend the color tokens in your Tailwind config:

// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        ...require('@pmgpathum/sampui/tokens').colors,
        // Add your custom colors
        brand: {
          primary: '#your-color',
        },
      },
    },
  },
};

CSS Variables

SampUI uses CSS variables for theming. You can override them:

/* app/globals.css */
:root {
  --color-primary-500: #your-color;
  --spacing-4: 1.5rem;
  /* ... other overrides */
}

Component Variants

Most components support multiple variants:

  • Buttons: brand-primary, brand-secondary, brand-tertiary, neutral-primary, neutral-secondary, neutral-tertiary, destructive-primary, destructive-secondary, destructive-tertiary, inverse
  • Sizes: large, medium, small
  • States: default, hover, active, disabled, loading

🎯 Design Token Reference

Colors

import { colors } from '@pmgpathum/sampui';

// Primary colors
colors.primary[50]   // Lightest
colors.primary[500] // Base
colors.primary[900] // Darkest

// Semantic colors
colors.success[500]
colors.warning[500]
colors.destructive[500]
colors.neutral[500]

Typography

import { typography } from '@pmgpathum/sampui';

typography.fontFamily.sans
typography.fontSize.xs    // 12px
typography.fontSize.sm    // 14px
typography.fontSize.base  // 16px
typography.fontSize.lg    // 18px
typography.fontSize.xl    // 20px
typography.fontWeight.normal
typography.fontWeight.medium
typography.fontWeight.semibold
typography.fontWeight.bold

Spacing

import { spacing } from '@pmgpathum/sampui';

spacing[0]   // 0px
spacing[1]   // 4px
spacing[2]   // 8px
spacing[4]   // 16px
spacing[8]   // 32px
spacing[16]  // 64px

Shadows

import { shadows } from '@pmgpathum/sampui';

shadows.sm
shadows.md
shadows.lg
shadows.xl

Breakpoints

import { breakpoints } from '@pmgpathum/sampui';

breakpoints.sm   // 640px
breakpoints.md   // 768px
breakpoints.lg   // 1024px
breakpoints.xl   // 1280px
breakpoints['2xl'] // 1536px

📘 TypeScript Usage

SampUI is built with TypeScript and provides full type safety:

import { Button } from '@pmgpathum/sampui/client';
import type { ButtonProps } from '@pmgpathum/sampui/client';

// Type-safe props
const buttonProps: ButtonProps = {
  variant: 'brand-primary', // Autocomplete works!
  size: 'large',
  disabled: false,
};

<Button {...buttonProps} />

Type Definitions

All component props are exported with TypeScript types:

import type {
  ButtonProps,
  TextFieldProps,
  DialogProps,
  // ... all component types
} from '@pmgpathum/sampui/client';

⚡ Next.js App Router Integration

SampUI is optimized for Next.js App Router with proper server/client component separation:

Server Components

Use tokens and utilities in Server Components:

// app/page.tsx (Server Component)
import { colors, spacing } from '@pmgpathum/sampui';

export default function ServerPage() {
  return (
    <div style={{ color: colors.primary[500] }}>
      Server Component
    </div>
  );
}

Client Components

Import components from @pmgpathum/sampui/client:

// components/ClientComponent.tsx
'use client';

import { Button, Dialog } from '@pmgpathum/sampui/client';

export function ClientComponent() {
  return <Button>Click me</Button>;
}

Layout Integration

// app/layout.tsx
import '@pmgpathum/sampui/styles';
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'] });

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={inter.className}>
        {children}
      </body>
    </html>
  );
}

Route Groups

// app/(marketing)/layout.tsx
import { DefaultPageLayout } from '@pmgpathum/sampui/client';

export default function MarketingLayout({ children }) {
  return <DefaultPageLayout>{children}</DefaultPageLayout>;
}

🔧 Troubleshooting

Styles Not Loading

Problem: Components render but styles are missing.

Solution:

  1. Ensure you've imported the styles: import '@pmgpathum/sampui/styles';
  2. Check that Tailwind is configured correctly
  3. Verify the content paths in tailwind.config.js include the package:
    content: [
      './node_modules/@pmgpathum/sampui/dist/**/*.{js,mjs}',
    ]

"use client" Directive Errors

Problem: Error about missing 'use client' directive.

Solution:

  • Import components from @pmgpathum/sampui/client instead of @pmgpathum/sampui
  • Or add 'use client'; at the top of your component file

TypeScript Errors

Problem: Type errors when importing components.

Solution:

  1. Ensure TypeScript version >= 5.3.0
  2. Check tsconfig.json includes the package:
    {
      "compilerOptions": {
        "moduleResolution": "bundler",
        "resolveJsonModule": true
      }
    }

Build Errors

Problem: Build fails with module resolution errors.

Solution:

  1. Clear .next cache: rm -rf .next
  2. Reinstall dependencies: rm -rf node_modules && npm install
  3. Ensure Node.js version >= 18.0.0

Private Registry Authentication

Problem: Cannot install package from private registry.

Solution:

  1. Verify .npmrc is configured correctly
  2. Check NPM_TOKEN environment variable is set
  3. Ensure token has access to @sampath scope
  4. Try: npm config get @sampath:registry

Component Not Rendering

Problem: Component imports but doesn't render.

Solution:

  1. Check browser console for errors
  2. Verify styles are imported
  3. Ensure component is used in a Client Component
  4. Check component props are correct (use TypeScript for validation)

Tailwind Classes Not Working

Problem: Custom Tailwind classes don't apply.

Solution:

  1. Verify content paths in tailwind.config.js
  2. Restart your dev server after config changes
  3. Check for CSS conflicts or specificity issues

📖 Additional Resources

🛠️ Development

See CONTRIBUTING.md for development setup and guidelines.

📝 Versioning

This project uses Changesets for version management.

📄 License

UNLICENSED - Private package for Sampath Bank use only.

🆘 Support

For issues and support, please contact the design system team or open an issue in the internal repository.