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 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-event-modifiers

v1.0.1

Published

Enhances React elements with Svelte-inspired event modifiers like 'onClick-preventDefault' and 'onClick-stopPropagation'.

Downloads

9

Readme

React Event Modifier

Enhances React elements with Svelte-inspired event modifiers.

📖 Overview

Svelte has a nice feature to modify events in useful ways. For example you can quickly call stopPropagation() or preventDefault() on your events with simple 'modifiers' on an element.

This library brings some of that functionality to React in a tiny ~1kB package.

How Svelte does it

<button on:click|stopPropagation="{handleClick}">
  <!-- The click event wont't propagate -->
</button>

<form on:submit|preventDefault="{handleSubmit}">
  <!-- The submit event won't reload the page -->
</form>

How react-event-modifiers does it

import mod from "react-event-modifiers"

<mod.button onClick-stopPropagation={handleClick}>
    {/* The click event wont't propagate */}
</mod.button>

<mod.form onSubmit-preventDefault={handleSubmit}>
    {/* The submit event won't reload the page */}
</mod.form>

🚀 Get started

Install the library:

npm i react-event-modifiers

When you have an element you wish to update like this:

<button onClick={handleClick}>Click me</button>

Then import the library and update the element as follows:

import mod from "react-event-modifiers"

<mod.button onClick-stopPropagation={handleClick}>Click me</mod.button>

Note the mod. prefix to the element, and the -stopPropagation modifier to the event handler prop.

You can use modifiers without a handler like this:

<mod.button onClick-stopPropagation>Click me</mod.button>

and chain modifiers together like this:

<mod.button onClick-preventDefault-stopPropagation={handleClick}>Click me</mod.button>

All native JSX elements are supported and this library should act as a drop in replacement which doesn't affect other props. Typescript is fully supported too!

Typescript example

Note that the only Svelte modifiers that are supported are stopPropagation and preventDefault. React already supports capture events and other modifiers were deemed too niche to implement.


🧐 How it works

Part of the reason for building this little library was to see if this was possible.

It works as follows:

  • Importing react-event-modifier returns a proxy object.
  • When you call <mod.div ...> the proxy is called with the keyword 'div' and all of the react props.
  • This library can then create a normal react 'div' element and modify the props in any way we like.
  • Typescript is used to ensure that only native elements (like div) and event handlers (like onClick) are modifiable.

Modifying the props:

  • The props are given as a simple JS object with keys/vals like { "onClick-stopPropagation": customHandler }.
  • This library can then strip out the modifiers like -stopPropagation and wrap functions with an appropriate handler.
  • Finally the new handler is assigned to the default keyword and the result is a modified object like { "onClick": (e) => { e.stopPropagation(); customHandler(e) } }

Creating the types:

  • One critical piece of this library is ensuring that React types are maintained when using the library. For example:
    • The element <mod.div> should have all of the props and types of <div>
    • The handler <mod.div onClick-stopPropagation={...}> should have the same signature as onClick={...}
  • The library uses all features of the Creating types from types handbook guide importantly:
    • Mapped types to copy and modify the original JSX.IntrinsicElements types into custom ones
    • Template literal types to modify event types like onClick to onClick-stopPropagation
  • Finally this library even has Typescript tests which cover important use cases. E.g. testing that non-modifiable props like className are not polluted with modifiers.

🤷 Is this actually useful?

It's a definitely a tiny quality of life feature but it comes in handy. It really shines when making games and modals where there are many overlaying clickable elements. Having a simple modifier can keep code clean and even save you from making your own click wrappers. It's also a nice feature if you're writing a lot of client-side forms.


💻 Development

Issues and PRs are welcome!

Useful commands:

  • Run tests: npm run tests
  • Run linting etc: npm run check
  • Run the UI demo: cd react-demo-ts/ then npm run dev
  • Build: npm run build