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

rifm

v0.12.1

Published

Tiny react input formatter and mask

Downloads

4,467,639

Readme

RIFM - React Input Format & Mask

Is a tiny (≈ 800b) component (and hook) to transform any input component into formatted or masked input.

Demo

Highlights

  • Requires React 16.8+
  • Dependency free
  • Tiny (≈ 800b)
  • Supports any input.
  • Can mask input, format and more
  • Small readable source
  • flow + typescript definitions

Example

Rifm offers both a Render Prop and a Hook API:

Render Prop

import { Rifm } from 'rifm';
import { TextField } from '@material-ui/core';

const numberFormat = (str: string) => {
  const r = parseInt(str.replace(/[^\d]+/gi, ''), 10);
  return r ? r.toLocaleString('en') : '';
}

...

  const [value, setValue] = React.useState('')

  <Rifm
    value={value}
    onChange={setValue}
    format={numberFormat}
  >
    {({ value, onChange }) => (
      <TextField
        type="tel"
        value={value}
        onChange={onChange}
      />
    )}
  </Rifm>

...

Hook

import { useRifm } from 'rifm';
import { TextField } from '@material-ui/core';

const numberFormat = (str: string) => {
  const r = parseInt(str.replace(/[^\d]+/gi, ''), 10);
  return r ? r.toLocaleString('en') : '';
}

...

  const [value, setValue] = React.useState('')

  const rifm = useRifm({
    value,
    onChange: setValue,
    format: numberFormat
  })

  <TextField
    type="tel"
    value={rifm.value}
    onChange={rifm.onChange}
  />

...

Install

yarn add rifm

API

Terminology

Rifm is based on simple idea (*):

  • format operation applied to input value after edit doesn't change the order of some symbols before cursor

* This is not always true, but we solve some edge cases where it's not.

Imagine you have simple integer number formatter with ` as thousands separator and current input state is 123`4|67 ("|" shows current cursor position).

User press 5 then formatted input must be equal to 1`234`5|67.

The overall order of elements has changed (was 1->2->3->`->4->... became 1->`->2->3->4...) but the order of digits before cursor hasn't changed (was 1->2->3->4 and hasn't changed).

The same is true for float numbers formatting, dates and more. Symbols with preserved order are different and depends on format. We call this kind of symbols - "accepted" symbols.

Rifm solves only one task - find the right place for cursor after formatting.

Knowledge about what symbols are "accepted" and cursor position after any user action is enough to find the final cursor position.

Most operations which are not covered with above idea like case enforcements, masks guides, floating point ","=>"." replacement can be done using simple postprocessing step - replace. This operation works well if you need to change input value without loosing cursor position.

And finaly masks - masks are usually is format with replace editing mode + some small cursor visual hacks.

Input Props

These are accepted by the Rifm component as props and the useRifm hook as named arguments.

| Prop | type | default | Description | | ------------ | :---------------------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------ | | accept | RegExp (optional) | /\d/g | Regular expression to detect "accepted" symbols | | format | string => string | | format function | | value | string | | input value | | onChange | string => void | | event fired on input change | | children | ({ value, onChange }) => Node | | value and onChange handler you need to pass to underlying input element | | mask | boolean (optional) | | use replace input mode if true, use cursor visual hacks if prop provided | | replace | string => string (optional) | | format postprocessor allows you to fully replace any/all symbol/s preserving cursor | | append | string => string (optional) | | format postprocessor called only if cursor is in the last position and new symbols added, used for specific use-case to add non accepted symbol when you type |

Output Props

These will be passed into the children render prop for the Rifm component as named arguments, and returned from the useRifm hook as an object.

| Prop | type | default | Description | | ------------ | :--------------------- | :------ | :--------------------------------------------------------------- | | value | string | | A formatted string value to pass as a prop to your input element | | onChange | SyntheticEvent => void | | The change handler to pass as a prop to your input element |

See the Demo there are a lot of examples there.

Thanks

@TrySound for incredible help and support on this