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-directive

v2.0.0

Published

A conditional, className and listing directive for react apps

Downloads

12

Readme

react-directive

A conditional, className and listing directive for react apps

NPM JavaScript Style Guide

Install

# npm
npm i react-directive

# yarn 
yarn add react-directive

Introduction

react-directive is a library for creating conditional or listing directives in a react app. It takes a lot of inspiration from Vue.js' conditional, class bindings and listing directives such as v-if, v-for, and :class. Its two main purposes are listed below.

  • To avoid the headache of using conditional (ternary) operators or higher order array methods such as map for list rendering.
  • To keep JSX clean and concise.

Usage

To use react-directive import it to your component.

import  React  from  'react';
import  directive  from  'react-directive';

const  Component  =  props  =>  {
	return (
        // This is the same as a div element but has more features like dirIf, dirFor, extended className etc.
		<directive.div>
			{ /* Any children for the div element */ }
		</directive.div>
	);
}

Conditional Rendering

react-directive provides directives such as dirIf, dirShow and components <Switch />, <Case /> <Default /> to render (show) or remove (hide) an element from the page.

Prop dirIf

The prop dirIf is used to conditionally render a block. The block will only be rendered if the directive’s expression returns a truthy value (Check out truthy and falsy values in javascript here). It works like v-if for Vuejs and ngIf for angular.

Currently, there is no support for else and else-if yet. ( You can use the <Switch /> component to handle such cases. More on that later ).

Note: undefined is the only exceptional falsy value that evaluates to true because the default value for dirIf is true

Usage

The example component below renders a div element only if the name's length is greater than 4 otherwise it will just render a null value. If you want to keep the node and only toggle style's display value, use the dirShow prop instead.

import  React, { useState }  from  'react';
import  directive  from  'react-directive';

const  Component  =  props  =>  {
    const [currentName, setCurrentName] = useState('Musah');

	return (
		<directive.div dirIf={currentName.length > 4}>
			Div contents
		</directive.div>
	);
}
/*
	When dirIf is truthy, it renders
	<div>Div contents</div> 

    When dirIf is falsy, it renders nothing
*/

Prop dirShow

The prop dirShow is used to conditionally show a block. The block will only be shown if the directive’s expression returns a truthy value. It works like v-show for Vuejs.

Note: dirShow takes precedence to any another display for styles. For example if you set the display to block and dirShow is false, it will still hide the element. Note: undefined is the only exceptional falsy value that evaluates to true because the default value for dirShow is true

Usage

The example component below shows a div element only if the name's length is greater than 4 otherwise it will hide the div element by add the display:none to its styles.

import  React, { useState }  from  'react';
import  directive  from  'react-directive';

const  Component  =  props  =>  {
    const [currentName, setCurrentName] = useState('Musah');

	return (
		<directive.div dirShow={currentName.length > 4}>
			Div contents
		</directive.div>
	);
}
/*
	When dirShow is truthy, it renders
	<div>Div contents</div> 

    When dirShow is falsy, it renders
    <div style="display:none;">Div contents</div>
*/

Component <Switch />

The <Switch /> component is used to conditionally render a <Case /> that resolves to a truthy value. Otherwise it renders <Default /> (If it exists).

Usage

The example component below shows the div element with contents Case 2 because it is the first case that resolves to a truthy value.

Note that the when prop for the <Case /> component supports either a (truthy | falsy) value or a function that returns a (truthy | falsy) value. It is recommended to use the function version if the calculation is intensive. This helps in short circuiting (lazy evaluation) when the case is not reached.

import  React, { useState }  from  'react';
import  { Switch, Case, Default }  from  'react-directive';

const  Component  =  props  =>  {
    const [currentName, setCurrentName] = useState('Musah');

    // This makes it more concise to render an element instead of using nested ternary operator. 
    // Fun fact: I was getting lots of eslint problems because of using ternary operators which was one of my main motivations for building this library.
	return (
      <Switch>
          <Case when={!currentName.length}>
            <div>Case 1</div>
          </Case>
          <Case when={currentName.length > 4}>
            <div>Case 2</div>
          </Case>
          {/* The case below resolves to true but the case above will render because it is the first match */}
          <Case when> 
            <div>Case 3</div>
          </Case>
          <Default>
            <div>Default</div>
          </Default>
     </Switch>
  );
}
/*
	renders
    <div>Case 2</div>
*/

Class Names

A common need for data binding is manipulating an element's class list. react-directive provides the hook useClassName and an extended version of the className prop to handle this issue

Hook useClassName

A simple hook for generating class names.

Usage

The hook takes in two optional parameters: classes and deps (dependencies).

  • classes can be a string, an array of strings, an object with class names as keys and truthy values, or an array of such objects.

  • deps is an optional dependencies array that tells the hook to re-run when one of its values changes.

Note: When dependencies are not passed, it will fallback to re-calculate the class names based on the classes argument itself. Also it is advisable to pass an array of primitive values or cached values. So that it doesn't re-calculate unnecessarily. Think of it like a useEffect dependency.

Here are some basic examples:

import { useClassName } from 'react-directive';

function Component() {
  const className = useClassName({
    active: true,
    disabled: false,
  });

  return <div className={className}>Contents</div>;
}

// Renders <div class="active">Contents</div>

You can also pass an array of objects, strings, or a combination of both:

import { useState } from 'react'
import { useClassName } from 'react-directive';

function Component() {
  const [isActive, setIsActive] = useState(true);
  const [isDisabled, setIsDisabled] = useState(false);
  const className = useClassName([
      'highlighted',
    { active: isActive, disabled: isDisabled },
  ], [isActive, isDisabled]); // Optional deps to tell it to re-calculate based on isActive and isDisabled values

  return <div className={className}>Contents</div>;
}
// Renders <div class="highlighted active">Contents</div>
// This is useful if you have some other classNames that doesn't have to react to any value

Prop className

react-directive extends the default className of React to support what the useClassName hook supports above. To pass the dependencies, use classNameDeps props.

Here are some basic examples:

import { useState } from 'react'
import directive from 'react-directive';

function Component() {
  const [isActive, setIsActive] = useState(true);
  const [isDisabled, setIsDisabled] = useState(false);

  return <directive.div className={{isActive, isDisabled}} classNameDeps={[isActive, isDisabled]}  >Contents</directive.div>;
}
// Renders <div class="active">Contents</div>
// classNameDeps is optional but makes it more efficient and performant.

List Rendering

react-directive provides the directive dirFor and the component <For /> to generate lists. This makes it more readable than using Array.prototype.map.

Usage

The <For /> component takes in an object with two properties: each and children

  • each is an array of items that you want to render.

  • children is a function that takes in two arguments: value and index. value is the current item in the each array and index is its index in the array.

Note: Make sure to pass a unique key prop to the elements rendered by the children function. This is important for React to keep track of the elements and render updates efficiently.

Here is a basic example:

import { For } from 'react-directive';

function Component() {
  const items = ['Item 1', 'Item 2', 'Item 3'];

  return (
    <For each={items}>
      {(value, index) => <div key={index}>{value}</div>}
    </For>
  );
}

/* renders
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
*/

You might have noticed that we are passing a function. It is important to know that if you want the values of the elements in the list you passed, you must pass a function to be able to access them. This works like <Context.Consumer />.

Prop dirFor

react-directive includes a prop that takes an array of items you want to render. The children prop is a function or React node that is called for each item in the array. The function takes in two arguments: currentItem and index. currentItem is the current item in the dirFor array and index is its index in the array.

Note: Make sure to pass a unique key prop to the elements rendered by the children function using dirKey (More later). This is important for React to keep track of the elements and render updates efficiently. It fallsback to using the index of the item if not provided

Here is a basic example:

import directive from 'react-directive';

function Component() {
  const items = ['Item 1', 'Item 2', 'Item 3'];

  return (
    // this means the current item. Used because the items are unique. If they are not
    <directive.div dirKey="this" dirFor={items}>{(currentItem) => currentItem}</directive.div>
  );
}

/* renders
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
*/

Other props

Prop dirKey

The dirKey prop is used to specify the key of the current element which is in the loop while using dirFor.

  • It can take this, which means the current item should be used as a key. Note: use this for only primitive values that you know will be unique in the list.
  • It can take any other string. When any other string is specified, it will use that to find the index in the current item according to the name. It will assume that the current item is an object. If null or undefined is returned, it will fallback to the index
  • It can take in a function that returns the key

Prop dirRef

The dirRef prop is used instead of the standard ref prop for directives. The ref prop will not work when using directives.

Here is a basic example:

import { useRef } from 'react';
import directive from 'react-directive';

function Component() {
  const inputRef = useRef<HTMLInputElement>(null);
  const focusInput = () => {
    inputRef.current.focus();
  }

  return (
    <React.Fragement> 
      <directive.input placeholder="Name" dirRef={inputRef} />
      <button onClick={focusInput}>Focus Input</button>
    </React.Fragement>
  );
}

/* renders
    <div>Item 1</div>
    <div>Item 2</div>
    <div>Item 3</div>
*/

Pull Requests

Pull requests are welcome. Open pull requests to the pr branch and make sure it all lint and tests are passing.

License

MIT © Musah Kusi Hussein