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

primolab-ui-kit

v1.1.4

Published

Primo UI Kit - A comprehensive React component library with Tailwind CSS

Readme

Primo UI Kit

A comprehensive React component library built with Tailwind CSS, featuring customizable components with a consistent design system.

Installation

npm install primolab-ui-kit

Setup

Import the styles in your main application file:

import 'primolab-ui-kit/styles'

Make sure you have React 18+ or 19+ installed as a peer dependency.

Components

Button

A versatile button component with multiple variants and sizes.

import { Button } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      <Button variant="primary" size="md" onClick={() => alert('Clicked!')}>
        Click Me
      </Button>
      <Button variant="danger" size="sm">Delete</Button>
      <Button variant="outline" fullWidth>Full Width Button</Button>
    </div>
  )
}

Props:

  • variant: 'primary' | 'secondary' | 'danger' | 'success' | 'warning' | 'info' | 'outline' | 'ghost'
  • size: 'xs' | 'sm' | 'md' | 'lg'
  • disabled: boolean
  • fullWidth: boolean
  • onClick: function

Modal

A customizable modal dialog with backdrop and animations.

import { Modal, Button } from 'primolab-ui-kit'
import { useState } from 'react'

function App() {
  const [isOpen, setIsOpen] = useState(false)

  return (
    <>
      <Button onClick={() => setIsOpen(true)}>Open Modal</Button>
      <Modal
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        title="My Modal"
        size="md"
        footer={
          <Button variant="primary" onClick={() => setIsOpen(false)}>
            Close
          </Button>
        }
      >
        <p>This is the modal content</p>
      </Modal>
    </>
  )
}

Props:

  • isOpen: boolean (required)
  • onClose: function (required)
  • title: string
  • size: 'sm' | 'md' | 'lg' | 'xl' | 'full'
  • showCloseButton: boolean
  • closeOnBackdropClick: boolean
  • footer: ReactNode

Bootbox

A dialog component for displaying alerts, confirmations, and custom content with different visual variants.

import { Bootbox, Button } from 'primolab-ui-kit'
import { useState } from 'react'

function App() {
  const [showAlert, setShowAlert] = useState(false)
  const [showConfirm, setShowConfirm] = useState(false)
  const [showCustom, setShowCustom] = useState(false)

  // Alert type - Simple message with OK button
  const handleAlertExample = () => {
    setShowAlert(true)
  }

  // Confirm type - Yes/No confirmation
  const handleConfirmExample = () => {
    setShowConfirm(true)
  }

  // Custom type - Custom content with actions
  const handleCustomExample = () => {
    setShowCustom(true)
  }

  return (
    <>
      <Button onClick={handleAlertExample}>Show Alert</Button>
      <Button onClick={handleConfirmExample}>Show Confirm</Button>
      <Button onClick={handleCustomExample}>Show Custom</Button>

      {/* Alert Type */}
      <Bootbox
        isOpen={showAlert}
        onClose={() => setShowAlert(false)}
        type="alert"
        variant="danger"
        title="Azione non permessa"
        message="Non è possibile spostare un appuntamento nel passato."
        closeText="OK"
      />

      {/* Confirm Type */}
      <Bootbox
        isOpen={showConfirm}
        onClose={() => setShowConfirm(false)}
        onConfirm={() => {
          console.log('Confirmed!')
          setShowConfirm(false)
        }}
        type="confirm"
        variant="primary"
        title="Conferma"
        message="Confermi la modifica dell'appuntamento?"
        confirmText="Conferma"
        cancelText="Annulla"
      />

      {/* Custom Type */}
      <Bootbox
        isOpen={showCustom}
        onClose={() => setShowCustom(false)}
        onConfirm={() => {
          console.log('Custom action confirmed')
          setShowCustom(false)
        }}
        type="custom"
        variant="primary"
        title="Modifica appuntamento"
        confirmText="Conferma"
        cancelText="Annulla"
      >
        <div>
          <h3 className="text-lg font-semibold mb-4">Conferma modifica appuntamento</h3>
          <label className="block mb-2 text-sm font-medium">
            Seleziona il motivo della modifica:
          </label>
          <select className="w-full p-2 border rounded">
            <option>Medico sbagliato</option>
            <option>Orario non disponibile</option>
            <option>Richiesta paziente</option>
          </select>
        </div>
      </Bootbox>
    </>
  )
}

Props:

  • isOpen: boolean (required) - Controls bootbox visibility
  • onClose: function (required) - Called when closing the bootbox
  • onConfirm: function - Called when confirm button is clicked (for confirm/custom types)
  • type: 'alert' | 'confirm' | 'custom' - Type of bootbox
    • alert: Shows title, message, and single OK button
    • confirm: Shows title, message, Cancel and Confirm buttons
    • custom: Shows title, custom content, Cancel and Confirm buttons
  • variant: 'primary' | 'warning' | 'info' | 'danger' - Visual style variant
    • primary: Violet header (#9985B5)
    • warning: Yellow header (#D4A017)
    • info: Light blue header (#5B9BD5)
    • danger: Red header (#D9534F)
  • title: string - Bootbox title displayed in colored header
  • message: string - Message to display (for alert/confirm types)
  • children: ReactNode - Custom content (for custom type)
  • confirmText: string - Text for confirm button (default: 'Conferma')
  • cancelText: string - Text for cancel button (default: 'Annulla')
  • closeText: string - Text for close button in alert type (default: 'OK')
  • closeOnBackdropClick: boolean - Allow closing by clicking backdrop (default: false)
  • closeOnEscape: boolean - Allow closing by pressing ESC key (default: false)

Input

Form input component with label, validation, and helper text.

import { Input } from 'primolab-ui-kit'

function App() {
  const [value, setValue] = useState('')

  return (
    <Input
      label="Email"
      type="email"
      placeholder="Enter your email"
      value={value}
      onChange={(e) => setValue(e.target.value)}
      required
      helperText="We'll never share your email"
    />
  )
}

Props:

  • label: string
  • type: string
  • value: string
  • onChange: function
  • error: string
  • helperText: string
  • required: boolean
  • disabled: boolean
  • fullWidth: boolean
  • size: 'sm' | 'md' | 'lg'

Select

Dropdown select component with options.

import { Select } from 'primolab-ui-kit'

function App() {
  const options = [
    { value: '1', label: 'Option 1' },
    { value: '2', label: 'Option 2' },
    { value: '3', label: 'Option 3' }
  ]

  return (
    <Select
      label="Choose an option"
      options={options}
      value={selectedValue}
      onChange={(e) => setSelectedValue(e.target.value)}
      placeholder="Select..."
    />
  )
}

TextArea

Multi-line text input component.

import { TextArea } from 'primolab-ui-kit'

function App() {
  return (
    <TextArea
      label="Description"
      rows={4}
      placeholder="Enter description"
      value={description}
      onChange={(e) => setDescription(e.target.value)}
    />
  )
}

Table

Data table component with customizable columns and rows.

import { Table } from 'primolab-ui-kit'

function App() {
  const columns = [
    { header: 'Name', align: 'left' },
    { header: 'Email', align: 'left' },
    { header: 'Status', align: 'center' }
  ]

  const data = [
    { id: 1, name: 'John Doe', email: '[email protected]', status: 'Active' },
    { id: 2, name: 'Jane Smith', email: '[email protected]', status: 'Inactive' }
  ]

  return (
    <Table
      columns={columns}
      data={data}
      renderRow={(item) => (
        <>
          <td className="px-4 py-3">{item.name}</td>
          <td className="px-4 py-3">{item.email}</td>
          <td className="px-4 py-3 text-center">{item.status}</td>
        </>
      )}
      hoverable
      striped
    />
  )
}

Card

Container component for grouping content.

import { Card } from 'primolab-ui-kit'

function App() {
  return (
    <Card
      title="Card Title"
      subtitle="Card subtitle"
      hoverable
      footer={<button>Action</button>}
    >
      <p>Card content goes here</p>
    </Card>
  )
}

Badge

Small status or label indicator.

import { Badge } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      <Badge variant="success">Active</Badge>
      <Badge variant="danger" rounded>Error</Badge>
      <Badge variant="warning" size="sm">Pending</Badge>
    </div>
  )
}

Alert

Alert messages for notifications and feedback.

import { Alert } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      <Alert variant="success" title="Success!">
        Your action was completed successfully.
      </Alert>
      <Alert variant="danger" onClose={() => console.log('Closed')}>
        An error occurred.
      </Alert>
    </div>
  )
}

Spinner

Loading spinner component.

import { Spinner } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      <Spinner size="md" color="primary" />
      <Spinner size="lg" color="success" />
    </div>
  )
}

Skeleton

Loading placeholder component.

import { Skeleton } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      <Skeleton variant="title" />
      <Skeleton variant="text" count={3} />
      <Skeleton variant="card" />
    </div>
  )
}

SelectSearchable

Advanced select component with search functionality and multi-select support.

import { SelectSearchable } from 'primolab-ui-kit'
import { useState } from 'react'

function App() {
  const [value, setValue] = useState('')
  const [multiValue, setMultiValue] = useState([])

  const options = [
    { value: '1', label: 'Option 1' },
    { value: '2', label: 'Option 2' },
    { value: '3', label: 'Option 3' },
    { value: '4', label: 'Option 4', disabled: true }
  ]

  return (
    <div>
      {/* Single Select */}
      <SelectSearchable
        label="Choose an option"
        options={options}
        value={value}
        onChange={(e) => setValue(e.target.value)}
        placeholder="Search or select..."
        searchPlaceholder="Type to search..."
      />

      {/* Multi Select */}
      <SelectSearchable
        label="Choose multiple options"
        options={options}
        value={multiValue}
        onChange={(e) => setMultiValue(e.target.value)}
        multiple
        placeholder="Select multiple options"
      />
    </div>
  )
}

Props:

  • label: string
  • options: SelectOption[]
  • value: string | string[]
  • onChange: function
  • error: string
  • helperText: string
  • disabled: boolean
  • required: boolean
  • fullWidth: boolean
  • placeholder: string
  • size: 'sm' | 'md' | 'lg'
  • searchPlaceholder: string
  • noResultsText: string
  • multiple: boolean

Loader

Flexible loading component that can display either a spinner or skeleton with different layout variants.

import { Loader } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      {/* Spinner variants */}
      <Loader type="spinner" variant="inline" text="Loading..." />
      <Loader type="spinner" variant="block" size="lg" />

      {/* Overlay loader */}
      <div className="relative h-64">
        <Loader type="spinner" variant="overlay" text="Loading data..." />
      </div>

      {/* Skeleton loader */}
      <Loader
        type="skeleton"
        skeletonProps={{ variant: 'card', count: 3 }}
      />
    </div>
  )
}

Props:

  • type: 'spinner' | 'skeleton'
  • variant: 'inline' | 'overlay' | 'block'
  • size: 'sm' | 'md' | 'lg' | 'xl'
  • color: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'white'
  • text: string
  • skeletonProps: SkeletonProps
  • className: string

Tooltip

Customizable tooltip component with multiple positions and variants.

import { Tooltip } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      <Tooltip
        content="This is a helpful tooltip"
        position="top"
        variant="primary"
      >
        <button>Hover me</button>
      </Tooltip>

      <Tooltip
        title="Warning"
        content="This action cannot be undone"
        position="right"
        variant="warning"
      >
        <button>Delete</button>
      </Tooltip>
    </div>
  )
}

Props:

  • children: ReactNode (required)
  • content: ReactNode (required)
  • variant: 'primary' | 'warning' | 'danger'
  • title: string
  • position: 'top' | 'bottom' | 'left' | 'right'
  • className: string

Accordion

Expandable/collapsible content component that can be used standalone or as table rows.

import { Accordion } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      {/* Standalone accordion */}
      <Accordion
        expandedContent={
          <div>
            <p>This is the expanded content</p>
          </div>
        }
        defaultExpanded={false}
        onToggle={(isExpanded) => console.log('Expanded:', isExpanded)}
      >
        <h3>Click to expand</h3>
      </Accordion>

      {/* Table row accordion */}
      <table>
        <tbody>
          <Accordion
            asTableRow
            expandedContent={
              <div>Additional row details</div>
            }
          >
            <td>Column 1</td>
            <td>Column 2</td>
          </Accordion>
        </tbody>
      </table>
    </div>
  )
}

Props:

  • children: ReactNode (required)
  • expandedContent: ReactNode (required)
  • defaultExpanded: boolean
  • asTableRow: boolean
  • className: string
  • arrowClassName: string
  • contentClassName: string
  • onToggle: function

Checkbox

Checkbox input component with label and validation.

import { Checkbox } from 'primolab-ui-kit'
import { useState } from 'react'

function App() {
  const [checked, setChecked] = useState(false)

  return (
    <Checkbox
      label="I agree to the terms and conditions"
      checked={checked}
      onChange={(e) => setChecked(e.target.checked)}
      required
      helperText="You must accept to continue"
    />
  )
}

Props:

  • label: string
  • checked: boolean
  • onChange: function
  • disabled: boolean
  • error: boolean | string
  • helperText: string
  • required: boolean
  • className: string

Toggle

Toggle switch component for boolean states.

import { Toggle } from 'primolab-ui-kit'
import { useState } from 'react'

function App() {
  const [enabled, setEnabled] = useState(false)

  return (
    <Toggle
      label="Enable notifications"
      checked={enabled}
      onChange={setEnabled}
      helperText="Receive email notifications"
    />
  )
}

Props:

  • checked: boolean
  • onChange: function
  • disabled: boolean
  • label: string
  • error: string
  • helperText: string
  • required: boolean
  • className: string

DateTimePicker

Date and time picker input component.

import { DateTimePicker } from 'primolab-ui-kit'
import { useState } from 'react'

function App() {
  const [date, setDate] = useState('')
  const [datetime, setDatetime] = useState('')

  return (
    <div>
      {/* Date only */}
      <DateTimePicker
        label="Select date"
        value={date}
        onChange={(e) => setDate(e.target.value)}
        required
      />

      {/* Date and time */}
      <DateTimePicker
        label="Select date and time"
        value={datetime}
        onChange={(e) => setDatetime(e.target.value)}
        showTime
        fullWidth
      />
    </div>
  )
}

Props:

  • label: string
  • value: string
  • onChange: function
  • error: string
  • helperText: string
  • disabled: boolean
  • required: boolean
  • fullWidth: boolean
  • size: 'sm' | 'md' | 'lg'
  • showTime: boolean
  • className: string

Toast

Toast notification component with auto-dismiss and customizable position.

import { Toast } from 'primolab-ui-kit'
import { useState } from 'react'

function App() {
  const [showToast, setShowToast] = useState(false)

  return (
    <div>
      <button onClick={() => setShowToast(true)}>Show Toast</button>

      {showToast && (
        <Toast
          variant="success"
          title="Success!"
          onClose={() => setShowToast(false)}
          position="top-right"
          duration={5000}
          autoClose
        >
          Your changes have been saved successfully.
        </Toast>
      )}
    </div>
  )
}

Props:

  • children: ReactNode (required)
  • variant: 'success' | 'danger' | 'warning' | 'info'
  • title: string
  • onClose: function
  • showIcon: boolean
  • className: string
  • duration: number (milliseconds, default: 5000)
  • position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center' | 'bottom-center'
  • autoClose: boolean

InfoBox

Simple informational box component for displaying contextual information.

import { InfoBox } from 'primolab-ui-kit'

function App() {
  return (
    <div>
      <InfoBox variant="info">
        <p>This is an informational message.</p>
      </InfoBox>

      <InfoBox variant="warning">
        <p>Please review this carefully before proceeding.</p>
      </InfoBox>

      <InfoBox variant="danger">
        <p>This action requires administrator privileges.</p>
      </InfoBox>
    </div>
  )
}

Props:

  • children: ReactNode (required)
  • variant: 'info' | 'warning' | 'danger'
  • className: string

Navbar

Navigation bar container component.

import { Navbar, NavbarItem } from 'primolab-ui-kit'

function App() {
  const [activeTab, setActiveTab] = useState('home')

  return (
    <Navbar>
      <NavbarItem
        active={activeTab === 'home'}
        onClick={() => setActiveTab('home')}
      >
        Home
      </NavbarItem>
      <NavbarItem
        active={activeTab === 'about'}
        onClick={() => setActiveTab('about')}
      >
        About
      </NavbarItem>
      <NavbarItem
        active={activeTab === 'contact'}
        onClick={() => setActiveTab('contact')}
      >
        Contact
      </NavbarItem>
    </Navbar>
  )
}

Navbar Props:

  • children: ReactNode (required)
  • className: string

NavbarItem Props:

  • children: ReactNode (required)
  • active: boolean
  • onClick: function
  • href: string
  • className: string

Theme Customization

The UI kit uses a comprehensive color system that can be customized. The default colors are:

  • Primary: #9985B5 (Purple)
  • Secondary: #B6C224 (Lime)
  • Danger: #D9534F (Red)
  • Warning: #D4A017 (Gold)
  • Success: #5A9E6F (Green)
  • Info: #5B9BD5 (Blue)

All components are built with customization in mind. You can:

  1. Override styles using the className prop
  2. Use Tailwind utility classes directly
  3. Customize the theme by overriding CSS variables

TypeScript Support

Full TypeScript support is included with type definitions for all components.

import {
  ButtonProps,
  ModalProps,
  TableProps,
  InputProps,
  SelectProps,
  SelectSearchableProps,
  TextAreaProps,
  CardProps,
  BadgeProps,
  AlertProps,
  SpinnerProps,
  SkeletonProps,
  LoaderProps,
  BootboxProps,
  TooltipProps,
  AccordionProps,
  CheckboxProps,
  ToggleProps,
  DateTimePickerProps,
  ToastProps,
  InfoBoxProps,
  NavbarProps,
  NavbarItemProps
} from 'primolab-ui-kit'

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

MIT

primo-lab-ui-kit