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

v0.0.6

Published

Conditional rendering helpers for react

Downloads

4

Readme


Quick Start

npm install --save react-floco
import { Switch, Case, Default } from 'react-floco';

/** 
 * Renders a status based on color 
 */
function StatusFromColor (props) {

    return (<Switch value={props.color}>
        <Case for={"red"}>Danger!</Case>
        <Case for={"orange"}>Warning!</Case>
        <Case for={"green"}>All's well</Case>
        <Default>Unknown</Default>
    </Switch>);
}

Features

Component library

Switch statements

The <Switch> component controls rendering of child <Case> components where the for prop matches the current value of that <Switch>. Together, these components mimic the behavior of switch-case statements for component rendering:

import { Switch, Case, Default } from 'react-floco';

/**
 * Render a badge type based on the badgeCode prop
 */
function UserBadge (props) {

    return (<Switch value={props.badgeCode}>
        <Case for={"p"}>Platinum badge</Case>
        <Case for={"g"}>Gold badge</Case>
        <Case for={"s"}>Silver badge</Case>
        <Case for={"b"}>Bonze badge</Case>
        <Default>No badge earned</Default>
    </Switch>);
}

The <Switch> component also allows for matching across mixed value types for <Case> components:

<Switch value={data}>
    <Case for={1}>Data {data} is a number</Case>
    <Case for={true}>Data {data} is a boolean</Case>
    <Case for={'foo'}>Data {data} is a string</Case>
</Switch>

Multiple <Case> components for the same value case are also possible:

<Switch value={data}>
    <Case for={1}>Data is a number</Case>
    <Case for={true}>Data is a boolean</Case>
    <hr/>
    <Case for={true}>Data is not false</Case>
    <Case for={1}>Data is less than 5</Case>
</Switch>

The value prop also supports callback functions - the switch automatically invokes the function and will use the result for <Case> matching. Asynchronous values and functions are also supported:

<Switch value={() => getUserStatus()}>
    <Case for={"online"}>User is onboard!</Case>
    <Case for={"offline"}>User isn't around..</Case>
    <Default>Hmm, not sure..</Default>
</Switch>

Conditional statements

The <If> component controls rendering of child content when the condition prop evaluates "truthy". If <Else> child components are present, they will be rendered when condition is evaluated "falsey":

import { If, Else } from 'react-floco';

/**
 * Render a human friendly message based on responseIsOk prop
 */
function RenderResponse (props) {

    return (<If condition={ props.responseIsOk }>
        Got successful response. Everything worked as expected!
        <Else>Something went wrong.</Else>
    </If>);
}

As with the <Case> and <Default> components, multiple <Else> components are allowed for a single <If> component. All <Else> components will be rendered when condition evaluates "falsey":

<If condition={isError}>
    <p>Something went wrong!</p>
    <Else>Phew..</Else>
    <hr/>
    <Else>No error. Everything went as expected!</Else>
</If>

Like the value prop for <Switch>, the condition prop also supports callback functions as well as promises:

<If condition={() => isLoggedIn()}>
    <p>Welcome friend!</p>
    <Else>Who goes there?</Else>
</If>

Count controlled loops

The <Repeat> component allows a single component to be rendered multiple times. Unlike <Switch> and <If>, the <Repeat> component renders children via a callback function. The render callback passes a unique key prop that corresponds to the current iteration index:

import { Repeat } from 'react-floco';

/**
 * Renders an annoying list of questions
 */
function AnnoyingList (props) {

    return (<Repeat times={props.count}>
    { ({ key }) => <p key={key}>Are we there yet?</p> }
    </Repeat>);
}

The render callback will automatically pass through any additional props that are passed to <Repeat>:

<Repeat times={5} name={'Bob'} age={32}>
    { /* props contains name and age */ }
    { (props) => <UserItem {...props} /> }
</Repeat>

Asynchronous support

The <Switch> and <If> components support asynchronous evaluation and rendering. If a Promise is passed to the value prop of the <Switch> component, then cases will be matched on the resolved value:

<Switch value={fetchUserStatus}>
    <Case for={"offline"}>User has left the building!</Case>
    <Case for={"online"}>The user is online</Case>
</Switch>

If an asynchronous value is rejected then any <Default> blocks that are present will be rendered:

<Switch value={Promise.reject()}>
    <Case for={true}>Impossible!</Case>
    <Default>Either no matching case exists, or the value promise was rejected..</Default>
</Switch>

The <Loading> component can be used in tandem with asynchronous rendering. The <Loading> component(s) are only rendered if the value props Promise is in a pending state:

<Switch value={fetchEmotion}>
    <Loading>I'm busy figuring someone out..</Loading>
    <Case for={'happy'}>I figured out they're happy!</Case>
    <Case for={'sad'}>I think they're sad!</Case>
    <Default>I couldn't read them..</Default>
</Switch>

The <If> component supports asynchronous rendering in the same way:

<If value={fetchIsHeadsFromTails}>
    <Loading>The coin is spinning..</Loading>
    <p>Landed on heads!</p>
    <Else>Landed on tails!</Else>
</If>

API

| Component | Prop | Type | Required | Description | | ------------- | ----------- | -------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | <Switch> | value | object | yes | Specifies the value that Case children will be matched against. If a function is specified, then it is invoked during rendering and the result is used for matching. | | <Case> | for | object | yes | The value that this case is rendered for. | | <If> | condition | bool, function | yes | Determines if the content of the component is rendered. The component is rendered if a truthy value or a function that returns a truthy value, is specified. | | <Repeat> | times | number | yes | The number of times that children are rendered. |

Run tests

npm run test

Run examples

docker-compose up

License

Licensed under MIT