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

neumorphic-peripheral

v1.0.0

Published

A lightweight, framework-agnostic JavaScript/TypeScript library for beautiful neumorphic styling

Readme

neumorphic-peripheral

A lightweight, framework-agnostic JavaScript/TypeScript library that provides beautiful neumorphic styling and functionality for any web framework.

Features

  • Universal Framework Support - Works with React, Vue, Svelte, Angular, Next.js, Nuxt.js, and vanilla JavaScript
  • Lightweight - Under 20kb gzipped with zero dependencies
  • TypeScript Ready - Full TypeScript support with comprehensive type definitions
  • Accessible - WCAG 2.1 AA compliant with screen reader support
  • Themeable - Built-in light/dark themes with custom theme support
  • Smart Components - Password fields with eye toggle, input validation, and more

Quick Start

Installation

npm install neumorphic-peripheral

Basic Usage

import np from 'neumorphic-peripheral'

// Apply neumorphic styling to any element
np.card(document.getElementById('my-card'))
np.input(document.querySelector('.email-input'))
np.password(document.querySelector('.password-field'))
np.button(document.querySelector('.submit-btn'))

Framework Examples

React/Next.js

import np from 'neumorphic-peripheral'
import { useEffect, useRef } from 'react'

function MyComponent() {
  const cardRef = useRef()
  const inputRef = useRef()
  
  useEffect(() => {
    np.card(cardRef.current)
    np.input(inputRef.current, { validate: { email: true, required: true } })
  }, [])
  
  return (
    <div ref={cardRef}>
      <input ref={inputRef} type="email" placeholder="Email" />
    </div>
  )
}

Vue/Nuxt.js

<template>
  <div ref="cardEl">
    <input ref="inputEl" type="email" placeholder="Email" />
  </div>
</template>

<script setup>
import np from 'neumorphic-peripheral'
import { ref, onMounted } from 'vue'

const cardEl = ref()
const inputEl = ref()

onMounted(() => {
  np.card(cardEl.value)
  np.input(inputEl.value, { validate: { email: true } })
})
</script>

Svelte

<script>
  import np from 'neumorphic-peripheral'
  import { onMount } from 'svelte'
  
  let cardEl
  let inputEl
  
  onMount(() => {
    np.card(cardEl)
    np.input(inputEl, { validate: { email: true } })
  })
</script>

<div bind:this={cardEl}>
  <input bind:this={inputEl} type="email" placeholder="Email" />
</div>

Components

Card

Create beautiful neumorphic container elements.

np.card(element, {
  variant: 'raised' | 'inset' | 'flat', // default: 'raised'
  size: 'sm' | 'md' | 'lg',             // default: 'md'
  padding: '16px',                      // custom padding
  theme: 'light' | 'dark' | customTheme
})

Input

Enhanced input fields with validation support.

np.input(element, {
  validate: {
    required: true,
    email: true,
    minLength: 8,
    pattern: /^[A-Za-z]+$/,
    custom: [(value) => value.includes('@') ? null : 'Must contain @']
  },
  validateOn: 'blur' | 'change' | 'submit', // default: 'blur'
  placeholder: 'Enter text...',
  errorMessage: 'Custom error message'
})

Password

Smart password fields with visibility toggle and strength indicator.

np.password(element, {
  showToggle: true,                    // default: true
  togglePosition: 'right' | 'left',   // default: 'right'  
  strengthIndicator: true,             // default: false
  validate: {
    required: true,
    minLength: 8
  }
})

The password component automatically:

  • Converts text to bullet characters
  • Adds a clickable eye icon for visibility toggle
  • Shows password strength indicators (if enabled)
  • Includes all input validation features

Button

Interactive neumorphic buttons with loading states.

np.button(element, {
  variant: 'primary' | 'secondary' | 'ghost', // default: 'primary'
  size: 'sm' | 'md' | 'lg',                   // default: 'md'
  loading: false,                             // default: false
  onClick: (event) => console.log('clicked')
})

Validation

Built-in validation system with real-time feedback.

Built-in Validators

np.input(element, {
  validate: {
    required: true,           // Field is required
    email: true,              // Valid email format
    minLength: 8,             // Minimum character length
    maxLength: 50,            // Maximum character length
    pattern: /^\d+$/,         // Custom regex pattern
    custom: [                 // Custom validation functions
      (value) => value.startsWith('A') ? null : 'Must start with A'
    ]
  }
})

Custom Validation

const customValidator = (value) => {
  if (value.length < 5) return 'Too short'
  if (!value.includes('@')) return 'Must contain @'
  return null // Valid
}

np.input(element, { validate: customValidator })

Theming

Using Built-in Themes

import np from 'neumorphic-peripheral'

// Set global theme
np.setTheme('dark')
np.setTheme('light')

// Auto-detect system preference
np.autoDetectTheme()

Custom Themes

np.setTheme({
  colors: {
    surface: '#f0f0f0',
    shadow: {
      light: '#ffffff',
      dark: '#d1d9e6'
    },
    text: '#333333',
    textSecondary: '#666666',
    accent: '#6c5ce7',
    error: '#e74c3c',
    success: '#27ae60'
  },
  borderRadius: '12px',
  spacing: '16px',
  shadowIntensity: 0.15,
  animation: {
    duration: '0.2s',
    easing: 'cubic-bezier(0.4, 0, 0.2, 1)'
  }
})

CSS Custom Properties

The library automatically updates CSS custom properties that you can use in your own styles:

:root {
  --np-surface: #f0f0f3;
  --np-shadow-light: #ffffff;
  --np-shadow-dark: #d1d9e6;
  --np-text: #333333;
  --np-accent: #6c5ce7;
  --np-radius: 12px;
  /* ... and more */
}

.my-custom-element {
  background: var(--np-surface);
  border-radius: var(--np-radius);
  color: var(--np-text);
}

Auto-Initialization

Use data attributes for automatic component initialization:

<!-- Auto-initialize on DOM ready -->
<div data-np="card" data-np-config='{"variant": "inset"}'>
  <input data-np="input" data-np-config='{"validate": {"email": true}}' 
         type="email" placeholder="Email">
  <input data-np="password" data-np-config='{"strengthIndicator": true}' 
         type="password" placeholder="Password">
  <button data-np="button" data-np-config='{"variant": "primary"}'>
    Submit
  </button>
</div>

Enable auto-initialization:

np.config({ autoInit: true })

API Reference

Component Methods

All components return an instance with these methods:

const cardInstance = np.card(element, config)

// Update configuration
cardInstance.update({ variant: 'inset' })

// Destroy component
cardInstance.destroy()

// Get current config
const config = cardInstance.config

Input/Password Specific Methods

const inputInstance = np.input(element, config)

// Validation
const result = inputInstance.validate()
const isValid = inputInstance.isValid()
inputInstance.clearErrors()

// Value management
inputInstance.setValue('new value')
const value = inputInstance.getValue()

// Focus management
inputInstance.focus()
inputInstance.blur()

Password Specific Methods

const passwordInstance = np.password(element, config)

// Visibility toggle
passwordInstance.toggleVisibility()
passwordInstance.showPassword()
passwordInstance.hidePassword()
const isVisible = passwordInstance.isVisible()

// Password strength
const strength = passwordInstance.getPasswordStrength()

Button Specific Methods

const buttonInstance = np.button(element, config)

// Loading state
buttonInstance.setLoading(true)

// Programmatic click
buttonInstance.click()

// Update properties
buttonInstance.setVariant('secondary')
buttonInstance.setSize('lg')

Events

Components emit custom events you can listen for:

element.addEventListener('np:input', (e) => {
  console.log('Input value changed:', e.detail.value)
})

element.addEventListener('np:validation', (e) => {
  console.log('Validation result:', e.detail.result)
})

element.addEventListener('np:click', (e) => {
  console.log('Button clicked:', e.detail)
})

element.addEventListener('np:visibility-toggle', (e) => {
  console.log('Password visibility:', e.detail.visible)
})

// Theme changes
window.addEventListener('np:theme-change', (e) => {
  console.log('Theme changed:', e.detail.theme)
})

Accessibility

The library is built with accessibility in mind:

  • Full keyboard navigation support
  • Screen reader compatible with proper ARIA attributes
  • High contrast mode support
  • Reduced motion support
  • Focus management and indicators
  • Semantic HTML structure

CSS Stylesheet (Optional)

Include the optional CSS file for enhanced styling:

import 'neumorphic-peripheral/styles/neumorphic.css'

Or link it in HTML:

<link rel="stylesheet" href="node_modules/neumorphic-peripheral/styles/neumorphic.css">

Browser Support

  • Chrome 70+
  • Firefox 70+
  • Safari 12+
  • Edge 79+

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

MIT License - see LICENSE for details.

Changelog

See CHANGELOG.md for version history and breaking changes.