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

@lp-labs/react-shadow-editor

v0.1.0

Published

Controlled multi-layer box shadow editor with inset and validated CSS export.

Readme

@lp-labs/react-shadow-editor

An original controlled multiple box-shadow editor with inset, opacity, ordering, and validated CSS export. React 18.2 or 19 is the only runtime peer; there are no runtime dependencies.

Use

npm install @lp-labs/react-shadow-editor react react-dom

In a React application with CSS imports enabled:

import { useState } from "react";
import {
  ShadowEditor,
  createShadow,
  shadowToCss,
  validateShadow,
} from "@lp-labs/react-shadow-editor";
import "@lp-labs/react-shadow-editor/styles.css";

export default function App() {
  const [value, setValue] = useState(createShadow);
  return (
    <>
      <ShadowEditor value={value} onChange={setValue} />
      <div style={{ boxShadow: validateShadow(value).length ? "none" : shadowToCss(value) }}>
        Your element
      </div>
    </>
  );
}

ESM named imports and CommonJS require expose the same API. Import the styles.css subpath separately; JavaScript does not import it. Module import and server rendering do not touch browser globals.

Component and complete types

ShadowEditor(props: ShadowEditorProps) requires value: ShadowValue and onChange(next: ShadowValue): void. Persist each next value; edits do not mutate the supplied value. Optional props: disabled?: boolean = false, className?: string = "", style?: React.CSSProperties, and "aria-label"?: string = "Shadow editor".

interface ShadowLayer {
  id: string;
  x: number;
  y: number;
  blur: number;
  spread: number;
  color: string;
  opacity: number;
  inset: boolean;
}
interface ShadowValue { layers: ShadowLayer[] }

These types and ShadowEditorProps are exported. All fields are required. There may be 0-16 layers. IDs are unique strings of 1-64 characters, used for React keys rather than CSS. X, Y and spread are finite in [-1000,1000] pixels; blur is finite in [0,1000] pixels; opacity is finite in [0,1]. Colors must be six-digit hex RGB strings and inset must be boolean. Negative spread is supported.

All runtime exports

  • ShadowEditor: the component above.
  • createShadowLayer(id = "shadow-1"): ShadowLayer: returns fresh defaults: x 0, y 4, blur 12, spread 0, color "#000000", opacity 0.2, inset false. Throws RangeError for empty or overlong id. Uniqueness is checked on a full value, not by this factory.
  • createShadow(): ShadowValue: returns one fresh default layer.
  • validateShadow(value: ShadowValue): string[]: returns constraint errors, or []. Expects structurally typed data, not arbitrary unknown JSON.
  • shadowToCss(value: ShadowValue): string: validates and returns a CSS property value, not a declaration: ordered, comma-separated shadows using px lengths and rgba(r, g, b, opacity). The first layer is frontmost. Empty layers return "none". Invalid values throw RangeError. It never injects CSS, writes a file or accesses the clipboard.

These are all runtime exports; no default export or custom error class exists.

Editing, export and limits

Add shadow creates a fresh default with a unique id. Remove may delete the last layer, producing none. Move forward exchanges a layer with the previous layer to change stacking order. All layer controls are visible, with finite number inputs, a hex color text field and an inset checkbox.

Finite intermediate numeric edits and text edits are emitted even when invalid. The editor announces validation errors and suppresses CSS export until corrected. The read-only export textarea adds box-shadow: and a semicolon around the helper's property value. It is selectable text, not an automatic download. Only validated numbers and hex-derived RGBA colors are serialized; CSS variables, URLs, functions and arbitrary declarations are rejected.

The preview uses native CSS and may clip very large shadows. This editor supports box shadows only: no text-shadow, drop-shadow filters, CSS parsing, color spaces other than RGB, non-pixel lengths, blend modes, animated shadows, or full design-tool compatibility. No production certification is claimed.

Customization and accessibility

Styles are scoped to .lpsh-editor; override --lpsh-accent, pass root style, or use className. Layer legends, visible labels, native buttons, inset checkboxes, keyboard-editable fields, visible focus outlines and announced errors support keyboard operation. Provide sufficient contrast when changing colors; the preview also contains text.

box-shadow |

License

MIT.

Support

If this library is useful to you, consider supporting its maintenance with a donation via PayPal.

Author

Created by Libin Prasanth. Connect on LinkedIn for updates and discussion.