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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@vcnkit/essentials

v0.2.2

Published

Essential elements for VCNKit

Readme

VCNKit/Essentials

@vcnkit/essentials contains essential utilities, decorators and theming for VCNKit.

Installation

NPM

$ npm install --save @vcnkit/essentials

Yarn

$ yarn add @vcnkit/essentials

Utilities

noop()

Simple void function to use as a default prop when your component expects a function.

import { noop } from '@vcnkit/essentials';

SomeComponent.defaultProps = {
    onClick: noop,
};

omit(props, [ prop, ... ])

Omits the specified props from the given prop object

import { omit } from '@vcnkit/essentials';

const SomeComponent = (props) => (
    <div { ...omit(props, [ 'someProp', 'anotherProp' ]) } >
        'someProp' and 'anotherProp' have been omitted.
    </div>
)

extract(props, [ prop, ... ])

Extracts the specified props from the given prop object, basically the reverse of omit

import { extract } from '@vcnkit/essentials';

const SomeComponent = (props) => (
    <div { ...extract(props, [ 'role', 'id' ]) }>
        'role' and 'id' will have been attached to this div.
    </div>
);

getRelatedTarget(event)

Internet Explorer compatible relatedTarget for blur events. This function will give you the node that will receive focus after the blur has occured.

import { getRelatedTarget } from '@vcnkit/essentials';

class SomeComponent extends React.Component {
    handleBlur = event => {
        // Will contain the Node that received focus.
        const relatedTarget = getRelatedTarget(event);
    };

    render() {
        return (
            <input onBlur={ this.handleBlur } />
        );
    }
}

isTargetDescendantOf(root, target)

Checks if the given target Node is a descendant of root (but not the same node).

import { isTargetDescendantOf } from '@vcnkit/essentials';

function isBodyDescendantOfDocument() {
    return isTargetDescendantOf(document, document.body);
}

createHoC(Component, WrappedComponent)

Utility to reduce boilerplate when creating Higher-Order Components

It will provide the resulting HoC with a displayName that is a cobmination of Component and WrappedComponent. It will also take care of forwarding refs and hoisting the non-react statics.

import { createHoC } from '@vcnkit/essentials';

function myHoC(WrappedComponent) {
    class MyHoC extends React.Component {
        render() {
            const { forwardRef, ...rest } = this.props;

            return (
                <WrappedComponent
                    ref={ forwardRef }
                    { ...rest }
                />
            )
        }
    }

    MyHoC.displayName = 'MyHoC';
    return createHoC(MyHoC, WrappedComponent);
}

Decorators

uniqueId

Passes a getId() function through props to the decorated component. This function will always return the same identifier for the same instance.

Optionally the getId() function takes a suffix-parameter, this will result in the given suffix being added to the identifier.

import { uniqueId } from '@vcnkit/essentials';

@uniqueId()
class SomeComponent extends React.Component {
    render() {
        const { getId } = this.props;

        return (
            <div>
                <label htmlFor={ getId('input') }>Label</label>
                <input
                    id={ getId('input') }
                    type="text"
                />
            </div>
        );
    }
}

Stateless components can use the decorator by wrappign itself.

import { uniqueId } from '@vcnkit/essentials';

const SomeComponent = ({ getId }) => (
    <div>
        <label htmlFor={ getId('input') }>Label</label>
        <input
            id={ getId('input') }
            type="text"
        />
    </div>
);

export default uniqueId()(SomeComponent);

hoverable

Provides decorated components with a hovering-prop. This props tells the component if the user is currently hovering over the element.

To make this work, this decorator provides the onMouseEnter and onMouseLeave props which should be attached to your component.

import { hoverable } from '@vcnkit/essentials';

@hoverable()
class SomeComponent extends React.Component {
    render() {
        const { hovering, onMouseEnter, onMouseLeave, ...rest } = this.props;

        return (
            <div
                onMouseEnter={ onMouseEnter }
                onMouseLeave={ onMouseLeave }
                { ...rest }
            >
                { hovering ? 'User is hovering over this div!' : 'User is not hovering over this div' }
            </div>
        );
    }
}

Stateless components can use the decorator by wrapping itself.

import { hoverable } from '@vcnkit/essentials';

const SomeComponent = ({ hovering, onMouseEnter, onMouseLeave, ...rest ) => (
    <div
        onMouseEnter={ onMouseEnter }
        onMouseLeave={ onMouseLeave }
        { ...rest }
    >
        { hovering ? 'User is hovering over this element!' : 'User is not hovering over this element' }
    </div>
);

export default hoverable()(SomeComponent);    

focusable(focusOnChildFocus = false)

Provides decorated components with a focused-prop. This prop tells the component if the component currently has focus, or if focusOnChildFocus is true if a child component has focus.

This decorator will not provide a tabIndex prop, the component itself is responsible for giving itself or it's children a tabIndex prop.

import { focusable } from '@vcnkit/essentials';

@focusable()
class SomeComponent extends React.Component {
    render() {
        const { focused, onFocus, onBlur, ...rest } = this.props;

        return (
            <div
                onFocus={ onFocus }
                onBlur={ onBlur }
                tabIndex={ 0 }
                { ...rest }
            >
                { focused ? 'Element has focus' : 'Element does not have focus' }
            </div>
        );
    }
}

Stateless components can use the decorator by wrapping itself.

import { focusable } from '@vcnkit/essentials';

const SomeComponent = ({ hovering, onMouseEnter, onMouseOut, ...rest ) => (
    <div
        onFocus={ onFocus }
        onBlur={ onBlur }
        tabIndex={ 0 }
        { ...rest }
    >
        { focused ? 'Element has focus' : 'Element does not have focus' }
    </div>
);

export default focusable()(SomeComponent);    

expandable

Provides decorated components with a expanded-prop. The expansion state can either be controlled from another component by passing your own expanded-prop to the decorated component. When it changes, an attached onChange(currentExpandedState: bool) will be triggered.

It is also possible to let the decorator keep the state internal, you can set the default state by passing initialExpanded.

import { expandable } from '@vcnkit/essentials';

@expandable()
class SomeComponent extends React.Component {
    render() {
        const { expanded, onChange } = this.props;

        return (
            <div>
                <h1 onClick={ onChange }>Click here to toggle</h1>
                { expanded && (
                    <p>Expanded!</p>
                ) }
            </div>
        )
    }
}

// Using internal state (starts expanded)
const SomeOtherComponent = () => (
    <SomeComponent initialExpanded/>
)

// Controlling state from another component
class ExpandController extends React.Component {
    state = {
        expanded: false,
    };

    handleChange = (currentExpandedState) => {
        this.setState({
            expanded: !currentExpandedState,
        });
    }

    render() {
        const { expanded } = this.state;

        return (
            <SomeComponent
                expanded={ expanded }
                onChange={ this.handleChange }
            />
        )
    }
}

Decorating a class or stateless component with multiple decorators

If you want a component to have both the hoverable and focusable decorators, you can simply chain them.

import * as React from 'react';
import { hoverable, focusable } from '@vcnkit/essentials';

@focusable()
@hoverable()
class SomeClassComponent extends React.Component {
    render() {
        const { hovering, focused, ...rest } = this.props;

        return (
            <div
                tabIndex={ 0 }
                { ...rest }
            >
                { hovering ? 'User is hovering over this element!' : 'User is not hovering over this element' }
                { focused ? 'Element has focus' : 'Element does not have focus' }
            </div>            
        )
    }
}

And for stateless components

import { hoverable, focusable } from '@vcnkit/essentials';

/*
 * ...rest will contain all the necessary event handlers. onMouseEnter, onMouseLeave, onFocus and onBlur
 */
const SomeComponent = ({ hovering, focused, ...rest }) => (
    <div
        tabIndex={ 0 }
        { ...rest }
    >
        { hovering ? 'User is hovering over this element!' : 'User is not hovering over this element' }
        { focused ? 'Element has focus' : 'Element does not have focus' }
    </div>
);

export default focusable()(hoverable()(SomeComponent))

Attaching refs to decorated components

The decorators in @vcnkit/essentials utilize React's forwardRef API to pass refs to the decorated components.

Using React's createRef API:

import * as React from 'react';
import { hoverable } from '@vcnkit/essentials';

@hoverable()
class MyDecoratedComponent extends React.Component {
    ...
}

class MyComponent extends React.Component {
    constructor(props) {
        super(props);

        // This will hold a ref to 'MyDecoratedComponent' instead of the decorator itself.
        this.ref = React.createRef();
    }

    render() {
        return (
            <MyDecoratedComponent
                ref={ this.ref }
            />
        )
    }
}

Or, using a callback ref:

import * as React from 'react';
import { hoverable } from '@vcnkit/essentials';

@hoverable()
class MyDecoratedComponent extends React.Component {
    ...
}

class MyComponent extends React.Component {
    render() {
        return (
            <MyDecoratedComponent
                ref={ ref => { this.ref = ref; } }
            />
        )
    }
}