@ymnch.wt/neumorphism-ui
v1.0.5
Published
Soft-UI (Neumorphism) React component library with full TypeScript support
Maintainers
Readme
@ymnch.wt/neumorphism-ui
Soft-UI (Neumorphism) React component library with full TypeScript support.
✨ Features
- 🎨 Beautiful Neumorphism (Soft-UI) design system
- 📦 11 ready-to-use React components
- 🎯 Full TypeScript support with type definitions
- 🎨 Comprehensive design tokens (colors, shadows, typography, spacing)
- 🪶 Zero CSS dependencies - pure inline styles
- 🌳 Tree-shakeable ES modules
- 📱 Responsive and accessible
📦 Installation
npm install @ymnch.wt/neumorphism-uiPeer dependencies:
npm install react react-dom lucide-react🎨 Font Setup
Add the Tinos font to your HTML <head>:
<link
href="https://fonts.googleapis.com/css2?family=Tinos:wght@400;700&display=swap"
rel="stylesheet"
/>🚀 Quick Start
import { NeuButton, NeuCard, color, shadow, typo, typography } from "@ymnchwt/neumorphism-ui";
function App() {
return (
<div style={{ background: color.surface.default, minHeight: "100vh", padding: 24 }}>
<NeuCard type="Raised" size="MD">
<h1 style={typo(typography.heading.h1)}>Welcome</h1>
<p style={typo(typography.body.default)}>
Beautiful Neumorphism UI components
</p>
<NeuButton size="MD" onClick={() => alert("Clicked!")}>
Get Started
</NeuButton>
</NeuCard>
</div>
);
}🎯 Components
Buttons
NeuButton - Primary button component
import { NeuButton } from "@ymnchwt/neumorphism-ui";
<NeuButton size="MD" state="Default" onClick={handleClick}>
Click me
</NeuButton>
// Props: size: "SM" | "MD" | "LG"
// state: "Default" | "Hover" | "Pressed" | "Disabled"NeuIconButton - Icon button component
import { NeuIconButton } from "@ymnchwt/neumorphism-ui";
import { Heart } from "lucide-react";
<NeuIconButton size="MD" onClick={handleLike}>
<Heart size={18} />
</NeuIconButton>
// Props: size: "SM" | "MD" | "LG"
// state: "Default" | "Pressed"Form Inputs
NeuInput - Text input and textarea
import { NeuInput } from "@ymnchwt/neumorphism-ui";
<NeuInput
placeholder="Enter your name"
value={name}
onChange={setName}
state="Default"
/>
<NeuInput
textarea
placeholder="Your message..."
value={message}
onChange={setMessage}
/>
// Props: state: "Default" | "Focus" | "Filled" | "Error" | "Disabled"
// textarea: booleanNeuToggle - Toggle switch
import { NeuToggle } from "@ymnchwt/neumorphism-ui";
<NeuToggle
state="Off"
onChange={(on) => setEnabled(on)}
/>
// Props: state: "Off" | "On" | "Disabled"NeuCheckbox - Checkbox with label
import { NeuCheckbox } from "@ymnchwt/neumorphism-ui";
<NeuCheckbox
label="Accept terms"
state="Unchecked"
onChange={(checked) => setAccepted(checked)}
/>
// Props: state: "Unchecked" | "Checked" | "Disabled"NeuRadio - Radio button with label
import { NeuRadio } from "@ymnchwt/neumorphism-ui";
<NeuRadio
label="Option A"
state={selected === 0 ? "Checked" : "Unchecked"}
onClick={() => setSelected(0)}
/>
// Props: state: "Unchecked" | "Checked" | "Disabled"Layout & Display
NeuCard - Container card
import { NeuCard } from "@ymnchwt/neumorphism-ui";
<NeuCard type="Raised" size="MD">
<h2>Card Title</h2>
<p>Card content</p>
</NeuCard>
// Props: type: "Raised" | "Flat"
// size: "SM" | "MD" | "LG" (160×120 | 280×200 | 480×320)NeuNavBar - Navigation bar
import { NeuNavBar } from "@ymnchwt/neumorphism-ui";
import { Home, Search, Bell } from "lucide-react";
<NeuNavBar
items={[
{ label: "Home", icon: <Home size={18} /> },
{ label: "Search", icon: <Search size={18} /> },
{ label: "Alerts", icon: <Bell size={18} /> },
]}
activeIndex={0}
onSelect={(index) => setActiveTab(index)}
/>NeuBadge - Status badge
import { NeuBadge } from "@ymnchwt/neumorphism-ui";
<NeuBadge type="Active">Featured</NeuBadge>
<NeuBadge type="Default">Draft</NeuBadge>
// Props: type: "Default" | "Active"Progress & Feedback
NeuProgressBar - Progress indicator
import { NeuProgressBar } from "@ymnchwt/neumorphism-ui";
<NeuProgressBar progress={75} active />
// Props: progress: number (0-100)
// active: booleanNeuSlider - Interactive slider
import { NeuSlider } from "@ymnchwt/neumorphism-ui";
<NeuSlider
value={volume}
onChange={(v) => setVolume(v)}
/>
// Props: value: number (0-100)🎨 Design Tokens
Colors
import { color } from "@ymnchwt/neumorphism-ui";
color.surface.default // "#F0F0F3" - Main background
color.shadow.dark // "#C8C8CC" - Dark shadow
color.shadow.light // "#FFFFFF" - Light shadow
color.text.primary // "#3A3A4A" - Primary text
color.text.secondary // "#7A7A8A" - Secondary text
color.text.disabled // "#B0B0BC" - Disabled text
color.border.subtle // "#E0E0E4" - Subtle borderShadows
import { shadow } from "@ymnchwt/neumorphism-ui";
shadow.raised // Elevated appearance (6px outer)
shadow.pressed // Pressed/inset appearance (4px inset)
shadow.flat // Subtle depth (2px outer)Spacing
import { spacing } from "@ymnchwt/neumorphism-ui";
spacing.xs // 4px
spacing.sm // 8px
spacing.md // 16px
spacing.lg // 24px
spacing.xl // 40pxBorder Radius
import { radius } from "@ymnchwt/neumorphism-ui";
radius.sm // 4px
radius.md // 8px
radius.lg // 16px
radius.full // 9999px (fully rounded)Typography
import { typography, typo, fontFamily } from "@ymnchwt/neumorphism-ui";
// Use typo() helper to convert tokens to React CSSProperties
<h1 style={typo(typography.heading.h1)}>Heading</h1>
<p style={typo(typography.body.default)}>Body text</p>
<span style={typo(typography.label.sm)}>Label</span>
// Available scales:
// - typography.heading.h1, h2, h3
// - typography.body.default, strong
// - typography.label.md, sm
// Font family constant
fontFamily // "'Tinos', serif"📝 Complete Example
import React, { useState } from "react";
import {
NeuCard,
NeuInput,
NeuButton,
NeuCheckbox,
NeuBadge,
color,
spacing,
typography,
typo,
} from "@ymnchwt/neumorphism-ui";
function ContactForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");
const [agreed, setAgreed] = useState(false);
const handleSubmit = () => {
if (agreed) {
console.log({ name, email, message });
}
};
return (
<div style={{
background: color.surface.default,
minHeight: "100vh",
padding: spacing.xl,
display: "flex",
justifyContent: "center",
alignItems: "center"
}}>
<NeuCard type="Raised" size="LG">
<div style={{ padding: spacing.md }}>
<div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: spacing.md }}>
<h2 style={{ ...typo(typography.heading.h2), color: color.text.primary }}>
Contact Us
</h2>
<NeuBadge type="Active">New</NeuBadge>
</div>
<div style={{ marginBottom: spacing.md }}>
<NeuInput
placeholder="Your name"
value={name}
onChange={setName}
/>
</div>
<div style={{ marginBottom: spacing.md }}>
<NeuInput
placeholder="Email address"
value={email}
onChange={setEmail}
/>
</div>
<div style={{ marginBottom: spacing.md }}>
<NeuInput
textarea
placeholder="Your message..."
value={message}
onChange={setMessage}
/>
</div>
<div style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginTop: spacing.lg
}}>
<NeuCheckbox
label="I agree to the terms"
state={agreed ? "Checked" : "Unchecked"}
onChange={setAgreed}
/>
<NeuButton
size="MD"
state={!agreed ? "Disabled" : "Default"}
onClick={handleSubmit}
>
Send Message
</NeuButton>
</div>
</div>
</NeuCard>
</div>
);
}
export default ContactForm;🎨 Design Philosophy
This library follows the Neumorphism (Soft UI) design pattern:
- Subtle depth: Components appear to extrude from or sink into the background
- Light source: Consistent lighting from top-left creates realistic shadows
- Monochromatic: Limited color palette for cohesive appearance
- Soft edges: Rounded corners throughout
- Minimal contrast: Soft shadows instead of harsh borders
📄 License
MIT © ymnch.wt
🔗 Links
🙏 Acknowledgments
This library includes components inspired by shadcn/ui (MIT License).
