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

@emporix/component-library

v1.4.0

Published

A React component library for Emporix projects

Readme

Emporix Component Library

A modern React component library built with TypeScript, Vite, and SCSS modules.

Features

  • 🚀 Modern Stack: Built with Vite, TypeScript, and React 18
  • 🎨 Styled Components: SCSS modules for component styling
  • 📚 Storybook: Interactive component documentation
  • 🧪 Testing: Comprehensive test suite with Vitest and React Testing Library
  • 📦 Library Build: Optimized for npm package distribution
  • 🔄 CI/CD: Automated testing and publishing pipeline
  • 🎨 CSS Variables: Global theming system with CSS custom properties

Quick Start

Installation

npm install @emporix/component-library

Usage

Important: Import the library styles in your app so component layout and appearance stay consistent. If you skip this step, components may be unstyled or layout may break.

Method 1: Import styles in your main CSS file (Recommended)

/* In your main CSS file (e.g., index.css, App.css) */
@import '@emporix/component-library/styles';
import { PrimaryButton } from '@emporix/component-library'

const MyComponent = () => {
  return (
    <PrimaryButton onClick={() => console.log('Clicked!')}>
      Click me
    </PrimaryButton>
  )
}

Method 2: Import styles in your main JavaScript/TypeScript file

import { PrimaryButton } from '@emporix/component-library'
import '@emporix/component-library/styles'

const MyComponent = () => {
  return (
    <PrimaryButton onClick={() => console.log('Clicked!')}>
      Click me
    </PrimaryButton>
  )
}

Method 3: Copy CSS file manually (Fallback)

If the above methods don't work, copy the CSS file from node_modules/@emporix/component-library/dist/style.css to your project and import it directly.

Components

PrimaryButton

A simple, focused button component for primary actions.

import { PrimaryButton } from '@emporix/component-library'

// Basic usage
<PrimaryButton>Click me</PrimaryButton>

// With disabled state
<PrimaryButton disabled>Disabled Button</PrimaryButton>

// With click handler
<PrimaryButton onClick={() => alert('Confirmed!')}>
  Confirm Action
</PrimaryButton>

Props

| Prop | Type | Default | Description | | ----------- | ---------- | ------- | -------------------------- | | children | ReactNode | - | Button content | | disabled | boolean | false | Whether button is disabled | | onClick | () => void | - | Click handler | | className | string | - | Additional CSS class | | data-testid | string | - | Test ID for testing |

InputText

A text input with optional label and tooltip. Hover and focus styles match the Dropdown component.

import { InputText } from '@emporix/component-library'

// With label and info tooltip
<InputText
  label="Id"
  tooltip="Unique identifier for this record"
  placeholder="Enter id"
/>

// Required field
<InputText label="Name" required placeholder="Enter name" />

// Disabled
<InputText label="Id" placeholder="Enter id" disabled />

Props

| Prop | Type | Default | Description | | ----------- | --------- | ------- | -------------------------------------------- | | label | ReactNode | - | Label text above the input | | tooltip | string | - | If set, shows info icon with this tooltip | | required | boolean | false | Shows asterisk on label | | inputId | string | - | id for the input (for label association) | | disabled | boolean | false | Whether the input is disabled | | className | string | - | Additional CSS class for the root | | data-testid | string | - | Test ID for root and input (suffix -input) |

All standard HTML input attributes (placeholder, value, onChange, etc.) are supported.

SelectButton

Choose single or multiple options using buttons. API inspired by PrimeReact SelectButton. Selected state uses project primary colors.

import { SelectButton } from '@emporix/component-library'

const options = [
  { label: 'Off', value: 'off' },
  { label: 'On', value: 'on' },
]

// Single selection
<SelectButton
  value={value}
  onChange={(e) => setValue(e.value)}
  options={options}
/>

// Multiple selection
<SelectButton
  value={selected}
  onChange={(e) => setSelected(e.value)}
  options={options}
  multiple
/>

Props

| Prop | Type | Default | Description | | -------------- | ------------------------ | ------- | --------------------------------------- | | value | unknown | - | Selected value (or array when multiple) | | onChange | (e: ChangeEvent) => void | - | Callback when selection changes | | options | T[] | - | Array of options | | optionLabel | string | "label" | Property name for option label | | optionValue | string | "value" | Property name for option value | | optionDisabled | string | - | Property name for disabled flag | | multiple | boolean | false | Allow multiple selection | | itemTemplate | (option) => ReactNode | - | Custom render for each option | | disabled | boolean | false | Disable the whole component | | invalid | boolean | false | Validation invalid state | | className | string | - | Additional CSS class | | data-testid | string | - | Test ID for root and option buttons |

Tabs

A flexible tabs component for organizing content into multiple panels.

import { Tabs, TabItem } from '@emporix/component-library'

const tabs: TabItem[] = [
  {
    id: 'tab1',
    label: 'First Tab',
    content: <div>First tab content</div>,
  },
  {
    id: 'tab2',
    label: 'Second Tab',
    content: <div>Second tab content</div>,
  },
]

// Basic usage
<Tabs
  tabs={tabs}
  activeTabId="tab1"
  onTabChange={(tabId) => setActiveTab(tabId)}
/>

// With custom styling and test ID
<Tabs
  tabs={tabs}
  activeTabId="tab1"
  onTabChange={(tabId) => setActiveTab(tabId)}
  className="custom-tabs"
  data-testid="my-tabs"
/>

Props

| Prop | Type | Default | Description | | ----------- | ----------------------- | ------- | ------------------------------ | | tabs | TabItem[] | - | Array of tab items | | activeTabId | string | - | ID of the currently active tab | | onTabChange | (tabId: string) => void | - | Callback when tab is changed | | className | string | - | Additional CSS class | | data-testid | string | - | Test ID for testing |

TabItem Interface

| Prop | Type | Description | | ------- | --------- | ------------------------------ | | id | string | Unique identifier for the tab | | label | string | Display label for the tab | | content | ReactNode | Content to display when active |

Theming with CSS Variables

The component library uses CSS variables for easy theming. You can customize the appearance by overriding these variables:

:root {
  --color-primary: #your-primary-color;
  --color-primary-hover: #your-primary-hover-color;
  --border-radius-md: 0.5rem;
  --font-size-lg: 1.2rem;
  /* ... other variables */
}

Available CSS Variables

The component library provides a minimal set of CSS variables that are actually used in the codebase. These variables are primarily used for the showcase page styling and can be customized for theming.

Colors

--color-primary: #007bff;
--color-primary-hover: #0056b3;
--color-dark: #343a40;

Text Colors

--color-text-primary: #212529;
--color-text-secondary: #6c757d;

Background Colors

--color-bg-primary: #ffffff;
--color-bg-secondary: #f8f9fa;

Border Colors

--color-border-light: #e9ecef;

Focus Ring

Reusable focus outline for inputs, dropdowns, SelectButton, etc. Override to change focus appearance globally.

--focus-ring-box-shadow: 0 0 0 2px rgba(38, 101, 183, 0.35);

Spacing

--spacing-sm: 0.5rem; /* 8px */
--spacing-md: 1rem; /* 16px */
--spacing-lg: 1.5rem; /* 24px */
--spacing-xl: 3rem; /* 48px */

Border Radius

--border-radius-sm: 0.25rem; /* 4px */
--border-radius-md: 0.375rem; /* 6px */
--border-radius-lg: 0.5rem; /* 8px */

Typography

Font Sizes:

--font-size-sm: 0.875rem; /* 14px */
--font-size-base: 0.875rem; /* 14px */
--font-size-lg: 1.125rem; /* 18px */

Font Weights:

--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;

Line Height:

--line-height-base: 1rem;

Theming Examples

Basic Theming

:root {
  --color-primary: #your-brand-color;
  --color-primary-hover: #your-brand-hover-color;
  --border-radius-md: 0.5rem;
  --font-size-lg: 1.2rem;
}

Dark Theme

:root {
  --color-bg-primary: #1a1a1a;
  --color-bg-secondary: #2d2d2d;
  --color-text-primary: #ffffff;
  --color-text-secondary: #cccccc;
  --color-border-light: #404040;
}

Custom Component Styling

.my-custom-component {
  padding: var(--spacing-md);
  border-radius: var(--border-radius-lg);
  background-color: var(--color-bg-primary);
  color: var(--color-text-primary);
  border: 1px solid var(--color-border-light);
}

Development

Prerequisites

  • Node.js 18+
  • npm or yarn

Setup

# Clone the repository
git clone <repository-url>
cd component-library

# Install dependencies
npm install

# Start development server
npm run dev

# Start Storybook
npm run storybook

Available Scripts

  • npm run dev - Start development server with showcase
  • npm run build - Build the development version
  • npm run build:lib - Build the library for distribution
  • npm run test - Run tests
  • npm run test:ui - Run tests with UI
  • npm run test:coverage - Run tests with coverage
  • npm run storybook - Start Storybook
  • npm run build-storybook - Build Storybook
  • npm run lint - Run ESLint
  • npm run lint:fix - Fix ESLint issues
  • npm run type-check - Run TypeScript type checking
  • npm run format - Format code with Prettier
  • npm run format:check - Check code formatting

Testing

The library includes comprehensive tests using Vitest and React Testing Library.

# Run all tests
npm test

# Run tests with coverage
npm run test:coverage

# Run tests with UI
npm run test:ui

Storybook

Interactive component documentation is available in Storybook.

# Start Storybook
npm run storybook

# Build Storybook
npm run build-storybook

Building for Distribution

The library is built using Vite with optimized settings for npm distribution.

# Build the library
npm run build:lib

The build output includes:

  • ES modules (index.es.js)
  • UMD bundle (index.umd.js)
  • TypeScript declarations (index.d.ts)
  • CSS styles (styles.css)

Code Formatting

This project uses Prettier for consistent code formatting. The configuration is defined in .prettierrc.

# Format all files
npm run format

# Check if files are formatted correctly
npm run format:check

The project also includes pre-commit hooks that automatically format staged files before commits.

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Development Guidelines

  • Follow TypeScript best practices
  • Write tests for new components
  • Add Storybook stories for components
  • Follow the existing code style
  • Update documentation as needed
  • Use arrow functions for React components (enforced by ESLint)
  • Avoid using React.FC type annotation (redundant with modern TypeScript)
  • Use CSS variables for all styling values
  • Follow the established naming conventions for CSS classes

Troubleshooting

Import Issues

If you encounter import errors like "Failed to resolve entry for package", ensure:

  1. The package is properly installed: npm install @emporix/component-library
  2. You're using the correct import syntax:
    import { PrimaryButton } from '@emporix/component-library'
    import '@emporix/component-library/styles'
  3. Your bundler supports ES modules and the package.json exports field

Styling Issues

If the PrimaryButton component appears unstyled or you get "styles not found" errors:

  1. Try Method 1 (Recommended): Import styles in your main CSS file:

    @import '@emporix/component-library/styles';
  2. Try Method 2: Import styles in your main JavaScript/TypeScript file:

    import '@emporix/component-library/styles'
  3. If both methods fail: Copy the CSS file manually:

    • Copy node_modules/@emporix/component-library/dist/style.css to your project
    • Import it in your main CSS file: @import './path/to/style.css';
  4. Check your bundler configuration: Ensure your bundler (Vite, Webpack, etc.) is configured to handle CSS imports from node_modules

  5. Verify the CSS classes: The component uses SCSS modules with hashed class names (e.g., _primaryButton_1d0ha_1, _primaryButtonDisabled_1d0ha_53) and CSS variables for theming

TypeScript Issues

If TypeScript can't find types, make sure:

  1. The @types/react package is installed
  2. Your tsconfig.json includes the library in node_modules

Bundler-Specific Notes

Vite

All methods should work with Vite. Method 1 (CSS import) is recommended.

Webpack

Method 1 and Method 2 should work. If you encounter issues, try Method 3.

Create React App

Method 1 and Method 2 should work. If you encounter issues, try Method 3.

Next.js

Method 1 (CSS import) is recommended. Import the CSS in your _app.tsx or _app.js file.

License

MIT License - see LICENSE file for details.

Support

For support and questions, please open an issue in the repository.