Forms switchneumorphism

Neumorphic Switch

Soft-UI toggle switch.

Preview

Usage

Copy the full block below to use this component with its imports.

astro
---
import { NeumorphicSwitch } from 'astro-component-kit';
---

<NeumorphicSwitch id="notify" label="Enable Notifications" checked />
--- import { NeumorphicSwitch } from 'astro-component-kit'; --- <NeumorphicSwitch id="notify" label="Enable Notifications" checked />

Manual Installation

If you are not using the npm package, create a new file src/components/lib/NeumorphicSwitch.astro and paste the following code:

astro
---
/**
 * NeumorphicSwitch — A soft-UI checkbox toggle with realistic inset and outset shadow states.
 * 
 * @param {string} label - Optional descriptive text suffix.
 * @param {string} id - HTML ID for input linkage.
 * @param {string} name - HTML name binding.
 * @param {boolean} checked - Initial toggle state. Default is false.
 */
interface Props {
  label?: string;
  id: string;
  name?: string;
  checked?: boolean;
}

const { label, id, name, checked = false } = Astro.props;
---

<div class="neu-switch-wrapper">
  <label class="neu-switch">
    <input type="checkbox" {id} {name} {checked} />
    <span class="slider"></span>
  </label>
  {label && <label for={id} class="neu-label">{label}</label>}
</div>

<style>
  .neu-switch-wrapper { display: flex; align-items: center; gap: var(--sp-3, 0.75rem); }
  
  .neu-switch {
    position: relative;
    display: inline-block;
    width: 60px;
    height: 32px;
    flex-shrink: 0;
  }
  
  .neu-label { font-size: 0.9rem; color: var(--c-text-2, #94a3b8); cursor: pointer; }
  
  .neu-switch input {
    opacity: 0;
    width: 0;
    height: 0;
  }
  
  .slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background: var(--c-bg, #1a1f2e);
    transition: 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    border-radius: 34px;
    border: 1px solid var(--c-border, rgba(255, 255, 255, 0.05));
    box-shadow:
      inset 2px 2px 5px rgba(0, 0, 0, 0.5),
      inset -2px -2px 5px rgba(255, 255, 255, 0.04);
  }
  
  .slider:before {
    position: absolute;
    content: "";
    height: 24px;
    width: 24px;
    left: 4px;
    bottom: 3px;
    background: #374151;
    transition: 0.4s cubic-bezier(0.18, 0.89, 0.32, 1.28);
    border-radius: 50%;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
  }
  
  input:checked + .slider {
    background: rgba(99, 102, 241, 0.1);
    border-color: rgba(99, 102, 241, 0.2);
  }
  
  input:checked + .slider:before {
    transform: translateX(28px);
    background: var(--c-primary, #818cf8);
    box-shadow: 0 0 15px rgba(129, 140, 248, 0.5);
  }
</style>
--- /** * NeumorphicSwitch — A soft-UI checkbox toggle with realistic inset and outset shadow states. * * @param {string} label - Optional descriptive text suffix. * @param {string} id - HTML ID for input linkage. * @param {string} name - HTML name binding. * @param {boolean} checked - Initial toggle state. Default is false. */ interface Props { label?: string; id: string; name?: string; checked?: boolean; } const { label, id, name, checked = false } = Astro.props; --- <div class="neu-switch-wrapper"> <label class="neu-switch"> <input type="checkbox" {id} {name} {checked} /> <span class="slider"></span> </label> {label && <label for={id} class="neu-label">{label}</label>} </div> <style> .neu-switch-wrapper { display: flex; align-items: center; gap: var(--sp-3, 0.75rem); } .neu-switch { position: relative; display: inline-block; width: 60px; height: 32px; flex-shrink: 0; } .neu-label { font-size: 0.9rem; color: var(--c-text-2, #94a3b8); cursor: pointer; } .neu-switch input { opacity: 0; width: 0; height: 0; } .slider { position: absolute; cursor: pointer; inset: 0; background: var(--c-bg, #1a1f2e); transition: 0.4s cubic-bezier(0.4, 0, 0.2, 1); border-radius: 34px; border: 1px solid var(--c-border, rgba(255, 255, 255, 0.05)); box-shadow: inset 2px 2px 5px rgba(0, 0, 0, 0.5), inset -2px -2px 5px rgba(255, 255, 255, 0.04); } .slider:before { position: absolute; content: ""; height: 24px; width: 24px; left: 4px; bottom: 3px; background: #374151; transition: 0.4s cubic-bezier(0.18, 0.89, 0.32, 1.28); border-radius: 50%; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4); } input:checked + .slider { background: rgba(99, 102, 241, 0.1); border-color: rgba(99, 102, 241, 0.2); } input:checked + .slider:before { transform: translateX(28px); background: var(--c-primary, #818cf8); box-shadow: 0 0 15px rgba(129, 140, 248, 0.5); } </style>

Quick Info

Category
Forms
Filename
NeumorphicSwitch.astro
Dependencies
None — pure Astro + CSS
Tags
switchneumorphism