npm.io
1.1.1 • Published 3d ago

@hbi-developer/react-switch-component

Licence
MIT
Version
1.1.1
Deps
0
Size
18 kB
Vulns
0
Weekly
0

@hbi-developer/react-switch-component

A zero-dependency Switch component for React — declarative conditional rendering that reads like native `switch`

License npm version React TypeScript Zero Dependencies


Table of Contents


Overview

@hbi-developer/react-switch-component brings the familiar switch statement pattern to React JSX. Instead of nested ternaries or long chains of && conditions, you describe each branch as a component — readable, composable, and type-safe.

The library ships with zero runtime dependencies beyond React itself. It is built for performance: only the matched branch is rendered, with optional transition delays for animation libraries.

import { Switch } from "@hbi-developer/react-switch-component";

function StatusView({ status }: { status: "loading" | "success" | "error" }) {
  return (
    <Switch.Root>
      <Switch.Case condition={status === "loading"}>
        <Spinner />
      </Switch.Case>

      <Switch.Case condition={status === "success"}>
        <SuccessPanel />
      </Switch.Case>

      <Switch.Default>
        <ErrorPanel />
      </Switch.Default>
    </Switch.Root>
  );
}

Why This Library

Conditional UI in React often degrades into unreadable logic:

// Before — hard to scan, easy to break
{
  status === "loading" ? (
    <Spinner />
  ) : status === "success" ? (
    <SuccessPanel />
  ) : (
    <ErrorPanel />
  );
}

With this library, the same logic becomes declarative and mirrors native JavaScript:

// After — reads like a switch statement
<Switch.Root>
  <Switch.Case condition={status === "loading"}>
    <Spinner />
  </Switch.Case>
  <Switch.Case condition={status === "success"}>
    <SuccessPanel />
  </Switch.Case>
  <Switch.Default>
    <ErrorPanel />
  </Switch.Default>
</Switch.Root>
Approach Readability Composability Transition Support
Nested ternaries Low Poor Manual
if / early return High N/A (outside JSX) Manual
Switch component High High Built-in delay API

Features

  • Zero Dependencies — lightweight bundle, no transitive packages
  • Declarative APISwitch.Case, Switch.Default, and Switch.Layout mirror familiar patterns
  • First-Match Semantics — behaves like a native switch; the first truthy case wins
  • Layout Wrapper — inject matched content into a parent element (cards, motion containers, etc.)
  • Delayed Switches — per-case or global delays for exit/enter animation coordination
  • TypeScript First — full type definitions exported
  • React 16.8+ — hooks-based, compatible with React 19

Installation

# pnpm (recommended)
pnpm add @hbi-developer/react-switch-component

# npm
npm install @hbi-developer/react-switch-component

# yarn
yarn add @hbi-developer/react-switch-component

Peer dependency: React >=16.8.0


Quick Start

import { Switch } from "@hbi-developer/react-switch-component";

export function AuthGate({ role }: { role: "admin" | "user" | "guest" }) {
  return (
    <Switch.Root>
      <Switch.Case condition={role === "admin"}>
        <AdminDashboard />
      </Switch.Case>

      <Switch.Case condition={role === "user"}>
        <UserDashboard />
      </Switch.Case>

      <Switch.Default>
        <GuestLanding />
      </Switch.Default>
    </Switch.Root>
  );
}

Note: Switch is an alias for Switch.Root. Use whichever reads better in your codebase.


How It Works

Children parsed once
        ↓
First matching Switch.Case selected
        ↓
No match? → Switch.Default (index 0)
        ↓
Optional delay applied
        ↓
Switch.Layout wraps output (if provided)
        ↓
Single branch rendered to DOM

Evaluation rules:

  1. Cases are evaluated top to bottom; the first condition={true} wins.
  2. If no case matches, Switch.Default is rendered.
  3. Only one branch mounts at a time — no hidden siblings in the tree.
  4. delay defers the index change, keeping the previous branch visible until the timer completes.

Examples

Custom Layout Wrapper

Use Switch.Layout to wrap matched content in a container — ideal for shared styles or animation wrappers.

<Switch.Root>
  <Switch.Layout withDefault={true}>
    <article className="panel" />
  </Switch.Layout>

  <Switch.Case condition={isAdmin}>
    <AdminPanel />
  </Switch.Case>

  <Switch.Default>
    <UserPanel />
  </Switch.Default>
</Switch.Root>

The child of Switch.Layout must be a single React element. Matched case content is injected as its children.

withDefault Behavior
false (default) Layout wraps matched cases only
true Layout also wraps Switch.Default content

Global Delay

Apply a uniform delay before any branch switch — useful when coordinating with CSS transitions.

<Switch.Root delay={300}>
  <Switch.Case condition={status === "loading"}>
    <LoadingSpinner />
  </Switch.Case>
  <Switch.Case condition={status === "success"}>
    <DataView />
  </Switch.Case>
</Switch.Root>

Per-Case Delay

Pass a record to set delays per branch index:

Index Target
0 Switch.Default
1, 2, … Switch.Case in order of appearance
<Switch.Root delay={{ 0: 0, 1: 200, 2: 500 }}>
  <Switch.Case condition={status === "success"}>
    <SuccessMessage />
  </Switch.Case>

  <Switch.Case condition={status === "error"}>
    <ErrorMessage />
  </Switch.Case>

  <Switch.Default>
    <IdleState />
  </Switch.Default>
</Switch.Root>

Invalid delay keys (out of range or non-numeric) throw at runtime with a descriptive error.


API Reference

Switch / Switch.Root

The root container. Accepts cases, an optional default, and an optional layout.

Prop Type Default Description
children ReactNode Switch.Case, Switch.Default, and optionally Switch.Layout
delay number | Record<number, number> 0 Delay in milliseconds before switching branches

Switch.Case

Renders its children when condition is truthy and no earlier case has matched.

Prop Type Description
condition boolean When true, this case is a candidate for rendering
children ReactNode Content to render when this case is active

Switch.Default

Fallback branch when no Switch.Case matches.

Prop Type Description
children ReactNode Fallback content

Switch.Layout

Optional wrapper applied around the active branch output.

Prop Type Default Description
children ReactElement Wrapper element that receives matched content as children
withDefault boolean false When true, also wraps Switch.Default output

Exported Types
import {
  Switch,
  type SwitchRootProps,
  type SwitchCaseProps,
  type SwitchDefaultProps,
  type SwitchLayoutProps,
} from "@hbi-developer/react-switch-component";

Development

# Clone
git clone https://github.com/HBI-Developer/react-switch-component.git
cd react-switch-component

# Install
pnpm install

# Build (outputs to dist/)
pnpm run build

The package builds with TypeScript (tsc) and publishes only the dist/ directory.


Contributing

Contributions are welcome. For bugs and feature requests, open an issue. For code changes:

git checkout -b feat/your-feature
pnpm run build
git commit -m "feat: describe your change"
git push origin feat/your-feature

Then open a pull request against main.


License

MIT HBI Developer


Support


Declarative conditional rendering — as simple as switch, as native as React.

Keywords